def update_procedure(self, thing_id, created, lifetime, last_updated, interval): pass def general_action(self, body, thing_id, subreddit, username): if not subreddit.lower() in self.APPROVE or 'leafeator' in username.lower(): # filtering out all other stuff return False result = self.REGEX.search(body) if result: self.oauth.refresh() self.session._add_comment(thing_id, self.RESPONSE) return True return False def on_new_message(self, message): pass def init(database): """Init Call from module importer to return only the object itself, rather than the module.""" return LeafeatorBot(database) if __name__ == '__main__': from praw import Reddit r = Reddit(user_agent='Manual Testing') cmt = r.get_info(thing_id='t1_cud1d76') lb = LeafeatorBot(None) lb.execute_comment(cmt)
class OAuth2RedditTest(PRAWTest): def setUp(self): self.configure() self.r = Reddit(USER_AGENT, site_name='reddit_oauth_test', disable_update_check=True) def test_authorize_url(self): self.r.set_oauth_app_info(None, None, None) self.assertRaises(errors.OAuthAppRequired, self.r.get_authorize_url, 'dummy_state') self.r.set_oauth_app_info(self.r.config.client_id, self.r.config.client_secret, self.r.config.redirect_uri) url, params = self.r.get_authorize_url('...').split('?', 1) self.assertTrue('api/v1/authorize/' in url) params = dict(x.split('=', 1) for x in params.split('&')) expected = {'client_id': self.r.config.client_id, 'duration': 'temporary', 'redirect_uri': ('https%3A%2F%2F127.0.0.1%3A65010%2F' 'authorize_callback'), 'response_type': 'code', 'scope': 'identity', 'state': '...'} self.assertEqual(expected, params) @betamax() def test_get_access_information(self): # If this test fails, the following URL will need to be visted in order # to obtain a new code to pass to `get_access_information`: # self.r.get_authorize_url('...') token = self.r.get_access_information('MQALrr1di8GzcnT8szbTWhLcBUQ') expected = {'access_token': self.r.access_token, 'refresh_token': None, 'scope': set(('identity',))} self.assertEqual(expected, token) self.assertEqual('PyAPITestUser2', text_type(self.r.user)) @betamax() def test_get_access_information_with_invalid_code(self): self.assertRaises(errors.OAuthInvalidGrant, self.r.get_access_information, 'invalid_code') def test_invalid_app_access_token(self): self.r.clear_authentication() self.r.set_oauth_app_info(None, None, None) self.assertRaises(errors.OAuthAppRequired, self.r.get_access_information, 'dummy_code') def test_invalid_app_authorize_url(self): self.r.clear_authentication() self.r.set_oauth_app_info(None, None, None) self.assertRaises(errors.OAuthAppRequired, self.r.get_authorize_url, 'dummy_state') @betamax() def test_invalid_set_access_credentials(self): self.assertRaises(errors.OAuthInvalidToken, self.r.set_access_credentials, set(('identity',)), 'dummy_access_token') def test_oauth_scope_required(self): self.r.set_oauth_app_info('dummy_client', 'dummy_secret', 'dummy_url') self.r.set_access_credentials(set('dummy_scope',), 'dummy_token') self.assertRaises(errors.OAuthScopeRequired, self.r.get_me) @betamax() def test_scope_edit(self): self.r.refresh_access_information(self.refresh_token['edit']) submission = Submission.from_id(self.r, self.submission_edit_id) self.assertEqual(submission, submission.edit('Edited text')) @betamax() def test_scope_history(self): self.r.refresh_access_information(self.refresh_token['history']) self.assertTrue(list(self.r.get_redditor(self.un).get_upvoted())) @betamax() def test_scope_identity(self): self.r.refresh_access_information(self.refresh_token['identity']) self.assertEqual(self.un, self.r.get_me().name) @betamax() def test_scope_modconfig(self): self.r.refresh_access_information(self.refresh_token['modconfig']) self.r.get_subreddit(self.sr).set_settings('foobar') retval = self.r.get_subreddit(self.sr).get_stylesheet() self.assertTrue('images' in retval) @betamax() def test_scope_modflair(self): self.r.refresh_access_information(self.refresh_token['modflair']) self.r.get_subreddit(self.sr).set_flair(self.un, 'foobar') @betamax() def test_scope_modlog(self): num = 50 self.r.refresh_access_information(self.refresh_token['modlog']) result = self.r.get_subreddit(self.sr).get_mod_log(limit=num) self.assertEqual(num, len(list(result))) @betamax() def test_scope_modothers_modself(self): subreddit = self.r.get_subreddit(self.sr) self.r.refresh_access_information(self.refresh_token['modothers']) subreddit.add_moderator(self.other_user_name) # log in as other user self.r.refresh_access_information(self.other_refresh_token['modself']) self.r.accept_moderator_invite(self.sr) # now return to original user. self.r.refresh_access_information(self.refresh_token['modothers']) subreddit.remove_moderator(self.other_user_name) @betamax() def test_scope_modposts(self): self.r.refresh_access_information(self.refresh_token['modposts']) Submission.from_id(self.r, self.submission_edit_id).remove() @betamax() def test_scope_mysubreddits(self): self.r.refresh_access_information(self.refresh_token['mysubreddits']) self.assertTrue(list(self.r.get_my_moderation())) @betamax() def test_scope_creddits(self): # Assume there are insufficient creddits. self.r.refresh_access_information( self.refresh_token['creddits']) redditor = self.r.get_redditor('bboe') sub = self.r.get_submission(url=self.comment_url) # Test error conditions self.assertRaises(TypeError, sub.gild, months=1) for value in (False, 0, -1, '0', '-1'): self.assertRaises(TypeError, redditor.gild, value) # Test object gilding self.assertRaises(errors.InsufficientCreddits, redditor.gild) self.assertRaises(errors.InsufficientCreddits, sub.gild) self.assertRaises(errors.InsufficientCreddits, sub.comments[0].gild) @betamax() def test_scope_privatemessages(self): self.r.refresh_access_information( self.refresh_token['privatemessages']) self.assertTrue(list(self.r.get_inbox())) @betamax() def test_scope_read(self): self.r.refresh_access_information(self.refresh_token['read']) self.assertTrue(self.r.get_subreddit(self.priv_sr).subscribers > 0) fullname = '{0}_{1}'.format(self.r.config.by_object[Submission], self.priv_submission_id) method1 = self.r.get_info(thing_id=fullname) method2 = self.r.get_submission(submission_id=self.priv_submission_id) self.assertEqual(method1, method2) @betamax() def test_scope_read_get_front_page(self): self.r.refresh_access_information(self.refresh_token['mysubreddits']) subscribed = list(self.r.get_my_subreddits(limit=None)) self.r.refresh_access_information(self.refresh_token['read']) for post in self.r.get_front_page(): self.assertTrue(post.subreddit in subscribed) @betamax() def test_scope_read_get_sub_listingr(self): self.r.refresh_access_information(self.refresh_token['read']) subreddit = self.r.get_subreddit(self.priv_sr) self.assertTrue(list(subreddit.get_top())) @betamax() def test_scope_read_get_submission_by_url(self): url = ("https://www.reddit.com/r/reddit_api_test_priv/comments/16kbb7/" "google/") self.r.refresh_access_information(self.refresh_token['read']) submission = Submission.from_url(self.r, url) self.assertTrue(submission.num_comments != 0) @betamax() def test_scope_read_priv_sr_comments(self): self.r.refresh_access_information(self.refresh_token['read']) self.assertTrue(list(self.r.get_comments(self.priv_sr))) @betamax() def test_scope_wikiread_wiki_page(self): self.r.refresh_access_information(self.refresh_token['wikiread']) self.assertTrue(self.r.get_wiki_page(self.sr, 'index')) @betamax() def test_scope_read_priv_sub_comments(self): self.r.refresh_access_information(self.refresh_token['read']) submission = Submission.from_id(self.r, self.priv_submission_id) self.assertTrue(submission.comments) @betamax() def test_scope_submit(self): self.r.refresh_access_information(self.refresh_token['submit']) result = self.r.submit(self.sr, 'OAuth Submit', text='Foo') self.assertTrue(isinstance(result, Submission)) @betamax() def test_scope_subscribe(self): self.r.refresh_access_information(self.refresh_token['subscribe']) self.r.get_subreddit(self.sr).subscribe() @betamax() def test_scope_vote(self): self.r.refresh_access_information(self.refresh_token['vote']) submission = Submission.from_id(self.r, self.submission_edit_id) submission.clear_vote() @betamax() def test_set_access_credentials(self): self.assertTrue(self.r.user is None) result = self.r.refresh_access_information( self.refresh_token['identity'], update_session=False) self.assertTrue(self.r.user is None) self.r.set_access_credentials(**result) self.assertFalse(self.r.user is None) @betamax() def test_oauth_without_identy_doesnt_set_user(self): self.assertTrue(self.r.user is None) self.r.refresh_access_information(self.refresh_token['edit']) self.assertTrue(self.r.user is None)
class OAuth2RedditTest(PRAWTest): def setUp(self): self.configure() self.r = Reddit(USER_AGENT, site_name='reddit_oauth_test', disable_update_check=True) def test_authorize_url(self): self.r.set_oauth_app_info(None, None, None) self.assertRaises(errors.OAuthAppRequired, self.r.get_authorize_url, 'dummy_state') self.r.set_oauth_app_info(self.r.config.client_id, self.r.config.client_secret, self.r.config.redirect_uri) url, params = self.r.get_authorize_url('...').split('?', 1) self.assertTrue('api/v1/authorize/' in url) params = dict(x.split('=', 1) for x in params.split('&')) expected = {'client_id': self.r.config.client_id, 'duration': 'temporary', 'redirect_uri': ('https%3A%2F%2F127.0.0.1%3A65010%2F' 'authorize_callback'), 'response_type': 'code', 'scope': 'identity', 'state': '...'} self.assertEqual(expected, params) # @betamax() is currently broken for this test because the cassettes # are caching too aggressively and not performing a token refresh. def test_auto_refresh_token(self): self.r.refresh_access_information(self.refresh_token['identity']) old_token = self.r.access_token self.r.access_token += 'x' # break the token self.r.user.refresh() current_token = self.r.access_token self.assertNotEqual(old_token, current_token) self.r.user.refresh() self.assertEqual(current_token, self.r.access_token) @betamax() def test_get_access_information(self): # If this test fails, the following URL will need to be visted in order # to obtain a new code to pass to `get_access_information`: # self.r.get_authorize_url('...') token = self.r.get_access_information('MQALrr1di8GzcnT8szbTWhLcBUQ') expected = {'access_token': self.r.access_token, 'refresh_token': None, 'scope': set(('identity',))} self.assertEqual(expected, token) self.assertEqual('PyAPITestUser2', text_type(self.r.user)) @betamax() def test_get_access_information_with_invalid_code(self): self.assertRaises(errors.OAuthInvalidGrant, self.r.get_access_information, 'invalid_code') def test_invalid_app_access_token(self): self.r.clear_authentication() self.r.set_oauth_app_info(None, None, None) self.assertRaises(errors.OAuthAppRequired, self.r.get_access_information, 'dummy_code') def test_invalid_app_authorize_url(self): self.r.clear_authentication() self.r.set_oauth_app_info(None, None, None) self.assertRaises(errors.OAuthAppRequired, self.r.get_authorize_url, 'dummy_state') @betamax() def test_invalid_set_access_credentials(self): self.assertRaises(errors.OAuthInvalidToken, self.r.set_access_credentials, set(('identity',)), 'dummy_access_token') def test_oauth_scope_required(self): self.r.set_oauth_app_info('dummy_client', 'dummy_secret', 'dummy_url') self.r.set_access_credentials(set('dummy_scope',), 'dummy_token') self.assertRaises(errors.OAuthScopeRequired, self.r.get_me) def test_raise_client_exception(self): def raise_client_exception(*args): raise errors.ClientException(*args) self.assertRaises(errors.ClientException, raise_client_exception) self.assertRaises(errors.ClientException, raise_client_exception, 'test') ce_message = errors.ClientException('Test') ce_no_message = errors.ClientException() self.assertEqual(ce_message.message, str(ce_message)) self.assertEqual(ce_no_message.message, str(ce_no_message)) def test_raise_http_exception(self): def raise_http_exception(): raise errors.HTTPException('fakeraw') self.assertRaises(errors.HTTPException, raise_http_exception) http_exception = errors.HTTPException('fakeraw') self.assertEqual(http_exception.message, str(http_exception)) def test_raise_oauth_exception(self): oerrormessage = "fakemessage" oerrorurl = "http://oauth.reddit.com/" def raise_oauth_exception(): raise errors.OAuthException(oerrormessage, oerrorurl) self.assertRaises(errors.OAuthException, raise_oauth_exception) oauth_exception = errors.OAuthException(oerrormessage, oerrorurl) self.assertEqual(oauth_exception.message + " on url {0}".format(oauth_exception.url), str(oauth_exception)) def test_raise_redirect_exception(self): apiurl = "http://api.reddit.com/" oauthurl = "http://oauth.reddit.com/" def raise_redirect_exception(): raise errors.RedirectException(apiurl, oauthurl) self.assertRaises(errors.RedirectException, raise_redirect_exception) redirect_exception = errors.RedirectException(apiurl, oauthurl) self.assertEqual(redirect_exception.message, str(redirect_exception)) @betamax() def test_scope_history(self): self.r.refresh_access_information(self.refresh_token['history']) self.assertTrue(list(self.r.get_redditor(self.un).get_upvoted())) @betamax() def test_scope_identity(self): self.r.refresh_access_information(self.refresh_token['identity']) self.assertEqual(self.un, self.r.get_me().name) @betamax() def test_scope_mysubreddits(self): self.r.refresh_access_information(self.refresh_token['mysubreddits']) self.assertTrue(list(self.r.get_my_moderation())) @betamax() def test_scope_creddits(self): # Assume there are insufficient creddits. self.r.refresh_access_information( self.refresh_token['creddits']) redditor = self.r.get_redditor('bboe') sub = self.r.get_submission(url=self.comment_url) # Test error conditions self.assertRaises(TypeError, sub.gild, months=1) for value in (False, 0, -1, '0', '-1'): self.assertRaises(TypeError, redditor.gild, value) # Test object gilding self.assertRaises(errors.InsufficientCreddits, redditor.gild) self.assertRaises(errors.InsufficientCreddits, sub.gild) self.assertRaises(errors.InsufficientCreddits, sub.comments[0].gild) @betamax() def test_scope_privatemessages(self): self.r.refresh_access_information( self.refresh_token['privatemessages']) self.assertTrue(list(self.r.get_inbox())) @betamax() def test_scope_read(self): self.r.refresh_access_information(self.refresh_token['read']) self.assertTrue(self.r.get_subreddit(self.priv_sr).subscribers > 0) fullname = '{0}_{1}'.format(self.r.config.by_object[Submission], self.priv_submission_id) method1 = self.r.get_info(thing_id=fullname) method2 = self.r.get_submission(submission_id=self.priv_submission_id) self.assertEqual(method1, method2) @betamax() def test_scope_read_get_front_page(self): self.r.refresh_access_information(self.refresh_token['mysubreddits']) subscribed = list(self.r.get_my_subreddits(limit=None)) self.r.refresh_access_information(self.refresh_token['read']) for post in self.r.get_front_page(): self.assertTrue(post.subreddit in subscribed) @betamax() def test_set_access_credentials(self): self.assertTrue(self.r.user is None) result = self.r.refresh_access_information( self.refresh_token['identity'], update_session=False) self.assertTrue(self.r.user is None) self.r.set_access_credentials(**result) self.assertFalse(self.r.user is None) @betamax() def test_solve_captcha(self): # Use the alternate account because it has low karma, # so we can test the captcha. self.r.refresh_access_information(self.other_refresh_token['submit']) original_stdin = sys.stdin sys.stdin = FakeStdin('ljgtoo') # Comment this line when rebuilding self.r.submit(self.sr, 'captcha test', 'body') sys.stdin = original_stdin @betamax() def test_oauth_without_identy_doesnt_set_user(self): self.assertTrue(self.r.user is None) self.r.refresh_access_information(self.refresh_token['edit']) self.assertTrue(self.r.user is None)
class OAuth2RedditTest(PRAWTest): def setUp(self): self.configure() self.r = Reddit(USER_AGENT, site_name='reddit_oauth_test', disable_update_check=True) def test_authorize_url(self): self.r.set_oauth_app_info(None, None, None) self.assertRaises(errors.OAuthAppRequired, self.r.get_authorize_url, 'dummy_state') self.r.set_oauth_app_info(self.r.config.client_id, self.r.config.client_secret, self.r.config.redirect_uri) url, params = self.r.get_authorize_url('...').split('?', 1) self.assertTrue('api/v1/authorize/' in url) params = dict(x.split('=', 1) for x in params.split('&')) expected = { 'client_id': self.r.config.client_id, 'duration': 'temporary', 'redirect_uri': ('https%3A%2F%2F127.0.0.1%3A65010%2F' 'authorize_callback'), 'response_type': 'code', 'scope': 'identity', 'state': '...' } self.assertEqual(expected, params) @betamax() @mock_sys_stream("stdin") def test_empty_captcha_file(self): # Use the alternate account because it has low karma, # so we can test the captcha. self.r.refresh_access_information(self.other_refresh_token['submit']) self.assertRaises(errors.InvalidCaptcha, self.r.submit, self.sr, 'captcha test will fail', 'body') @betamax() def test_get_access_information(self): # If this test fails, the following URL will need to be visted in order # to obtain a new code to pass to `get_access_information`: # self.r.get_authorize_url('...') token = self.r.get_access_information('MQALrr1di8GzcnT8szbTWhLcBUQ') expected = { 'access_token': self.r.access_token, 'refresh_token': None, 'scope': set(('identity', )) } self.assertEqual(expected, token) self.assertEqual('PyAPITestUser2', text_type(self.r.user)) @betamax() def test_get_access_information_with_invalid_code(self): self.assertRaises(errors.OAuthInvalidGrant, self.r.get_access_information, 'invalid_code') @betamax() @mock_sys_stream("stdin") def test_inject_captcha_into_kwargs_and_raise(self): # Use the alternate account because it has low karma, # so we can test the captcha. self.r.refresh_access_information(self.other_refresh_token['submit']) # praw doesn't currently add the captcha into kwargs so lets # write a function in which it would and alias it to Reddit.submit @decorators.restrict_access(scope='submit') @decorators.require_captcha def submit_alias(r, sr, title, text, **kw): return self.r.submit.__wrapped__.__wrapped__( r, sr, title, text, captcha=kw.get('captcha')) self.assertRaises(errors.InvalidCaptcha, submit_alias, self.r, self.sr, 'captcha test will fail', 'body') def test_invalid_app_access_token(self): self.r.clear_authentication() self.r.set_oauth_app_info(None, None, None) self.assertRaises(errors.OAuthAppRequired, self.r.get_access_information, 'dummy_code') def test_invalid_app_authorize_url(self): self.r.clear_authentication() self.r.set_oauth_app_info(None, None, None) self.assertRaises(errors.OAuthAppRequired, self.r.get_authorize_url, 'dummy_state') @betamax() def test_invalid_set_access_credentials(self): self.assertRaises(errors.OAuthInvalidToken, self.r.set_access_credentials, set( ('identity', )), 'dummy_access_token') def test_oauth_scope_required(self): self.r.set_oauth_app_info('dummy_client', 'dummy_secret', 'dummy_url') self.r.set_access_credentials(set('dummy_scope', ), 'dummy_token') self.assertRaises(errors.OAuthScopeRequired, self.r.get_me) def test_raise_client_exception(self): def raise_client_exception(*args): raise errors.ClientException(*args) self.assertRaises(errors.ClientException, raise_client_exception) self.assertRaises(errors.ClientException, raise_client_exception, 'test') ce_message = errors.ClientException('Test') ce_no_message = errors.ClientException() self.assertEqual(ce_message.message, str(ce_message)) self.assertEqual(ce_no_message.message, str(ce_no_message)) def test_raise_http_exception(self): def raise_http_exception(): raise errors.HTTPException('fakeraw') self.assertRaises(errors.HTTPException, raise_http_exception) http_exception = errors.HTTPException('fakeraw') self.assertEqual(http_exception.message, str(http_exception)) def test_raise_oauth_exception(self): oerrormessage = "fakemessage" oerrorurl = "http://oauth.reddit.com/" def raise_oauth_exception(): raise errors.OAuthException(oerrormessage, oerrorurl) self.assertRaises(errors.OAuthException, raise_oauth_exception) oauth_exception = errors.OAuthException(oerrormessage, oerrorurl) self.assertEqual( oauth_exception.message + " on url {0}".format(oauth_exception.url), str(oauth_exception)) def test_raise_redirect_exception(self): apiurl = "http://api.reddit.com/" oauthurl = "http://oauth.reddit.com/" def raise_redirect_exception(): raise errors.RedirectException(apiurl, oauthurl) self.assertRaises(errors.RedirectException, raise_redirect_exception) redirect_exception = errors.RedirectException(apiurl, oauthurl) self.assertEqual(redirect_exception.message, str(redirect_exception)) @betamax() def test_scope_history(self): self.r.refresh_access_information(self.refresh_token['history']) self.assertTrue(list(self.r.get_redditor(self.un).get_upvoted())) @betamax() def test_scope_identity(self): self.r.refresh_access_information(self.refresh_token['identity']) self.assertEqual(self.un, self.r.get_me().name) @betamax() def test_scope_mysubreddits(self): self.r.refresh_access_information(self.refresh_token['mysubreddits']) self.assertTrue(list(self.r.get_my_moderation())) @betamax() def test_scope_creddits(self): # Assume there are insufficient creddits. self.r.refresh_access_information(self.refresh_token['creddits']) redditor = self.r.get_redditor('bboe') sub = self.r.get_submission(url=self.comment_url) # Test error conditions self.assertRaises(TypeError, sub.gild, months=1) for value in (False, 0, -1, '0', '-1', 37, '37'): self.assertRaises(TypeError, redditor.gild, value) # Test object gilding self.assertRaises(errors.InsufficientCreddits, redditor.gild) self.assertRaises(errors.InsufficientCreddits, sub.gild) self.assertRaises(errors.InsufficientCreddits, sub.comments[0].gild) @betamax() def test_scope_privatemessages(self): self.r.refresh_access_information( self.refresh_token['privatemessages']) self.assertTrue(list(self.r.get_inbox())) @betamax() def test_scope_read(self): self.r.refresh_access_information(self.refresh_token['read']) self.assertTrue(self.r.get_subreddit(self.priv_sr).subscribers > 0) fullname = '{0}_{1}'.format(self.r.config.by_object[Submission], self.priv_submission_id) method1 = self.r.get_info(thing_id=fullname) method2 = self.r.get_submission(submission_id=self.priv_submission_id) self.assertEqual(method1, method2) @betamax() def test_scope_read_get_front_page(self): self.r.refresh_access_information(self.refresh_token['mysubreddits']) subscribed = list(self.r.get_my_subreddits(limit=None)) self.r.refresh_access_information(self.refresh_token['read']) for post in self.r.get_front_page(): self.assertTrue(post.subreddit in subscribed) @betamax() def test_set_access_credentials(self): self.assertTrue(self.r.user is None) result = self.r.refresh_access_information( self.refresh_token['identity'], update_session=False) self.assertTrue(self.r.user is None) self.r.set_access_credentials(**result) self.assertFalse(self.r.user is None) @betamax() def test_set_access_credentials_with_list(self): self.assertTrue(self.r.user is None) result = self.r.refresh_access_information( self.refresh_token['identity'], update_session=False) self.assertTrue(self.r.user is None) result['scope'] = list(result['scope']) self.r.set_access_credentials(**result) self.assertFalse(self.r.user is None) @betamax() def test_set_access_credentials_with_string(self): self.assertTrue(self.r.user is None) result = self.r.refresh_access_information( self.refresh_token['identity'], update_session=False) self.assertTrue(self.r.user is None) result['scope'] = ' '.join(result['scope']) self.r.set_access_credentials(**result) self.assertFalse(self.r.user is None) @betamax() @mock_sys_stream("stdin", "ljgtoo") def test_solve_captcha(self): # Use the alternate account because it has low karma, # so we can test the captcha. self.r.refresh_access_information(self.other_refresh_token['submit']) self.r.submit(self.sr, 'captcha test', 'body') @betamax() @mock_sys_stream("stdin", "DFIRSW") def test_solve_captcha_on_bound_subreddit(self): # Use the alternate account because it has low karma, # so we can test the captcha. self.r.refresh_access_information(self.other_refresh_token['submit']) subreddit = self.r.get_subreddit(self.sr) # praw doesn't currently have a function in which require_captcha # gets a reddit instance from a subreddit and uses it, so lets # write a function in which it would and alias it to Reddit.submit @decorators.restrict_access(scope='submit') @decorators.require_captcha def submit_alias(sr, title, text, **kw): return self.r.submit.__wrapped__.__wrapped__( self.r, sr, title, text, captcha=kw.get('captcha')) submit_alias(subreddit, 'captcha test on bound subreddit', 'body') @betamax() def test_oauth_without_identy_doesnt_set_user(self): self.assertTrue(self.r.user is None) self.r.refresh_access_information(self.refresh_token['edit']) self.assertTrue(self.r.user is None)
class Reddit_Cleverbot: def __init__(self, username, password, subreddit='all', useragent=USERAGENT): self.username = username self.password = password self.useragent = useragent self.subreddit = subreddit self.reddit = Reddit(useragent) self.reddit.login(username, password) self.stopped = True self.thread = None self.done = set() self.conversations = dict() def random_hot_comment(self): sub = self.reddit.get_subreddit(self.subreddit) hot = [post for post in sub.get_hot(limit=25)] post = random.choice(hot) comments = praw.helpers.flatten_tree(post.comments) # filter the comments to remove already-replied ones comments = [comment for comment in comments if comment not in self.done and isinstance(comment, praw.objects.Comment)] return random.choice(comments[0:100]) def random_comment(self): comments = self.reddit.get_comments(self.subreddit) # filter the comments to remove already-replied ones comments = [comment for comment in comments if comment not in self.done] return random.choice(comments) def get_summoned_comments(self): comments = self.reddit.get_comments(self.subreddit) children = [comment for comment in comments if comment not in self.done and SUMMON in comment.body] # print "--> " + str(len(children)) + " summons found!" return [self.reddit.get_info(thing_id=comment.parent_id) for comment in children] def reply(self, comment): if self.reddit.get_info(thing_id=comment.parent_id).author.name == self.username: # TODO: handle a threaded conversation over restarts. will need a DB. ugh pass if comment.parent_id in self.conversations: cleverbot = self.conversations[comment.parent_id] else: cleverbot = Cleverbot() response = cleverbot.ask(comment.body) post = comment.reply(response) self.done.add(comment.id) self.conversations[post.id] = copy(cleverbot) def reply_unread(self, interval): for item in self.reddit.get_unread(): if item.parent_id not in self.conversations: print "Could not find conversation! Ignoring for now." pass self.reply(item) item.mark_as_read() time.sleep(interval) def reply_to_summons(self): summons = self.get_summoned_comments() for comment in summons: self.reply(comment) def _run_random(self, interval): while not self.stopped: self.reply_unread(interval) self.reply(self.random_hot_comment()) time.sleep(interval) def run_random(self, interval): self.stopped = False self.thread = Thread(target=self._run_random, args=(interval,)) self.thread.start() def stop(self): self.stopped = True #self.thread.join()
return False self.oauth.refresh() self.session._add_comment(thing.name, self.RESPONSE) self.database.insert_into_storage(thread_id, self.BOT_NAME) return True return False def on_new_message(self, message): pass def init(database): """Init Call from module importer to return only the object itself, rather than the module.""" return LeafeatorBot(database) if __name__ == "__main__": from praw import Reddit from core.DatabaseProvider import DatabaseProvider from core import LogProvider logger = LogProvider.setup_logging(log_level="DEBUG") db = DatabaseProvider() r = Reddit(user_agent="Manual Testing") subm = r.get_info(thing_id="t3_3ik036") cmt = r.get_info(thing_id="t1_cuilwo5") lb = LeafeatorBot(db) lb.execute_comment(cmt) # lb.execute_submission(subm)
class OAuth2RedditTest(PRAWTest): def setUp(self): self.configure() self.r = Reddit(USER_AGENT, site_name='reddit_oauth_test', disable_update_check=True) def test_authorize_url(self): self.r.set_oauth_app_info(None, None, None) self.assertRaises(errors.OAuthAppRequired, self.r.get_authorize_url, 'dummy_state') self.r.set_oauth_app_info(self.r.config.client_id, self.r.config.client_secret, self.r.config.redirect_uri) url, params = self.r.get_authorize_url('...').split('?', 1) self.assertTrue('api/v1/authorize/' in url) params = dict(x.split('=', 1) for x in params.split('&')) expected = { 'client_id': self.r.config.client_id, 'duration': 'temporary', 'redirect_uri': ('https%3A%2F%2F127.0.0.1%3A65010%2F' 'authorize_callback'), 'response_type': 'code', 'scope': 'identity', 'state': '...' } self.assertEqual(expected, params) # @betamax() is currently broken for this test because the cassettes # are caching too aggressively and not performing a token refresh. def test_auto_refresh_token(self): self.r.refresh_access_information(self.refresh_token['identity']) old_token = self.r.access_token self.r.access_token += 'x' # break the token self.r.user.refresh() current_token = self.r.access_token self.assertNotEqual(old_token, current_token) self.r.user.refresh() self.assertEqual(current_token, self.r.access_token) @betamax() def test_get_access_information(self): # If this test fails, the following URL will need to be visted in order # to obtain a new code to pass to `get_access_information`: # self.r.get_authorize_url('...') token = self.r.get_access_information('MQALrr1di8GzcnT8szbTWhLcBUQ') expected = { 'access_token': self.r.access_token, 'refresh_token': None, 'scope': set(('identity', )) } self.assertEqual(expected, token) self.assertEqual('PyAPITestUser2', text_type(self.r.user)) @betamax() def test_get_access_information_with_invalid_code(self): self.assertRaises(errors.OAuthInvalidGrant, self.r.get_access_information, 'invalid_code') def test_invalid_app_access_token(self): self.r.clear_authentication() self.r.set_oauth_app_info(None, None, None) self.assertRaises(errors.OAuthAppRequired, self.r.get_access_information, 'dummy_code') def test_invalid_app_authorize_url(self): self.r.clear_authentication() self.r.set_oauth_app_info(None, None, None) self.assertRaises(errors.OAuthAppRequired, self.r.get_authorize_url, 'dummy_state') @betamax() def test_invalid_set_access_credentials(self): self.assertRaises(errors.OAuthInvalidToken, self.r.set_access_credentials, set( ('identity', )), 'dummy_access_token') def test_oauth_scope_required(self): self.r.set_oauth_app_info('dummy_client', 'dummy_secret', 'dummy_url') self.r.set_access_credentials(set('dummy_scope', ), 'dummy_token') self.assertRaises(errors.OAuthScopeRequired, self.r.get_me) def test_raise_client_exception(self): def raise_client_exception(*args): raise errors.ClientException(*args) self.assertRaises(errors.ClientException, raise_client_exception) self.assertRaises(errors.ClientException, raise_client_exception, 'test') ce_message = errors.ClientException('Test') ce_no_message = errors.ClientException() self.assertEqual(ce_message.message, str(ce_message)) self.assertEqual(ce_no_message.message, str(ce_no_message)) def test_raise_http_exception(self): def raise_http_exception(): raise errors.HTTPException('fakeraw') self.assertRaises(errors.HTTPException, raise_http_exception) http_exception = errors.HTTPException('fakeraw') self.assertEqual(http_exception.message, str(http_exception)) def test_raise_oauth_exception(self): oerrormessage = "fakemessage" oerrorurl = "http://oauth.reddit.com/" def raise_oauth_exception(): raise errors.OAuthException(oerrormessage, oerrorurl) self.assertRaises(errors.OAuthException, raise_oauth_exception) oauth_exception = errors.OAuthException(oerrormessage, oerrorurl) self.assertEqual( oauth_exception.message + " on url {0}".format(oauth_exception.url), str(oauth_exception)) def test_raise_redirect_exception(self): apiurl = "http://api.reddit.com/" oauthurl = "http://oauth.reddit.com/" def raise_redirect_exception(): raise errors.RedirectException(apiurl, oauthurl) self.assertRaises(errors.RedirectException, raise_redirect_exception) redirect_exception = errors.RedirectException(apiurl, oauthurl) self.assertEqual(redirect_exception.message, str(redirect_exception)) @betamax() def test_scope_history(self): self.r.refresh_access_information(self.refresh_token['history']) self.assertTrue(list(self.r.get_redditor(self.un).get_upvoted())) @betamax() def test_scope_identity(self): self.r.refresh_access_information(self.refresh_token['identity']) self.assertEqual(self.un, self.r.get_me().name) @betamax() def test_scope_mysubreddits(self): self.r.refresh_access_information(self.refresh_token['mysubreddits']) self.assertTrue(list(self.r.get_my_moderation())) @betamax() def test_scope_creddits(self): # Assume there are insufficient creddits. self.r.refresh_access_information(self.refresh_token['creddits']) redditor = self.r.get_redditor('bboe') sub = self.r.get_submission(url=self.comment_url) # Test error conditions self.assertRaises(TypeError, sub.gild, months=1) for value in (False, 0, -1, '0', '-1'): self.assertRaises(TypeError, redditor.gild, value) # Test object gilding self.assertRaises(errors.InsufficientCreddits, redditor.gild) self.assertRaises(errors.InsufficientCreddits, sub.gild) self.assertRaises(errors.InsufficientCreddits, sub.comments[0].gild) @betamax() def test_scope_privatemessages(self): self.r.refresh_access_information( self.refresh_token['privatemessages']) self.assertTrue(list(self.r.get_inbox())) @betamax() def test_scope_read(self): self.r.refresh_access_information(self.refresh_token['read']) self.assertTrue(self.r.get_subreddit(self.priv_sr).subscribers > 0) fullname = '{0}_{1}'.format(self.r.config.by_object[Submission], self.priv_submission_id) method1 = self.r.get_info(thing_id=fullname) method2 = self.r.get_submission(submission_id=self.priv_submission_id) self.assertEqual(method1, method2) @betamax() def test_scope_read_get_front_page(self): self.r.refresh_access_information(self.refresh_token['mysubreddits']) subscribed = list(self.r.get_my_subreddits(limit=None)) self.r.refresh_access_information(self.refresh_token['read']) for post in self.r.get_front_page(): self.assertTrue(post.subreddit in subscribed) @betamax() def test_set_access_credentials(self): self.assertTrue(self.r.user is None) result = self.r.refresh_access_information( self.refresh_token['identity'], update_session=False) self.assertTrue(self.r.user is None) self.r.set_access_credentials(**result) self.assertFalse(self.r.user is None) @betamax() def test_solve_captcha(self): # Use the alternate account because it has low karma, # so we can test the captcha. self.r.refresh_access_information(self.other_refresh_token['submit']) original_stdin = sys.stdin sys.stdin = FakeStdin('ljgtoo') # Comment this line when rebuilding self.r.submit(self.sr, 'captcha test', 'body') sys.stdin = original_stdin @betamax() def test_oauth_without_identy_doesnt_set_user(self): self.assertTrue(self.r.user is None) self.r.refresh_access_information(self.refresh_token['edit']) self.assertTrue(self.r.user is None)
class OAuth2RedditTest(PRAWTest): def setUp(self): self.configure() site_name = (os.getenv('REDDIT_SITE') or 'reddit') + '_oauth_test' self.r = Reddit(USER_AGENT, site_name=site_name, disable_update_check=True) def test_authorize_url(self): self.r.set_oauth_app_info(None, None, None) self.assertRaises(errors.OAuthAppRequired, self.r.get_authorize_url, 'dummy_state') self.r.set_oauth_app_info(self.r.config.client_id, self.r.config.client_secret, self.r.config.redirect_uri) url, params = self.r.get_authorize_url('...').split('?', 1) self.assertTrue('api/v1/authorize/' in url) params = dict(x.split('=', 1) for x in params.split('&')) expected = { 'client_id': self.r.config.client_id, 'duration': 'temporary', 'redirect_uri': ('https%3A%2F%2F127.0.0.1%3A65010%2F' 'authorize_callback'), 'response_type': 'code', 'scope': 'identity', 'state': '...' } self.assertEqual(expected, params) @betamax def test_get_access_information(self): # If this test fails, the following URL will need to be visted in order # to obtain a new code to pass to `get_access_information`: # self.r.get_authorize_url('...') token = self.r.get_access_information('MQALrr1di8GzcnT8szbTWhLcBUQ') expected = { 'access_token': self.r.access_token, 'refresh_token': None, 'scope': set(('identity', )) } self.assertEqual(expected, token) self.assertEqual('PyAPITestUser2', text_type(self.r.user)) @betamax def test_get_access_information_with_invalid_code(self): self.assertRaises(errors.OAuthInvalidGrant, self.r.get_access_information, 'invalid_code') def test_invalid_app_access_token(self): self.r.clear_authentication() self.r.set_oauth_app_info(None, None, None) self.assertRaises(errors.OAuthAppRequired, self.r.get_access_information, 'dummy_code') def test_invalid_app_authorize_url(self): self.r.clear_authentication() self.r.set_oauth_app_info(None, None, None) self.assertRaises(errors.OAuthAppRequired, self.r.get_authorize_url, 'dummy_state') @betamax def test_invalid_set_access_credentials(self): self.assertRaises(errors.OAuthInvalidToken, self.r.set_access_credentials, set( ('identity', )), 'dummy_access_token') def test_oauth_scope_required(self): self.r.set_oauth_app_info('dummy_client', 'dummy_secret', 'dummy_url') self.r.set_access_credentials(set('dummy_scope', ), 'dummy_token') self.assertRaises(errors.OAuthScopeRequired, self.r.get_me) @betamax def test_scope_edit(self): self.r.refresh_access_information(self.refresh_token['edit']) submission = Submission.from_id(self.r, self.submission_edit_id) self.assertEqual(submission, submission.edit('Edited text')) @betamax def test_scope_history(self): self.r.refresh_access_information(self.refresh_token['history']) self.assertTrue(list(self.r.get_redditor(self.un).get_liked())) @betamax def test_scope_identity(self): self.r.refresh_access_information(self.refresh_token['identity']) self.assertEqual(self.un, self.r.get_me().name) @betamax def test_scope_modconfig(self): self.r.refresh_access_information(self.refresh_token['modconfig']) self.r.get_subreddit(self.sr).set_settings('foobar') retval = self.r.get_subreddit(self.sr).get_stylesheet() self.assertTrue('images' in retval) @betamax def test_scope_modflair(self): self.r.refresh_access_information(self.refresh_token['modflair']) self.r.get_subreddit(self.sr).set_flair(self.un, 'foobar') @betamax def test_scope_modlog(self): num = 50 self.r.refresh_access_information(self.refresh_token['modlog']) result = self.r.get_subreddit(self.sr).get_mod_log(limit=num) self.assertEqual(num, len(list(result))) @betamax def test_scope_modposts(self): self.r.refresh_access_information(self.refresh_token['modposts']) Submission.from_id(self.r, self.submission_edit_id).remove() @betamax def test_scope_mysubreddits(self): self.r.refresh_access_information(self.refresh_token['mysubreddits']) self.assertTrue(list(self.r.get_my_moderation())) @betamax def test_scope_creddits(self): # Assume there are insufficient creddits. self.r.refresh_access_information(self.refresh_token['creddits']) redditor = self.r.get_redditor('bboe') sub = self.r.get_submission(url=self.comment_url) # Test error conditions self.assertRaises(TypeError, sub.gild, months=1) for value in (False, 0, -1, '0', '-1'): self.assertRaises(TypeError, redditor.gild, value) # Test object gilding self.assertRaises(errors.InsufficientCreddits, redditor.gild) self.assertRaises(errors.InsufficientCreddits, sub.gild) self.assertRaises(errors.InsufficientCreddits, sub.comments[0].gild) @betamax def test_scope_privatemessages(self): self.r.refresh_access_information( self.refresh_token['privatemessages']) self.assertTrue(list(self.r.get_inbox())) @betamax def test_scope_read(self): self.r.refresh_access_information(self.refresh_token['read']) self.assertTrue(self.r.get_subreddit(self.priv_sr).subscribers > 0) fullname = '{0}_{1}'.format(self.r.config.by_object[Submission], self.priv_submission_id) method1 = self.r.get_info(thing_id=fullname) method2 = self.r.get_submission(submission_id=self.priv_submission_id) self.assertEqual(method1, method2) @betamax def test_scope_read_get_front_page(self): self.r.refresh_access_information(self.refresh_token['mysubreddits']) subscribed = list(self.r.get_my_subreddits(limit=None)) self.r.refresh_access_information(self.refresh_token['read']) for post in self.r.get_front_page(): self.assertTrue(post.subreddit in subscribed) @betamax def test_scope_read_get_sub_listingr(self): self.r.refresh_access_information(self.refresh_token['read']) subreddit = self.r.get_subreddit(self.priv_sr) self.assertTrue(list(subreddit.get_top())) @betamax def test_scope_read_get_submission_by_url(self): url = ("https://www.reddit.com/r/reddit_api_test_priv/comments/16kbb7/" "google/") self.r.refresh_access_information(self.refresh_token['read']) submission = Submission.from_url(self.r, url) self.assertTrue(submission.num_comments != 0) @betamax def test_scope_read_priv_sr_comments(self): self.r.refresh_access_information(self.refresh_token['read']) self.assertTrue(list(self.r.get_comments(self.priv_sr))) @betamax def test_scope_read_priv_sub_comments(self): self.r.refresh_access_information(self.refresh_token['read']) submission = Submission.from_id(self.r, self.priv_submission_id) self.assertTrue(submission.comments) @betamax def test_scope_submit(self): self.r.refresh_access_information(self.refresh_token['submit']) result = self.r.submit(self.sr, 'OAuth Submit', text='Foo') self.assertTrue(isinstance(result, Submission)) @betamax def test_scope_subscribe(self): self.r.refresh_access_information(self.refresh_token['subscribe']) self.r.get_subreddit(self.sr).subscribe() @betamax def test_scope_vote(self): self.r.refresh_access_information(self.refresh_token['vote']) submission = Submission.from_id(self.r, self.submission_edit_id) submission.clear_vote() @betamax def test_set_access_credentials(self): self.assertTrue(self.r.user is None) result = self.r.refresh_access_information( self.refresh_token['identity'], update_session=False) self.assertTrue(self.r.user is None) self.r.set_access_credentials(**result) self.assertFalse(self.r.user is None) @betamax def test_oauth_without_identy_doesnt_set_user(self): self.assertTrue(self.r.user is None) self.r.refresh_access_information(self.refresh_token['edit']) self.assertTrue(self.r.user is None)
class StatisticsFeeder: """ :type db: Database :type session: Reddit """ def __init__(self, database, handler, path='../html/'): self.db = database self.path = path self.session = Reddit(user_agent='Statistics poller for RedditRover', handler=handler) self.config = ConfigParser() self.config.read(resource_filename('config', 'bot_config.ini')) self.authors = self.get_authors() self.status_online() atexit.register(self.status_offline) def _set_status(self, state, message): template_info = '''<span class="label label-{type}">Status: {title}</span>''' if state == 'online': info = template_info.format(type='success', title='Online', content=message) elif state == 'offline': info = template_info.format(type='danger', title='Offline', content=message) elif state == 'warning': info = template_info.format(type='warn', title='Warning', content=message) else: info = '' self._write_meta(info=info) def _write_meta(self, info): meta_stats = self.db.select_day_from_meta(time()) if meta_stats: date, subm, comments, cycles = meta_stats reacted = self.db.get_total_responses_per_day(time())[0] rate = reacted * 100 / (comments + subm) else: subm, comments, cycles, rate = 0, 0, 0, 0 with open(self.path + '_data/_meta.json', 'w') as f: f.write(json.dumps( {'status': info, 'submissions': subm, 'comments': comments, 'cycles': cycles, 'rate': '{:.5f}'.format(rate)} )) def status_online(self): self._set_status('online', 'The bot is currently running, last update was {}'.format(time())) def status_offline(self): self._set_status('offline', 'The bot is currently offline.') def status_warning(self, traceback=None): if traceback: self._set_status('warning', 'Here is the latest traceback: <br /><pre>{}</pre>'.format(traceback)) else: self._set_status('warning', 'Check the console, there is maybe an error. (no traceback given)') def get_authors(self): carelist = [] for section in self.config.sections(): for option in self.config.options(section): if option == 'username': carelist.append(self.config.get(section, option).lower()) return carelist def get_old_comment_karma(self): threads = self.db.get_karma_loads() for thread in threads: # tuple of tuple thing_id = thread[0] thing = self.session.get_info(thing_id=thing_id) author_votes = thing.score if type(thing) is Comment: replies = thing.replies elif type(thing) is Submission: thing.replace_more_comments(limit=None, threshold=1) replies = thing.comments elif type(thing) is MoreComments: replies = thing.comments(update=True) for comment in replies: if comment.author and comment.author.name.lower() in self.authors: self.db.update_karma_count(thing_id, author_votes, comment.score) break else: self.db.update_karma_count_with_null(thing_id, author_votes) def _write_filler_karma(self): from random import randint threads = self.db.get_karma_loads() for thread in threads: thread_id = thread[0] self.db.update_karma_count(thread_id, randint(-50, 350), randint(-50, 350)) def render_overview(self): self.status_online() self._table_rows() self._plugin_activity() self._subreddit_activity() self._post_histogram() def _table_rows(self): dataset = self.db.get_all_stats() carelist = [] title = '<a href="{url}" target="_blank" class="text-primary"> {text} </a>' subreddit = '<a href="http://reddit.com/r/{sub}" target="_blank" class="text-warning"> {sub} </a>' author = '<a href="http://reddit.com/u/{usr}" target="_blank"> {usr} </a>' for line in dataset: if line[8] and line[7]: result = line[8] - line[7] line_7 = line[7] line_8 = line[8] # @TODO: Better variable assignment else: line_7 = '-' line_8 = '-' result = '-' carelist.append({'id': line[0], 'plugin': line[1], 'time': line[2], 'title': title.format(url=line[6], text=line[3]), 'username': author.format(usr=line[4]), 'subreddit': subreddit.format(sub=line[5]), 'permalink': line[6], 'upvotes_author': line_7, 'upvotes_plugin': line_8, 'upvotes_difference': result}) with open(self.path + '_data/overview_rows.json', 'w') as f: f.write(json.dumps(carelist)) def _plugin_activity(self): dataset = self.db.get_all_stats() chart_data = {} for line in dataset: if line[1] in chart_data: chart_data[line[1]] += 1 else: chart_data[line[1]] = 1 carelist = [] for k, v in chart_data.items(): carelist.append({'name': k, 'data': v}) with open(self.path + '_data/post_list.json', 'w') as f: f.write(json.dumps(carelist)) def _subreddit_activity(self): def tighten_filter(list, min_submissions): return [dict for dict in list if dict['data'] > min_submissions] dataset = self.db.get_all_stats() carelist = [] subreddit_data = {} for line in dataset: if line[5] in subreddit_data: subreddit_data[line[5]] += 1 else: subreddit_data[line[5]] = 1 for k, v in subreddit_data.items(): carelist.append({'name': k, 'data': v}) carelist = sorted(carelist, key=lambda x: x['data']) i = 0 while(len(carelist) > 16): carelist = tighten_filter(carelist, i) i += 1 with open(self.path + '_data/subreddit_data.json', 'w') as f: f.write(json.dumps(carelist)) def _post_histogram(self): dataset = self.db.get_all_stats() carelist = [] date_change_dataset = [[line[1], datetime.datetime.strptime(line[2], "%Y-%m-%d %H:%M:%S")] for line in dataset] post_history = {} # Insert all data in hourly ticks for line in date_change_dataset: # Yay, <= py3.2 doesn't have datetime.timestamp() timestamp = int((line[1] - datetime.datetime.utcfromtimestamp(0)).total_seconds()) // 3600 if line[0] in post_history: if timestamp in post_history[line[0]]: post_history[line[0]][timestamp] += 1 else: post_history[line[0]][timestamp] = 1 else: post_history[line[0]] = {timestamp: 1} # Sort values and insert nil-values so the graphs are accurate per tick for key, value in post_history.items(): all_values = sorted(value.items()) start, end = all_values[0][0], all_values[-1][0] for x in range(start, end + 1): if x not in value: value[x] = 0 # transform the data again to get simple json for js - also transform timestamp to js readable for k, v in post_history.items(): some_list = [] for key, value in sorted(v.items()): some_list.append([key * 3600 * 1000, value]) carelist.append({'name': k, 'data': some_list}) # write out with open(self.path + '_data/post_history.json', 'w') as f: f.write(json.dumps(carelist)) def render_karma(self): self._total_karma() self._average_karma() def _total_karma(self): dataset = self.db.get_all_stats() caredict = {} carelist = [] for line in dataset: if not line[8]: karma = 0 else: karma = line[8] if line[1] in caredict: caredict[line[1]] += karma else: caredict[line[1]] = karma for key, value in caredict.items(): carelist.append({'name': key, 'data': value}) with open(self.path + '_data/total_karma.json', 'w+') as f: f.write(json.dumps(carelist)) def _average_karma(self): dataset = self.db.get_all_stats() caredict = {} carelist = [] for line in dataset: if not line[8]: karma = 0 else: karma = line[8] if line[1] in caredict: caredict[line[1]] = [caredict[line[1]][0] + karma, caredict[line[1]][1] + 1] else: caredict[line[1]] = [karma, 1] for key, value in caredict.items(): carelist.append({'name': key, 'data': value[0] / value[1]}) with open(self.path + '_data/average_karma.json', 'w+') as f: f.write(json.dumps(carelist)) def render_messages(self): self._message_rows() def _message_rows(self): carelist = [] messages = self.db.get_all_messages() message_template = 'You\'ve mailed my bot here: http://reddit.com/message/messages/{msg_id}%0A%0A---%0A%0A' url_template = 'http://reddit.com/message/compose/?to={author}&subject={subject}&message={msg_template}' reply_template = '<a href="{answer_url}" target="_blank"> {body} </a>' for line in messages: msg = message_template.format(msg_id=line[0]) url = url_template.format(author=line[4], subject=line[3], msg_template=msg) reply = reply_template.format(answer_url=url, body=line[5]) carelist.append({'id': line[0], 'plugin': line[1], 'time': line[2], 'title': line[3], 'username': line[4], 'body': reply}) with open(self.path + '_data/message_rows.json', 'w') as f: f.write(json.dumps(carelist))
class OAuth2RedditTest(PRAWTest): def setUp(self): self.configure() self.r = Reddit(USER_AGENT, site_name="reddit_oauth_test", disable_update_check=True) def test_authorize_url(self): self.r.set_oauth_app_info(None, None, None) self.assertRaises(errors.OAuthAppRequired, self.r.get_authorize_url, "dummy_state") self.r.set_oauth_app_info(self.r.config.client_id, self.r.config.client_secret, self.r.config.redirect_uri) url, params = self.r.get_authorize_url("...").split("?", 1) self.assertTrue("api/v1/authorize/" in url) params = dict(x.split("=", 1) for x in params.split("&")) expected = { "client_id": self.r.config.client_id, "duration": "temporary", "redirect_uri": ("https%3A%2F%2F127.0.0.1%3A65010%2F" "authorize_callback"), "response_type": "code", "scope": "identity", "state": "...", } self.assertEqual(expected, params) # @betamax() is currently broken for this test def test_auto_refresh_token(self): self.r.refresh_access_information(self.refresh_token["identity"]) old_token = self.r.access_token self.r.access_token += "x" # break the token self.r.user.refresh() current_token = self.r.access_token self.assertNotEqual(old_token, current_token) self.r.user.refresh() self.assertEqual(current_token, self.r.access_token) @betamax() def test_get_access_information(self): # If this test fails, the following URL will need to be visted in order # to obtain a new code to pass to `get_access_information`: # self.r.get_authorize_url('...') token = self.r.get_access_information("MQALrr1di8GzcnT8szbTWhLcBUQ") expected = {"access_token": self.r.access_token, "refresh_token": None, "scope": set(("identity",))} self.assertEqual(expected, token) self.assertEqual("PyAPITestUser2", text_type(self.r.user)) @betamax() def test_get_access_information_with_invalid_code(self): self.assertRaises(errors.OAuthInvalidGrant, self.r.get_access_information, "invalid_code") def test_invalid_app_access_token(self): self.r.clear_authentication() self.r.set_oauth_app_info(None, None, None) self.assertRaises(errors.OAuthAppRequired, self.r.get_access_information, "dummy_code") def test_invalid_app_authorize_url(self): self.r.clear_authentication() self.r.set_oauth_app_info(None, None, None) self.assertRaises(errors.OAuthAppRequired, self.r.get_authorize_url, "dummy_state") @betamax() def test_invalid_set_access_credentials(self): self.assertRaises( errors.OAuthInvalidToken, self.r.set_access_credentials, set(("identity",)), "dummy_access_token" ) def test_oauth_scope_required(self): self.r.set_oauth_app_info("dummy_client", "dummy_secret", "dummy_url") self.r.set_access_credentials(set("dummy_scope"), "dummy_token") self.assertRaises(errors.OAuthScopeRequired, self.r.get_me) @betamax() def test_scope_edit(self): self.r.refresh_access_information(self.refresh_token["edit"]) submission = Submission.from_id(self.r, self.submission_edit_id) self.assertEqual(submission, submission.edit("Edited text")) @betamax() def test_scope_history(self): self.r.refresh_access_information(self.refresh_token["history"]) self.assertTrue(list(self.r.get_redditor(self.un).get_upvoted())) @betamax() def test_scope_identity(self): self.r.refresh_access_information(self.refresh_token["identity"]) self.assertEqual(self.un, self.r.get_me().name) @betamax() def test_scope_modconfig(self): self.r.refresh_access_information(self.refresh_token["modconfig"]) self.r.get_subreddit(self.sr).set_settings("foobar") retval = self.r.get_subreddit(self.sr).get_stylesheet() self.assertTrue("images" in retval) @betamax() def test_scope_modflair(self): self.r.refresh_access_information(self.refresh_token["modflair"]) self.r.get_subreddit(self.sr).set_flair(self.un, "foobar") @betamax() def test_scope_modlog(self): num = 50 self.r.refresh_access_information(self.refresh_token["modlog"]) result = self.r.get_subreddit(self.sr).get_mod_log(limit=num) self.assertEqual(num, len(list(result))) @betamax() def test_scope_modothers_modself(self): subreddit = self.r.get_subreddit(self.sr) self.r.refresh_access_information(self.refresh_token["modothers"]) subreddit.add_moderator(self.other_user_name) # log in as other user self.r.refresh_access_information(self.other_refresh_token["modself"]) self.r.accept_moderator_invite(self.sr) # now return to original user. self.r.refresh_access_information(self.refresh_token["modothers"]) subreddit.remove_moderator(self.other_user_name) @betamax() def test_scope_modposts(self): self.r.refresh_access_information(self.refresh_token["modposts"]) Submission.from_id(self.r, self.submission_edit_id).remove() @betamax() def test_scope_modself(self): subreddit = self.r.get_subreddit(self.sr) self.r.refresh_access_information(self.refresh_token["modothers"]) subreddit.add_moderator(self.other_user_name) self.r.refresh_access_information(self.refresh_token["modcontributors"]) subreddit.add_contributor(self.other_user_name) # log in as other user self.r.refresh_access_information(self.other_refresh_token["modself"]) self.r.accept_moderator_invite(self.sr) self.r.leave_moderator(subreddit) subreddit.leave_contributor() subreddit.refresh() self.assertFalse(subreddit.user_is_moderator) self.assertFalse(subreddit.user_is_contributor) @betamax() def test_scope_mysubreddits(self): self.r.refresh_access_information(self.refresh_token["mysubreddits"]) self.assertTrue(list(self.r.get_my_moderation())) @betamax() def test_scope_modwiki(self): self.r.refresh_access_information(self.refresh_token["modwiki"]) subreddit = self.r.get_subreddit(self.sr) page = subreddit.get_wiki_page("index") page.add_editor(self.other_user_name) page.remove_editor(self.other_user_name) @betamax() def test_scope_modwiki_modcontributors(self): self.r.refresh_access_information(self.refresh_token["modwiki+contr"]) subreddit = self.r.get_subreddit(self.sr) subreddit.add_wiki_ban(self.other_user_name) subreddit.remove_wiki_ban(self.other_user_name) subreddit.add_wiki_contributor(self.other_user_name) subreddit.remove_wiki_contributor(self.other_user_name) @betamax() def test_scope_creddits(self): # Assume there are insufficient creddits. self.r.refresh_access_information(self.refresh_token["creddits"]) redditor = self.r.get_redditor("bboe") sub = self.r.get_submission(url=self.comment_url) # Test error conditions self.assertRaises(TypeError, sub.gild, months=1) for value in (False, 0, -1, "0", "-1"): self.assertRaises(TypeError, redditor.gild, value) # Test object gilding self.assertRaises(errors.InsufficientCreddits, redditor.gild) self.assertRaises(errors.InsufficientCreddits, sub.gild) self.assertRaises(errors.InsufficientCreddits, sub.comments[0].gild) @betamax() def test_scope_privatemessages(self): self.r.refresh_access_information(self.refresh_token["privatemessages"]) self.assertTrue(list(self.r.get_inbox())) @betamax() def test_scope_read(self): self.r.refresh_access_information(self.refresh_token["read"]) self.assertTrue(self.r.get_subreddit(self.priv_sr).subscribers > 0) fullname = "{0}_{1}".format(self.r.config.by_object[Submission], self.priv_submission_id) method1 = self.r.get_info(thing_id=fullname) method2 = self.r.get_submission(submission_id=self.priv_submission_id) self.assertEqual(method1, method2) @betamax() def test_scope_read_get_front_page(self): self.r.refresh_access_information(self.refresh_token["mysubreddits"]) subscribed = list(self.r.get_my_subreddits(limit=None)) self.r.refresh_access_information(self.refresh_token["read"]) for post in self.r.get_front_page(): self.assertTrue(post.subreddit in subscribed) @betamax() def test_scope_read_get_sub_listingr(self): self.r.refresh_access_information(self.refresh_token["read"]) subreddit = self.r.get_subreddit(self.priv_sr) self.assertTrue(list(subreddit.get_top())) @betamax() def test_scope_read_get_submission_by_url(self): url = "https://www.reddit.com/r/reddit_api_test_priv/comments/16kbb7/" "google/" self.r.refresh_access_information(self.refresh_token["read"]) submission = Submission.from_url(self.r, url) self.assertTrue(submission.num_comments != 0) @betamax() def test_scope_read_priv_sr_comments(self): self.r.refresh_access_information(self.refresh_token["read"]) self.assertTrue(list(self.r.get_comments(self.priv_sr))) @betamax() def test_scope_wikiread_wiki_page(self): self.r.refresh_access_information(self.refresh_token["wikiread"]) self.assertTrue(self.r.get_wiki_page(self.sr, "index")) @betamax() def test_scope_read_priv_sub_comments(self): self.r.refresh_access_information(self.refresh_token["read"]) submission = Submission.from_id(self.r, self.priv_submission_id) self.assertTrue(submission.comments) @betamax() def test_scope_submit(self): self.r.refresh_access_information(self.refresh_token["submit"]) result = self.r.submit(self.sr, "OAuth Submit", text="Foo") self.assertTrue(isinstance(result, Submission)) @betamax() def test_scope_subscribe(self): self.r.refresh_access_information(self.refresh_token["subscribe"]) self.r.get_subreddit(self.sr).subscribe() @betamax() def test_scope_vote(self): self.r.refresh_access_information(self.refresh_token["vote"]) submission = Submission.from_id(self.r, self.submission_edit_id) submission.clear_vote() @betamax() def test_set_access_credentials(self): self.assertTrue(self.r.user is None) result = self.r.refresh_access_information(self.refresh_token["identity"], update_session=False) self.assertTrue(self.r.user is None) self.r.set_access_credentials(**result) self.assertFalse(self.r.user is None) @betamax() def test_oauth_without_identy_doesnt_set_user(self): self.assertTrue(self.r.user is None) self.r.refresh_access_information(self.refresh_token["edit"]) self.assertTrue(self.r.user is None)