def friend(self): """Friend the user. :returns: The json response from the server. """ self.reddit_session.evict(self.reddit_session.config['friends']) return _modify_relationship('friend')(self.reddit_session.user, self)
def unfriend(self): """Unfriend the user. :returns: The json response from the server. """ self.reddit_session.evict(self.reddit_session.config["friends"]) return _modify_relationship("friend", unlink=True)(self.reddit_session.user, self)
def test_restrict_access_permission_errors(self): # PRAW doesn't currently use _modify_relationship for friending but # this same check might be needed in the future, so, lets use this to # our advantage, temporarily bind a custom unfriend function, ensure # the proper error is raised, and then, unbind this function. redditor = self.r.get_redditor(self.un) redditor.temp_make_friend = _modify_relationship('friend') self.assertRaises(errors.LoginRequired, redditor.temp_make_friend, thing=None, user=self.other_user_name) del redditor.temp_make_friend # PRAW doesn't currently use restrict_access for mod duties without # setting a scope but this might be needed in the future, so, lets use # _modify_relationship to our advantage, temporarily bind a custom # nonsense function, ensure the proper error is raised, and then, # unbind this function. This can also be used to detect the # ModeratorRequired exception from restrict_access as PRAW doesn't have # any functions that would ordinarily end in this outcome, as all # moderator reddit endpoints are oauth compatible. subreddit = self.r.get_subreddit(self.sr) type(subreddit).temp_nonsense = _modify_relationship('nonsense') self.assertRaises(errors.LoginRequired, subreddit.temp_nonsense, user=self.un) self.r.login(self.other_non_mod_name, self.other_non_mod_pswd, disable_warning=True) subreddit = self.r.get_subreddit(self.sr) self.assertRaises(errors.ModeratorRequired, subreddit.temp_nonsense, user=self.un) del type(subreddit).temp_nonsense # PRAW doesn't currently have a method in which the subreddit # is taken from function defaults, so, let's write one instead @restrict_access(mod=True, scope=None) def fake_func(obj, **kwargs): return None type(self.r).fake_func = fake_func self.assertRaises(errors.ModeratorRequired, self.r.fake_func) del type(self.r).fake_func
class Subreddit(Messageable, Refreshable): """A class for Subreddits.""" _methods = (('accept_moderator_invite', AR), ('add_flair_template', MFMix), ('clear_flair_templates', MFMix), ('configure_flair', MFMix), ('delete_flair', MFMix), ('delete_image', MCMix), ('edit_wiki_page', AR), ('get_banned', MOMix), ('get_comments', UR), ('get_contributors', MOMix), ('get_flair', UR), ('get_flair_list', MFMix), ('get_moderators', UR), ('get_mod_log', MLMix), ('get_mod_queue', MOMix), ('get_mod_mail', MOMix), ('get_random_submission', UR), ('get_reports', MOMix), ('get_settings', MCMix), ('get_spam', MOMix), ('get_stylesheet', MOMix), ('get_unmoderated', MOMix), ('get_wiki_banned', MOMix), ('get_wiki_contributors', MOMix), ('get_wiki_page', UR), ('get_wiki_pages', UR), ('search', UR), ('select_flair', AR), ('set_flair', MFMix), ('set_flair_csv', MFMix), ('set_settings', MCMix), ('set_stylesheet', MCMix), ('submit', SubmitMixin), ('subscribe', SubscribeMixin), ('unsubscribe', SubscribeMixin), ('update_settings', MCMix), ('upload_image', MCMix)) # Subreddit banned add_ban = _modify_relationship('banned', is_sub=True) ban = _modify_relationship('banned', is_sub=True, deprecated='add_ban') unban = _modify_relationship('banned', unlink=True, is_sub=True, deprecated='remove_ban') remove_ban = _modify_relationship('banned', unlink=True, is_sub=True) # Subreddit contributors add_contributor = _modify_relationship('contributor', is_sub=True) make_contributor = _modify_relationship('contributor', is_sub=True, deprecated='add_contributor') remove_contributor = _modify_relationship('contributor', unlink=True, is_sub=True) # Subreddit moderators add_moderator = _modify_relationship('moderator', is_sub=True) make_moderator = _modify_relationship('moderator', is_sub=True, deprecated='add_moderator') remove_moderator = _modify_relationship('moderator', unlink=True, is_sub=True) # Subreddit wiki banned add_wiki_ban = _modify_relationship('wikibanned', is_sub=True) remove_wiki_ban = _modify_relationship('wikibanned', unlink=True, is_sub=True) # Subreddit wiki contributors add_wiki_contributor = _modify_relationship('wikicontributor', is_sub=True) remove_wiki_contributor = _modify_relationship('wikicontributor', unlink=True, is_sub=True) # Generic listing selectors get_controversial = _get_sorter('controversial') get_hot = _get_sorter('') get_new = _get_sorter('new') get_top = _get_sorter('top') # Explicit listing selectors get_controversial_from_all = _get_sorter('controversial', t='all') get_controversial_from_day = _get_sorter('controversial', t='day') get_controversial_from_hour = _get_sorter('controversial', t='hour') get_controversial_from_month = _get_sorter('controversial', t='month') get_controversial_from_week = _get_sorter('controversial', t='week') get_controversial_from_year = _get_sorter('controversial', t='year') get_new_by_date = _get_sorter('new', deprecated='get_new') get_new_by_rising = _get_sorter('rising', deprecated='get_rising') get_rising = _get_sorter('rising') get_top_from_all = _get_sorter('top', t='all') get_top_from_day = _get_sorter('top', t='day') get_top_from_hour = _get_sorter('top', t='hour') get_top_from_month = _get_sorter('top', t='month') get_top_from_week = _get_sorter('top', t='week') get_top_from_year = _get_sorter('top', t='year') def __cmp__(self, other): """Compare two subreddits based on the lowercase of their name. :returns: negative, 0, or positive depending on the comparison. """ return cmp(self.display_name.lower(), other.display_name.lower()) def __init__(self, reddit_session, subreddit_name=None, json_dict=None, fetch=False): # Special case for when my_subreddits is called as no name is returned # so we have to extract the name from the URL. The URLs are returned # as: /r/reddit_name/ if not subreddit_name: subreddit_name = json_dict['url'].split('/')[2] info_url = reddit_session.config['subreddit_about'] % subreddit_name super(Subreddit, self).__init__(reddit_session, json_dict, fetch, info_url) self.display_name = subreddit_name self._url = reddit_session.config['subreddit'] % subreddit_name # '' is the hot listing listings = ['new/', '', 'top/', 'controversial/'] base = (reddit_session.config['subreddit'] % self.display_name) self._listing_urls = [base + x + '.json' for x in listings] def __unicode__(self): return self.display_name def clear_all_flair(self): """Remove all user flair on this subreddit. :returns: The json response from the server when there is flair to clear, otherwise returns None. """ csv = [{'user': x['user']} for x in self.get_flair_list(limit=None)] if csv: return self.set_flair_csv(csv) else: return