def make_config(filename): """ Make a new config file. """ here = os.path.dirname(os.path.abspath(__file__)) template_file = os.path.join(here, CONFIG_TEMPLATE) with open(template_file, 'r') as f: config = json.load(f) print('Generating a new config, press [Enter] to accept default value.') _ask_config(config) bot_class = get_bot_class(config['bot_class']) r = Reddit('praw/oauth_access_info_setup 1.0') r.set_oauth_app_info(**config['oauth_info']) url = r.get_authorize_url('uniqueKey', bot_class.get_scope(), True) print('Go to this url: =====\n\n{}\n\n====='.format(url)) code = input('and enter the authorization code: ') assert code, "No authorization code supplied." access_info = r.get_access_information(code) access_info.pop('scope', None) config['access_info'] = access_info with open(filename, 'w') as f: json.dump(config, f, indent=2) print('Wrote config {!r}!'.format(filename)) return config
def authorized(): reddit_state = request.args.get('state', '') reddit_code = request.args.get('code', '') if not reddit_state or not reddit_code: return redirect(url_for('index')) r = Reddit(app.config['REDDIT_USER_AGENT'], handler=handler) r.set_oauth_app_info(app.config['REDDIT_CLIENT_ID'], app.config['REDDIT_CLIENT_SECRET'], app.config['REDDIT_REDIRECT_URI']) reddit_info = r.get_access_information(reddit_code) reddit_user = r.get_me() next_path = session['last_path'] if reddit_state != session['oauth_state']: flash("Invalid state given, please try again.", 'danger') return redirect(next_path or url_for('index')) user = user_by_nickname(reddit_user.name) if user is None: nickname = reddit_user.name user = User(nickname = nickname, role = 'u', accessToken = reddit_info['access_token'], refreshToken = reddit_info['refresh_token']) else: user.accessToken = reddit_info['access_token'] user.refreshToken = reddit_info['refresh_token'] db.session.add(user) db.session.commit() remember_me = False if 'remember_me' in session: remember_me = session['remember_me'] session.pop('remember_me', None) login_user(user, remember = remember_me) # update_flair(user) return redirect(next_path or url_for('index'))
def reset_image_pool(self, num_pictures): """ Retrieves the links to all the images that we want. """ reddit = Reddit(user_agent=PROGRAM_NAME) images_downloaded = 0 sr_dict = { sr_name : reddit.get_subreddit(sr_name).get_top() for sr_name in self.subreddit_pool } # randomly pick a number of pictures from the subreddits. # skip the ones that aren't actually pictures. while images_downloaded < num_pictures: subreddit = random.choice([key for key in sr_dict.keys()]) try: submission = next(sr_dict[subreddit]) except StopIteration: # remove subreddits which run out of content del sr_dict[subreddit] # quit if we've run out of subreddits if len(sr_dict.keys()) > 0: continue; else: break; link = submission.url if utils.is_image_link(link): print('({num_pics} of {total_pics}) Image found at {url}. Downloading...'.format(num_pics=images_downloaded+1, total_pics=num_pictures, url=link)) self.download_image(link, self.get_file_name(link)) images_downloaded += 1
def test_mark_as_read(self): oth = Reddit(USER_AGENT) oth.login('PyApiTestUser3', '1111') # pylint: disable-msg=E1101 msg = six_next(oth.user.get_unread(limit=1)) msg.mark_as_read() self.assertTrue(msg not in oth.user.get_unread(limit=5))
def say_something_sciencey(): r = Reddit('bot1', user_agent='Phteven') subreddits = ['shittyaskscience', "showerthoughts"] chosen_subreddit = random.choice(subreddits) submissions = r.subreddit(chosen_subreddit) posts = submissions.hot(limit=100) self_posts = [p for p in posts if p.domain.lower() == 'self.%s'.lower() % chosen_subreddit] return random.choice(self_posts).title
def reddit_titles(sub): from praw import Reddit r = Reddit(user_agent="my_useragent") news = r.get_subreddit(sub).get_hot(limit=10) news = list(news) #num = 3 for i in news: print(i.title)
def reddit_parser(): args = build_reddit_parser().parse_args() db_connection = create_connection(args.db_host, args.db_password) reddit = Reddit(user_agent=args.user_agent) subreddit = reddit.get_subreddit(args.subreddit) if args.username: password = getpass("Enter reddit password: ") reddit.login(args.username, password) single_threaded_impl(subreddit, db_connection, args.sub_limit, args.method)
def login(): next = request.args.get('next') from uuid import uuid1 state = str(uuid1()) session['oauth_state'] = state session['last_path'] = next r = Reddit(app.config['REDDIT_USER_AGENT'], handler=handler) r.set_oauth_app_info(app.config['REDDIT_CLIENT_ID'], app.config['REDDIT_CLIENT_SECRET'], app.config['REDDIT_REDIRECT_URI']) authorize_url = r.get_authorize_url(state,refreshable=True) return redirect(authorize_url)
def update_reddit(self): #Initialize PRAW and login r = Reddit(user_agent='/r/reddevils bot by /u/Hubwub') r.login(self.username,self.password) #Grab the current settings settings = r.get_subreddit(self.subreddit).get_settings() #Update the sidebar #print sidebar settings['description'] = sidebar settings = r.get_subreddit(self.subreddit).update_settings(description=settings['description'])
def get_nude(api_key, session): if not session.get([]): reddit = Reddit(client_id='UrExvPI1zjBAiQ', client_secret=api_key, user_agent='python:desubot URL: http://github.com/Motoko11/desubot:v2.0') subreddit = reddit.subreddit('gonewild') submissions = subreddit.top(limit=64) links = [submission.url for submission in submissions if not submission.stickied] shuffle(links) session.set(links) return session.get([]).pop(0)
def test_mark_as_unread(self): oth = Reddit(USER_AGENT) oth.login('PyApiTestUser3', '1111') found = None for msg in oth.user.get_inbox(): if not msg.new: found = msg msg.mark_as_unread() break else: self.fail('Could not find a read message.') self.assertTrue(found in oth.user.get_unread())
def get(self, *args, **kwargs): username = self.kwargs['username'] api = Reddit(user_agent=settings.USER_AGENT) exists = False redditor = None try: redditor = api.get_redditor(username) exists = True except HTTPError: exists = False data = {'exists': exists} if redditor: data['redditor'] = redditor.fullname return Response(data)
def test_mark_multiple_as_read(self): oth = Reddit(USER_AGENT) oth.login('PyApiTestUser3', '1111') messages = [] for msg in oth.user.get_unread(limit=None): if msg.author != oth.user.name: messages.append(msg) if len(messages) >= 2: return self.assertEqual(2, len(messages)) self.r.user.mark_as_read(messages) unread = oth.user.get_unread(limit=5) for msg in messages: self.assertTrue(msg not in unread)
def main(): parser = argparse.ArgumentParser( prog='modbot.py', description="Subreddit automoderating script") parser.add_argument('subreddit') parser.add_argument('-r', '--rulesdir', default='./rules') parser.add_argument('-u', '--user') parser.add_argument('-p', '--password') args = parser.parse_args() rh = RuleHandler(args.rulesdir, '*.rule') logging.config.fileConfig('logging.conf') reddit = Reddit('%s/%s' % (NAME, VERSION)) try: reddit.login(args.user, args.password) except praw.errors.InvalidUserPass: logging.critical("Login failure") sys.exit(1) sub = reddit.get_subreddit(args.subreddit) read_thinglists() comments_ph = None submissions_ph = None while True: logging.debug("Loop start") loopstart = time.time() try: modqueue_items = sub.get_mod_queue(limit=100) except Exception, e: modqueue_items = [] num = 0 for modqueue_item in modqueue_items: num += 1 matchrules(modqueue_item, rh.rules, is_modqueue=True) logging.info("Checked %d modqueue items" % num) try: if comments_ph == None: comments = sub.get_comments(limit=100) else: comments = sub.get_comments(place_holder=comments_ph, limit=500) except Exception, e: comments = []
def update_countdown(username, password, subreddit_name, target): user_agent = '/r/{0} countdown'.format(subreddit_name) reddit = Reddit(user_agent) reddit.login(username, password, disable_warning=True) # reddit access subreddit = reddit.get_subreddit(subreddit_name) settings = subreddit.get_settings() description = HTMLParser().unescape(settings['description']) # time matches countdown_delta = target - datetime.now() days_left = countdown_delta.days hours_left = countdown_delta.seconds // 3600 # regex and strings # countdownSearch = re.compile("(\[\d?\d?\]\([#][a-z]*\)\s[a-z]*[!]?\s?)+", re.I) # old regex countdownSearch = re.compile("((\s([a-z]{4})*)*\s?\[\d?\d?\]\([#][a-z]*\)\s[a-z]*[!]?\s?)+", re.I) origStr = " less than [](#days) days [](#hours) hours\n" noDaysStr = " less than [](#hours) hours\n" noHoursStr = " less than [](#minutes) minutes\n" raceLiveStr = " [](#days) Racing [](#hours) is [](#minutes) live\n" updatemeStr = " [](#days) Current [](#hours) event [](#minutes) ended\n" # make sure our event hasn't happened yet if target > datetime.now(): if days_left > 0: description = re.sub(countdownSearch, origStr, description) elif hours_left > 0 and days_left == 0: description = re.sub(countdownSearch, noDaysStr, description) else: description = re.sub(countdownSearch, noHoursStr, description) for key, value in compute_time_ago_params(target).iteritems(): pattern = "\\[[^\\]]*\\]\\(#{0}\\)".format(key) # replace [<anything>](#<key>) repl = "[{0}](#{1})".format(value, key) # with [<value>](#<key>) description = re.sub(pattern, repl, description) # if race is happening, show raceLiveStr, else race is over, show updatemeStr else: countdownSearch.search(description) if target.hour > datetime.now().hour - 3: description = re.sub(countdownSearch, raceLiveStr, description) else: description = re.sub(countdownSearch, updatemeStr, description) subreddit.update_settings(description=description)
def create_sidebar(self): h = HTMLParser.HTMLParser() #Initialize PRAW and login r = Reddit(user_agent='/r/reddevils bot by /u/Hubwub') r.login(self.username,self.password) #Grab the sidebar template from the wiki sidebar = r.get_subreddit(self.subreddit).get_wiki_page('edit_sidebar').content_md #Create list from sidebar by splitting at #### sidebar_list = sidebar.split('####') #Sidebar #print sidebar_list #sidebar = (sidebar_list[0]+league+sidebar_list[1]) sidebar = (sidebar_list[0]+league+rfixtures+goals+sidebar_list[1]) #Fix characters in sidebar sidebar = h.unescape(sidebar) return sidebar
def update_countdown(username, password, subreddit_name, target): user_agent = '/r/{0} countdown bot'.format(subreddit_name) reddit = Reddit(user_agent) reddit.login(username, password) subreddit = reddit.get_subreddit(subreddit_name) settings = subreddit.get_settings() description = HTMLParser().unescape(settings['description']) for key, value in compute_time_ago_params(target).iteritems(): pattern = "\\[[^\\]]*\\]\\(#{0}\\)".format(key) # replace [<anything>](#<key>) repl = "[{0}](#{1})".format(value, key) # with [<value>](#<key>) description = re.sub(pattern, repl, description) print(description) subreddit.update_settings(description=description)
def whoosh(r: praw.Reddit): print("Looking for unsuspecting victim") comment_made = False while not comment_made: random_sub = r.get_random_subreddit() print("Searching top submissions of {}".format(random_sub.display_name)) try: for submission in random_sub.get_hot(limit=10): flat_comments = praw.helpers.flatten_tree(submission.comments) for comment in flat_comments: if any(string in comment.body for string in words_to_monitor): print("Victim Found!") comment.reply(random.choice(what_to_say)) print("Comment made to post {} with comment id {}".format(submission.id, comment.id)) comment_made = True break # Only antagonize our first found victim. Nothing more. else: continue break else: continue break except (AttributeError, praw.errors.APIException) as e: print("Error encountered:") print(e) print("Moving onto next sub")
class GenericRedditLink: def __init__(self,parent): self.r=Reddit(user_agent="PollBotBestBot") self.parent=parent def __call__(self,msg): if msg["body"].lower().startswith("!r/"): m=msg["body"].lstrip("!r/") spli=m.split(":") subreddit=spli[0] print subreddit if subreddit in config.banned_subreddits: self.parent.scheduler.add("punishment:"+msg["mucnick"],0.1,self.parent.punishment,args=(msg["mucnick"],),repeat=True) self.parent.send_message(mto=self.parent.channel,mbody="Nope, not touching that.",mtype="groupchat") return body=self.get_hot(subreddit,msg) if body!=None: self.parent.send_message(mto=self.parent.channel,mbody=body,mtype="groupchat") if msg["body"].lower().startswith("!block ") and msg["mucnick"] in config.admins: m=m.spli(" ") subreddit=spli[1] config.banned_subreddits.append(subreddit) def get_hot(self,subreddit,msg): if msg["type"]=="groupchat": subreddit=self.r.get_subreddit(subreddit) try: if subreddit.over18: pass except (HTTPError, errors.InvalidSubreddit) as E: self.parent.send_message(mto=self.parent.channel,mbody="Learn to Reddit please, "+msg["mucnick"],mtype="groupchat") return None if subreddit.over18: #self.parent.send_message(mto=self.parent.channel,mbody="NSFW content is currently blocked. Direct complaints to mods and admins.",mtype="groupchat") extra=" :nws: " else: extra="" submissions=subreddit.get_hot(limit=10) a=None a1=None limit=random.randint(0,9) while limit>0: a1=a print a1 try: a=next(submissions) except StopIteration: a=a1 break print a limit-=1 try: return "\n"+extra+str(a.title)+extra+"\n"+extra+str(a.url)+extra except AttributeError: return "Reddit API is currently not accepting connections. Please wait ~30 seconds before retrying."
def __init__(self,parent): self.r=Reddit(user_agent="PollBotBestBot") self.parent=parent self.messagable=True self.trackable=False self.active=True self.cache=[]
def __init__(self, subreddit, site=None, user=None, pswd=None, verbose=None): self.reddit = Reddit(str(self), site) self._logged_in = False self._user = user self._pswd = pswd self.sub = self.reddit.get_subreddit(subreddit) self.verbose = verbose self._current_flair = None
def __init__(self, username, passwd, url, subreddit): self.rh = Reddit('Release the Snitch v 0.1 by Kolpa') self.rh.login(username, passwd) self.css = self.__load_css() self.desc = self.__load_desc() self.url = url self.subreddit = subreddit
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 __init__(self, subreddit, site=None, user=None, pswd=None, verbose=None): self.reddit = Reddit(str(self), site, disable_update_check=True) self.reddit.config.decode_html_entities = True self._logged_in = False self._user = user self._pswd = pswd self.sub = self.reddit.get_subreddit(subreddit) self.verbose = verbose self._current_flair = None
def test_report(self): # login as new user to report submission oth = Reddit(USER_AGENT) oth.login('PyApiTestUser3', '1111') subreddit = oth.get_subreddit(self.sr) submission = None for submission in subreddit.get_new_by_date(): if not submission.hidden: break else: self.fail('Could not find a non-reported submission.') submission.report() # check if submission was reported for report in self.r.get_subreddit(self.sr).get_reports(): if report.id == submission.id: break else: self.fail('Could not find reported submission.')
def __init__(self, subreddit, site=None, user=None, pswd=None, verbose=None): """Initialize the ModUtils class by passing in config options.""" self.reddit = Reddit(str(self), site, disable_update_check=True) self.reddit.config.decode_html_entities = True self._logged_in = False self._user = user self._pswd = pswd self.sub = self.reddit.get_subreddit(subreddit) self.verbose = verbose self._current_flair = None
def __init__(self,parent): self.r=Reddit(user_agent="PollBotBestBot")# self.r.login("PollBotBestBot", config.reddit_password) self.parent=parent self.values=[] self.limit=1000 self.currentSubmission="" self.status="WAITING"
def scrape(subreddit_name, backfill_to=None): """ Scrape a subreddit. :type subreddit_name: str :type backfill_to: datetime.datetime """ subreddit_name = subreddit_name.lower() imgur_client = ImgurClient( settings.IMGUR_CLIENT_ID, settings.IMGUR_CLIENT_SECRET) reddit = Reddit(user_agent=settings.REDDIT_USER_AGENT) subreddit = reddit.get_subreddit(subreddit_name) with session_manager() as session: if backfill_to is not None: _backfill( session, subreddit, subreddit_name, imgur_client, backfill_to) else: _scrape(session, subreddit, subreddit_name, imgur_client)
def ban_users(reddit: praw.Reddit, users): """ Ban the users on reddit. """ print("Updating DB objects...") # First pass, update database objects. for user, subs in users.items(): if user in config.EXEMPT_USERS: # Ignore these guys. They're cool/bots. continue if not db.session.query(exists().where(db.BannedUser.username == user)).scalar(): # Update. u = db.BannedUser(username=user, reason="AutoCensor automatic ban - Subreddits: {}".format(",").join(subs)) db.session.add(u) # Commit session. db.session.commit() print("Building many-to-many entries...") # Second pass, check for users and subreddits, and update many-to-many entires. for user in users: if user in config.EXEMPT_USERS: # Ignore these guys. They're cool/bots. continue try: u_object = db.session.query(db.BannedUser).filter(db.BannedUser.username == user).one() except sqlalchemy.orm.exc.NoResultFound: continue for managing_sub in db.session.query(db.ManagingSubreddit).all(): if u_object not in managing_sub.users: managing_sub.users.append(u_object) db.session.add(managing_sub) db.session.commit() print("Banning users...") banned = 0 # Last pass, ban them on our subreddits. for subobject in db.session.query(db.ManagingSubreddit).all(): # Get the subreddit. sub = reddit.get_subreddit(subobject.name) # Get the users. for user in subobject.users: # Begin the bans! try: sub.add_ban( user.username, ban_reason="Automatically banned for posting in these subreddits: {}".format(user.reason), note="Automatically banned for posting in these subreddits: {}".format(user.reason), ) banned += 1 except: # whatever continue return banned
def set_up_record(self): if not self._overrode_reddit_setup: if (pytest.placeholders.refresh_token != "placeholder_refresh_token"): self.reddit = Reddit( requestor_kwargs={"session": self._session}, client_id=pytest.placeholders.client_id, client_secret=pytest.placeholders.client_secret, user_agent=pytest.placeholders.user_agent, refresh_token=pytest.placeholders.refresh_token, )
def login(): #reddit reddit = Reddit(client_id=config["client_id"], client_secret=config["client_secret"], password=config["redditpassword"], user_agent=config["user_agent"], username=config["redditusername"]) # instagram instagram = Client(config["instagramusername"], config["instagrampassword"]) return reddit, instagram
def test_reddit__missing_required_settings(self): for setting in self.REQUIRED_DUMMY_SETTINGS: with pytest.raises(ClientException) as excinfo: settings = self.REQUIRED_DUMMY_SETTINGS.copy() settings[setting] = Config.CONFIG_NOT_SET Reddit(**settings) assert str(excinfo.value).startswith( "Required configuration " "setting '{}' missing.".format(setting)) if setting == "client_secret": assert "set to None" in str(excinfo.value)
def test_reddit__missing_required_settings(self): for setting in self.REQUIRED_DUMMY_SETTINGS: with pytest.raises(ClientException) as excinfo: settings = self.REQUIRED_DUMMY_SETTINGS.copy() del settings[setting] Reddit(**settings) assert str(excinfo.value).startswith( 'Required configuration ' 'setting \'{}\' missing.'.format(setting)) if setting == 'client_secret': assert 'set to None' in str(excinfo.value)
def setup_reddit(self): self._session = requests.Session() self.reddit = Reddit( requestor_kwargs={"session": self._session}, client_id=pytest.placeholders.client_id, client_secret=pytest.placeholders.client_secret, password=pytest.placeholders.password, user_agent=pytest.placeholders.user_agent, username=pytest.placeholders.username, )
def test_conflicting_settings(self): with pytest.raises(TypeError) as excinfo: Reddit( refresh_token="dummy", token_manager="dummy", **self.REQUIRED_DUMMY_SETTINGS, ) assert ( str(excinfo.value) == "legacy ``refresh_token`` setting cannot be provided when providing ``token_manager``" )
def test_check_for_async(self, caplog): reddit = Reddit(**self.REQUIRED_DUMMY_SETTINGS) reddit._core.request = self.patch_request loop = asyncio.get_event_loop() loop.run_until_complete(self.check_async(reddit)) log_record = caplog.records[0] assert log_record.levelname == "WARNING" assert ( log_record.message == "It appears that you are using PRAW in an asynchronous environment.\nIt is strongly recommended to use Async PRAW: https://asyncpraw.readthedocs.io.\nSee https://praw.readthedocs.io/en/latest/getting_started/multiple_instances.html#discord-bots-and-asynchronous-environments for more info.\n" )
def test_reddit__required_settings_set_to_none(self): required_settings = self.REQUIRED_DUMMY_SETTINGS.copy() del required_settings["client_secret"] for setting in required_settings: with pytest.raises(ClientException) as excinfo: settings = self.REQUIRED_DUMMY_SETTINGS.copy() settings[setting] = None Reddit(**settings) assert str(excinfo.value).startswith( "Required configuration " "setting '{}' missing.".format(setting))
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 reddit_activity(username: str): """Requests comment and submission data for the given user and any other users they have interacted with. Interactions between users are when the given user has replied to a submission or comment by another user. Writes data to out/{username}.csv. """ reddit = Reddit(client_id=config.client_id, client_secret=config.client_secret, user_agent=config.user_agent) # Build queue of users to collect activity of: provided user and users they have interacted via replying # Also append users who have interacted with provided user (they replied to a post/comment) users = exactlyOnceQueue() users.append(username) redditor = Redditor(reddit, name=username) for comment in redditor.comments.new(): if comment.parent().author: users.append(str(comment.parent().author)) # Add users who have replied to this comment for reply in comment.replies: if reply.author: users.append(str(reply.author)) for submission in redditor.submissions.new(): # Add users who have replied to this submission for reply in submission.comments: if reply.author: users.append(str(reply.author)) # Get comment and submission data of each user and append to list data = [] print(f'users to process:{str(len(users))}') while len(users) > 0: redditor = Redditor(reddit, name=users.pop()) # type: Redditor try: for submission in redditor.submissions.new(): # type: Submission row = parse_submission(submission) data.append(row) for comment in redditor.comments.new(): # type: Comment row = parse_comment(comment) data.append(row) except exceptions.NotFound: print(f'Exception occured on user {str(redditor)}') except exceptions.Forbidden: print(f'Exception occured on user {str(redditor)}') print(f'user complete, remaining = {str(len(users))}') # Construct DataFrame from list and write to CSV df = pandas.DataFrame(data=data, columns=['id', 'author', 'date', 'subreddit', 'replyingTo', 'polarity', 'subjectivity', 'replyCount']) df.set_index('id', inplace=True) df.to_csv(f'out/{username}.csv')
def test_read_only__without_untrusted_authenticated_core(self): required_settings = self.REQUIRED_DUMMY_SETTINGS.copy() required_settings['client_secret'] = None with Reddit(password=None, username=None, **required_settings) as reddit: assert reddit.read_only with pytest.raises(ClientException): reddit.read_only = False assert reddit.read_only reddit.read_only = True assert reddit.read_only
def set_reddit(*args, **kwargs): """Set all API hooks to use a single PRAW Reddit session. Parameters ---------- args : Positional Arguments Positional arguments used in instantiation of a Reddit session object. kwargs : Keyword Arguments Keyword arguments used in instantiation of a Reddit session object. """ HookBase.reddit = Reddit(*args, **kwargs)
def reddit_setup(): ''' Create reddit instance returns api: Reddit - Reddit instance''' api = Reddit(client_id=reddit_credentials.CLIENT_ID, client_secret=reddit_credentials.CLIENT_SECRET, user_agent=reddit_credentials.USER_AGENT, username=reddit_credentials.USERNAME, password=reddit_credentials.PASSWORD) return api
class RedditConnector(object): def __init__(self): super().__init__() self.reddit = Reddit(client_id = "", client_secret = "", user_agent = "", username = "", password = "") def get_url_details(self, url): return self.reddit.submission(url=url)
def test_read_only__with_authenticated_core(self): with Reddit( password=None, username=None, token_manager=DummyTokenManager(), **self.REQUIRED_DUMMY_SETTINGS, ) as reddit: assert not reddit.read_only reddit.read_only = True assert reddit.read_only reddit.read_only = False assert not reddit.read_only
def test_read_only__with_authenticated_core(self): with Reddit( password=None, refresh_token="refresh", username=None, **self.REQUIRED_DUMMY_SETTINGS, ) as reddit: assert not reddit.read_only reddit.read_only = True assert reddit.read_only reddit.read_only = False assert not reddit.read_only
def __init__(self, bot: Bot) -> None: try: self.reddit_client = RedditAPI( client_id=os.getenv("REDDIT_CLIENT_ID"), client_secret=os.getenv("REDDIT_CLIENT_SECRET"), user_agent=os.getenv("REDDIT_USER_AGENT"), username=os.getenv("REDDIT_USERNAME"), ) except MissingRequiredAttributeException: print("Reddit cog requires correct enviroment variables") self.cog_unload() self.bot = bot
def get_authed_reddit_for_cubersio_acct(): """ Returns a PRAW instance for the Reddit account to post the competition under. """ if __IS_DEVO: token = get_user_by_username(__DEVO_CUBERSIO_ACCT).reddit_token else: token = get_user_by_username(__PROD_CUBERSIO_ACCT).reddit_token return Reddit(client_id=__CLIENT_ID, client_secret=__CLIENT_SECRET, refresh_token=token, user_agent=__USER_AGENT)
def get_reddit_news(subs, search_terms, limit=None, praw_config='StockMarketML'): from praw import Reddit reddit = Reddit(praw_config) articles = defaultdict(list) used = [] for term in search_terms: for submission in reddit.subreddit('+'.join(subs)).search(term, limit=limit): if submission.title not in used: used.append(submission.title) articles[datetime.fromtimestamp(submission.created).strftime('%Y-%m-%d')].append(submission.title) return articles
def test_user_agent(self): self.assertWarnings(UserWarning, Reddit, 'robot agent') google_app_engine = "Google App Engine v2.6" old_server_software, os.environ['SERVER_SOFTWARE'] = \ os.getenv('SERVER_SOFTWARE'), google_app_engine try: self.assertIn(google_app_engine, Reddit('robot engine').http.headers['User-Agent']) finally: del os.environ['SERVER_SOFTWARE'] if old_server_software is not None: os.environ['SERVER_SOFTWARE'] = old_server_software
class SubredditStats(object): """Contain all the functionality of the subreddit_stats command.""" def __init__(self, subreddit): """Initialize the SubredditStats instance with config options.""" self.comments = [] self.submissions = [] self.reddit = Reddit(check_for_updates=False, user_agent=AGENT) self.subreddit = self.reddit.subreddit(subreddit) def fetch_gold(self): """Fetch recent glided content. """ for gilded in self.subreddit.gilded(): if isinstance(gilded, Comment): self.comments.append(gilded) else: self.submissions.append(gilded) def process_gilded(self): """Write gilded file.""" filename = '%s-gilded.csv' % self.base_filename LOGGER.debug('Processing gilded to %s', filename) with open(filename, 'w', newline='', encoding='utf-8') as f: writer = csv.writer(f, dialect=CustomDialect) writer.writerow([ 'id', 'author', 'score ', 'permalink', 'link_id', 'created_utc', 'distinguished', 'gilded' ]) for c in self.submissions: writer.writerow([ c.id, c.author, c.score, c.permalink, c.id, c.created_utc, c.distinguished, c.gilded ]) for c in self.comments: writer.writerow([ c.id, c.author, c.score, c.permalink(fast=True), c.link_id, c.created_utc, c.distinguished, c.gilded ]) return filename def run(self): """Run stats and return the created Submission.""" LOGGER.info('Analyzing subreddit: %s', self.subreddit) self.base_filename = '%s-%d' % (str(self.subreddit), time.time()) self.fetch_gold() if not self.comments and not self.submissions: LOGGER.warning('No submissions were found.') return return self.process_gilded()
def get_reddit_details(posts: List[PostType], reddit_inst: praw.Reddit) -> List[PostType]: """ Gets details of each post (i.e. score, title, etc.) and puts them into their PostType objects. :param posts: List of PostType objects with post ID and partial :param reddit_inst: Current reddit instance from praw. :return: """ post: PostType submission: praw.models.submission.Submission getting_sub: bool = True log.info("Collecting post data.") for post in posts: # Iterate through posts while getting_sub: # Loop to make sure the submission gets grabbed. try: submission = reddit_inst.submission(post.post_id) getting_sub = False except RECOVERABLE_EXC as err: log.debug(f"Couldn't get submission: {err}") time.sleep(5) try: # First get string items from post. post.post_url = f"https://old.reddit.com{submission.permalink}" post.title = submission.title post.author = submission.author if submission.author is not None else "Deleted" post.flair = submission.link_flair_text if submission.link_flair_text is not None else "" post.link = submission.url if not submission.is_self else "" post.self_text = submission.selftext if submission.is_self else "" post.subreddit = submission.subreddit.display_name # Then booleans post.stickied = submission.stickied post.locked = submission.locked post.edited = submission.edited post.distinguished = submission.distinguished post.is_self = submission.is_self post.locked = submission.locked post.spoiler = submission.spoiler # Lastly numerics post.post_score = submission.score post.num_of_comments = submission.num_comments post.percent_upvoted = submission.upvote_ratio post.time_created = submission.created_utc except NameError: log.debug("Submission could not be found and was not caught.") log.info("All post data collected.") return posts
def _initialize_api_wrappers(self): """ Initialize API Wrappers (PRAW and/or PSAW) Args: None Returns: None. Sets class api attribute. """ if self._init_praw: ## Load Credentials config_file = os.path.join(os.path.abspath(__file__).split(__file__)[0], "config.json") config = json.load(open(config_file,"r"))["reddit"] self._praw = Reddit(**config) ## Initialize API Objects self.api = PushshiftAPI(self._praw) else: ## Initialize API Objects self.api = PushshiftAPI()
class ConfigUpdater(GameThreadThread): # TODO: Add validation with pykwalify interval = timedelta(minutes=15) def __init__(self, root_sub, *args, **kwargs): self.r = Reddit('gamethread') self.root_sub = self.r.subreddit(root_sub) super().__init__(*args, **kwargs) def lap(self): root_config = SubredditCustomConfig(self.root_sub, 'gamethreads/root_config') self.save_root_config(self.root_sub, root_config.config) self.update_subreddits(set(root_config.get('subreddits'))) def save_root_config(self, root_sub, root_config): session = self.Session() obj, created = get_or_create(session, Config, name=root_sub.display_name) if obj.config != root_config: session.add(obj) obj.config = root_config obj.config_updated_utc = now() self.logger.info("Save %s: %r", root_sub, root_config) session.commit() def update_subreddits(self, sr_names): for sr_name in sr_names: self.logger.info("Updating config for %s", sr_name) session = self.Session() obj, created = get_or_create(session, Subreddit, name=sr_name) sr = self.r.subreddit(sr_name) sr_config = SubredditCustomConfig(sr, 'gamethreads/config') if obj.config != sr_config.config: session.add(obj) obj.config = sr_config.config self.logger.info("Got updated config: %r", obj.config) obj.config_updated_utc = now() session.commit()
def test_me__in_read_only_mode(self): self.reddit = Reddit( client_id="dummy", client_secret="dummy", praw8_raise_exception_on_me=True, user_agent="dummy", ) self.reddit._core._requestor._http = None assert self.reddit.read_only user = User(self.reddit) with pytest.raises(ReadOnlyException): user.me()
def first_time_user(context, interest): while True: state = AdapterRedditClient.gen_state() if not State.objects.filter(state__exact=state).exists(): a = State.objects.create(interest=interest, state=state, user=context.author.id) r = Reddit(client_id=CLIENT_ID, client_secret=CLIENT_SECRET, redirect_uri='https://redcord.ks-dev.com/auth', user_agent=UA) return r.auth.url(['submit', 'edit', 'read'], a.state, 'permanent')
def __init__(self, token=None, **kwargs): super(ServiceReddit, self).__init__(token, **kwargs) self.consumer_key = settings.TH_REDDIT_KEY['client_id'] self.consumer_secret = settings.TH_REDDIT_KEY['client_secret'] self.user_agent = settings.TH_REDDIT_KEY['user_agent'] self.service = 'ServiceReddit' self.oauth = 'oauth2' if token: self.token = token self.reddit = RedditApi(client_id=self.consumer_key, client_secret=self.consumer_secret, refresh_token=self.token, user_agent=self.user_agent)
def __init__(self, subreddit, site, distinguished, reddit=None): """Initialize the SubredditStats instance with config options.""" self.commenters = defaultdict(list) self.comments = [] self.distinguished = distinguished self.min_date = 0 self.max_date = time.time() - SECONDS_IN_A_DAY self.reddit = (reddit or Reddit( site, check_for_updates=False, user_agent=AGENT)) self.submissions = {} self.submitters = defaultdict(list) self.submit_subreddit = self.reddit.subreddit('subreddit_stats') self.subreddit = self.reddit.subreddit(subreddit)
def get_bot_permissions(sub_name: Text, reddit: Reddit) -> List[Text]: log.debug('Getting bot permissions on %s', sub_name) subreddit = reddit.subreddit(sub_name) if not subreddit: log.error('Failed to locate subreddit %s', sub_name) return None try: for mod in subreddit.moderator(): if mod.name == 'RepostSleuthBot': return mod.mod_permissions except Forbidden: return [] return []
def test_read_only__with_authenticated_core__non_confidential(self): with Reddit( client_id="dummy", client_secret=None, redirect_uri="dummy", user_agent="dummy", refresh_token="dummy", ) as reddit: assert not reddit.read_only reddit.read_only = True assert reddit.read_only reddit.read_only = False assert not reddit.read_only