def test_gild__no_creddits(self):
     self.reddit.read_only = False
     with self.recorder.use_cassette('TestComment.test_gild__no_creddits'):
         with pytest.raises(BadRequest) as excinfo:
             Comment(self.reddit, 'd1616q2').gild()
         reason = excinfo.value.response.json()['reason']
         assert 'INSUFFICIENT_CREDDITS' == reason
Exemple #2
0
 def test_refresh__removed_comment(self):
     with self.recorder.use_cassette("TestComment.test_refresh__removed_comment"):
         with pytest.raises(ClientException) as excinfo:
             Comment(self.reddit, "dma3mi5").refresh()
     assert (
         "This comment does not appear to be in the comment tree",
     ) == excinfo.value.args
 def test_attributes(self):
     with self.recorder.use_cassette('TestComment.test_attributes'):
         comment = Comment(self.reddit, 'cklhv0f')
         assert comment.author == 'bboe'
         assert comment.body.startswith('Yes it does.')
         assert not comment.is_root
         assert comment.submission == '2gmzqe'
 def test_refresh__deleted_comment(self):
     with self.recorder.use_cassette(
             'TestComment.test_refresh__deleted_comment'):
         with pytest.raises(ClientException) as excinfo:
             Comment(self.reddit, 'd7ltvl0').refresh()
     assert ('This comment does not appear to be in the '
             'comment tree', ) == excinfo.value.args
Exemple #5
0
 def test_attributes(self):
     with self.recorder.use_cassette("TestComment.test_attributes"):
         comment = Comment(self.reddit, "cklhv0f")
         assert comment.author == "bboe"
         assert comment.body.startswith("Yes it does.")
         assert not comment.is_root
         assert comment.submission == "2gmzqe"
Exemple #6
0
 def test_gild__no_creddits(self):
     self.reddit.read_only = False
     with self.recorder.use_cassette("TestComment.test_gild__no_creddits"):
         with pytest.raises(BadRequest) as excinfo:
             Comment(self.reddit, "d1616q2").gild()
         reason = excinfo.value.response.json()["reason"]
         assert "INSUFFICIENT_CREDDITS" == reason
Exemple #7
0
 def test_gild__no_creddits(self):
     self.reddit.read_only = False
     with self.recorder.use_cassette("TestComment.test_gild__no_creddits"):
         with pytest.raises(RedditAPIException) as excinfo:
             Comment(self.reddit, "d1616q2").gild()
         exception = excinfo.value
         assert "INSUFFICIENT_CREDDITS" == exception.error_type
Exemple #8
0
 def test_delete(self, _):
     self.reddit.read_only = False
     with self.use_cassette():
         comment = Comment(self.reddit, "d1616q2")
         comment.delete()
         assert comment.author is None
         assert comment.body == "[deleted]"
Exemple #9
0
 def test_parent__submission(self):
     comment = Comment(self.reddit, "cklfmye")
     with self.recorder.use_cassette("TestComment.test_parent__submission"):
         parent = comment.parent()
         assert comment in parent.comments
     assert isinstance(parent, Submission)
     assert parent.fullname == comment.parent_id
Exemple #10
0
 def test_delete(self, _):
     self.reddit.read_only = False
     with self.recorder.use_cassette('TestComment.test_delete'):
         comment = Comment(self.reddit, 'd1616q2')
         comment.delete()
         assert comment.author is None
         assert comment.body == '[deleted]'
Exemple #11
0
def delete_removal_comment(subreddit: Subreddit, post_removal):
    logger.warning("2: Deleting removal comment {post_id}".format(post_id=post_removal.removal_comment_id))

    removal_comment = Comment(id=post_removal.removal_comment_id, reddit=subreddit.reddit_api)
    removal_comment.delete()

    post_removal.removal_comment_id = None
    post_removal.save()
Exemple #12
0
 def run(self):
     for cid in self.cids:
         author = Comment(self.reddit, id=cid).author
         try:
             self.authors.append('Null' if author is None or author.created_utc > self.dateline else author.name)
         except:
             self.authors.append('NULL-ERR')
         self.i += 1
Exemple #13
0
 def test_award__self_gild(self):
     self.reddit.read_only = False
     with self.recorder.use_cassette("TestComment.test_award__self_gild"):
         with pytest.raises(RedditAPIException) as excinfo:
             Comment(self.reddit, "g7cn9xb").award(
                 gild_type="award_2385c499-a1fb-44ec-b9b7-d260f3dc55de")
         exception = excinfo.value
         assert "SELF_GILDING_NOT_ALLOWED" == exception.error_type
Exemple #14
0
 def test_award__not_enough_coins(self):
     self.reddit.read_only = False
     with self.use_cassette():
         with pytest.raises(RedditAPIException) as excinfo:
             Comment(self.reddit, "g7cmlgc").award(
                 gild_type="award_2385c499-a1fb-44ec-b9b7-d260f3dc55de")
         exception = excinfo.value
         assert "INSUFFICIENT_COINS_WITH_AMOUNT" == exception.error_type
Exemple #15
0
 def test_parent__comment(self):
     comment = Comment(self.reddit, "cklhv0f")
     with self.recorder.use_cassette("TestComment.test_parent__comment"):
         parent = comment.parent()
         parent.refresh()
         assert comment in parent.replies
     assert isinstance(parent, Comment)
     assert parent.fullname == comment.parent_id
Exemple #16
0
    def test_comment_no_has_url(self):
        comment = Comment(
            reddit,
            url=
            "https://www.reddit.com/r/worldnews/comments/98aj0i/former_un_chief_kofi_annan_dies_at_80/e4en2bt/",
        )

        assert find_urls_in(comment) is None
Exemple #17
0
def replay_remove_pending_tip(reddit, tx_queue, failover_time):
    # check if user have pending tips
    list_tips = user_function.get_unregistered_tip()

    if list_tips:
        for arr_tip in list_tips:
            tip = models.Tip().create_from_array(arr_tip)

            bot_logger.logger.info("replay tipping check for %s" % str(tip.id))

            # check if it's not too old & replay tipping
            if not tip.is_expired():
                if tip.receiver.is_registered():
                    bot_logger.logger.info(
                        "replay tipping %s - %s send %s to %s  " %
                        (str(tip.id), tip.sender.username, tip.amount,
                         tip.receiver.username))

                    tip.tx_id = crypto.tip_user(tip.sender.address,
                                                tip.receiver.address,
                                                tip.amount, tx_queue,
                                                failover_time)
                    if tip.tx_id:
                        tip.finish = True

                        user_function.remove_pending_tip(tip.id)

                        if tip.message_fullname is not None:
                            msg_id = re.sub(r't\d+_(?P<id>\w+)', r'\g<id>',
                                            tip.message_fullname)
                            msg = Comment(reddit, msg_id)
                            msg.reply(
                                Template(lang.message_tip).render(
                                    sender=tip.sender.username,
                                    receiver=tip.receiver.username,
                                    amount=str(tip.amount),
                                    value_usd=str(tip.get_value_usd()),
                                    txid=tip.tx_id))

                else:
                    tip.status = "waiting registration of receiver"
                    bot_logger.logger.info(
                        "replay check for %s - user %s not registered " %
                        (str(tip.id), tip.receiver.username))

            else:
                tip.status = "receiver not registered in time"
                tip.finish = ""
                bot_logger.logger.info(
                    "delete old tipping - %s send %s to %s  " %
                    (tip.sender.username, tip.amount, tip.receiver.username))
                user_function.remove_pending_tip(tip.id)

            # update tip status
            history.update_tip(tip.sender.username, tip)
            history.update_tip(tip.receiver.username, tip)
    else:
        bot_logger.logger.info("no pending tipping")
Exemple #18
0
    def test_construct_failure(self):
        message = "Exactly one of `id`, `url`, or `_data` must be provided."
        with pytest.raises(TypeError) as excinfo:
            Comment(self.reddit)
        assert str(excinfo.value) == message

        with pytest.raises(TypeError) as excinfo:
            Comment(self.reddit, id="dummy", url="dummy")
        assert str(excinfo.value) == message

        with pytest.raises(TypeError) as excinfo:
            Comment(self.reddit, "dummy", _data={"id": "dummy"})
        assert str(excinfo.value) == message

        with pytest.raises(TypeError) as excinfo:
            Comment(self.reddit, url="dummy", _data={"id": "dummy"})
        assert str(excinfo.value) == message

        with pytest.raises(TypeError) as excinfo:
            Comment(self.reddit, "dummy", "dummy", {"id": "dummy"})
        assert str(excinfo.value) == message

        with pytest.raises(ValueError):
            Comment(self.reddit, "")
        with pytest.raises(ValueError):
            Comment(self.reddit, url="")
Exemple #19
0
 def test_reply(self):
     self.reddit.read_only = False
     with self.recorder.use_cassette("TestComment.test_reply"):
         parent_comment = Comment(self.reddit, "d1616q2")
         comment = parent_comment.reply("Comment reply")
         assert comment.author == self.reddit.config.username
         assert comment.body == "Comment reply"
         assert not comment.is_root
         assert comment.parent_id == parent_comment.fullname
Exemple #20
0
    def test_comment_has_url(self):
        comment = Comment(
            reddit,
            url=
            "https://www.reddit.com/r/worldnews/comments/986846/ukraine_demands_15_year_sentence_for_ousted/e4dqaw1/",
        )

        assert find_urls_in(comment) == [
            "https://www.businessinsider.com/paul-manafort-daughter-text-messages-ukraine-2017-3"
        ]
Exemple #21
0
 def test_parent__chain(self):
     comment = Comment(self.reddit, "dkk4qjd")
     counter = 0
     with self.recorder.use_cassette("TestComment.test_parent__chain"):
         comment.refresh()
         parent = comment.parent()
         while parent != comment.submission:
             if counter % 9 == 0:
                 parent.refresh()
             counter += 1
             parent = parent.parent()
Exemple #22
0
 def reply_to_comment(self,
                      comment_id: Text,
                      comment_body: Text,
                      subreddit: Text = None) -> Optional[Comment]:
     if self.live_response:
         return self._reply_to_comment(comment_id,
                                       comment_body,
                                       subreddit=subreddit)
     log.debug('Live response disabled')
     # TODO - 1/12/2021 - Sketchy at best
     return Comment(self.reddit.reddit, id='1111')
Exemple #23
0
    def test_construct_failure(self):
        message = 'Exactly one of `id`, `url`, or `_data` must be provided.'
        with pytest.raises(TypeError) as excinfo:
            Comment(self.reddit)
        assert str(excinfo.value) == message

        with pytest.raises(TypeError) as excinfo:
            Comment(self.reddit, id='dummy', url='dummy')
        assert str(excinfo.value) == message

        with pytest.raises(TypeError) as excinfo:
            Comment(self.reddit, 'dummy', _data={'id': 'dummy'})
        assert str(excinfo.value) == message

        with pytest.raises(TypeError) as excinfo:
            Comment(self.reddit, url='dummy', _data={'id': 'dummy'})
        assert str(excinfo.value) == message

        with pytest.raises(TypeError) as excinfo:
            Comment(self.reddit, 'dummy', 'dummy', {'id': 'dummy'})
        assert str(excinfo.value) == message
Exemple #24
0
    def test_comment_has_urls(self):
        comment = Comment(
            reddit,
            url=
            "https://www.reddit.com/r/worldnews/comments/98aq8n/new_paper_shows_that_ants_are_so_productive/e4ek8my/",
        )

        assert find_urls_in(comment) == [
            "https://www.nytimes.com/2018/08/16/science/ants-worker-idleness.html",
            "http://np.reddit.com/r/autotldr/comments/98aw7d/new_paper_shows_that_ants_are_so_productive/",
            "http://np.reddit.com/r/autotldr/comments/31b9fm/faq_autotldr_bot/",
            "http://np.reddit.com/message/compose?to=%23autotldr",
        ]
Exemple #25
0
 def test_refresh__with_reply_sort_and_limit(self):
     with self.use_cassette():
         comment = Comment(self.reddit, "e4j4830")
         comment.reply_limit = 4
         comment.reply_sort = "new"
         comment.refresh()
         replies = comment.replies
     last_created = float("inf")
     for reply in replies:
         if isinstance(reply, Comment):
             if reply.created_utc > last_created:
                 assert False, "sort order incorrect"
             last_created = reply.created_utc
     assert len(comment.replies) == 3
Exemple #26
0
    def run(self):
        for cid in self.cids:
            author = Comment(self.reddit, id=cid).author
            try:
                if author is None:  # Deleted comment
                    self.authors.append("Null")
                    continue

                if author.created_utc > self.dateline:  # New user
                    self.dq_age.add(author.name)

                self.authors.append(author.name)
            except:  # thread CANNOT crash, typically means suspended user
                self.authors.append('NULL*')
Exemple #27
0
def scan_comments(subreddit):
    """Use Pushshift API to search comments, hardcoded to default to the last
    3 days. See https://redd.it/5gawot for API v2 documentation"""
    _endpoint = 'https://apiv2.pushshift.io/reddit/comment/search/'
    _fields = [
        'author', 'body', 'created_utc', 'id', 'link_author',
        'link_created_utc', 'link_id', 'link_num_comments', 'link_permalink',
        'parent_id', 'url'
    ]
    _args = '?q={0}&subreddit={1}&sort=desc&after=3d&fields={2}'.format(
        baseurl, subreddit, ','.join(_fields))
    url = _endpoint + _args
    req = requests.get(url)
    log.info('[%s] %s', req.status_code, req.headers['content-type'])
    status = req.status_code
    if status == 200:
        # log.debug('content: %s', r.text)
        result = req.json()
        for data in result['data']:
            log.info('Start sorting comment search result.')
            # skip own & replied comment
            if data['author'] == botlogin:
                log.info('Skipping own comment: %s', data['id'])
                continue
            elif data['author'] in botlist:
                log.info('Skipping bot comment: %s', data['author'])
                continue
            elif check_replied(data['id']):
                log.info('Skipping comment %s: replied', data['id'])
                continue
            # skip non-query comment
            elif not contain_url(data['body']):
                log.info('Skipping comment %s: no url found', data['id'])
                continue
            else:
                # get reddit.comment instance
                from praw.models import Comment
                comment = Comment(r, id=data['id'])
                reply(comment)
                log.info('Pausing')
                sleep()
    else:
        log_error = reddb(error_url=url,
                          error_log='status: {0}'.format(status))
        session.add(log_error)
        session.commit()
        log.info('%s. Logged to db', status)
        log.debug('[%s] code: %s, url: %s.', log_error.error_logtime,
                  log_error.error_log, log_error.error_url)
Exemple #28
0
 def test_refresh__with_reply_sort_and_limit(self):
     with self.recorder.use_cassette(
             'TestComment.test_refresh__with_reply_sort_and_limit'):
         comment = Comment(self.reddit, 'e4j4830')
         comment.reply_limit = 4
         comment.reply_sort = 'new'
         comment.refresh()
         replies = comment.replies
     last_created = float('inf')
     for reply in replies:
         if isinstance(reply, Comment):
             if (reply.created_utc > last_created):
                 assert False, 'sort order incorrect'
             last_created = reply.created_utc
     assert len(comment.replies) == 3
Exemple #29
0
def replay_remove_pending_tip(rpc, reddit, tx_queue, failover_time):
    # check if it's not too old & replay tipping
    limit_date = datetime.datetime.now() - datetime.timedelta(days=3)

    # check if user have pending tips
    list_tips = user_function.get_unregistered_tip()

    if list_tips:
        for tip in list_tips:
            bot_logger.logger.info("replay tipping check for %s" %
                                   str(tip['id']))
            if (datetime.datetime.strptime(tip['time'], '%Y-%m-%dT%H:%M:%S.%f')
                    > limit_date):
                if (user_function.user_exist(tip['receiver'])):
                    bot_logger.logger.info(
                        "replay tipping %s - %s send %s to %s  " %
                        (str(tip['id']), tip['sender'], tip['amount'],
                         tip['receiver']))
                    txid = crypto.tip_user(rpc, tip['sender'], tip['receiver'],
                                           tip['amount'], tx_queue,
                                           failover_time)
                    user_function.remove_pending_tip(tip['id'])

                    value_usd = utils.get_coin_value(tip['amount'])

                    if 'message_fullname' in tip.keys():
                        msg_id = re.sub(r't\d+_(?P<id>\w+)', r'\g<id>',
                                        tip['message_fullname'])
                        msg = Comment(reddit, msg_id)
                        msg.reply(
                            Template(lang.message_tip).render(
                                sender=tip['sender'],
                                receiver=tip['receiver'],
                                amount=str(tip['amount']),
                                value_usd=str(value_usd),
                                txid=txid))

                else:
                    bot_logger.logger.info(
                        "replay check for %s - user %s not registered " %
                        (str(tip['id']), tip['receiver']))
            else:
                bot_logger.logger.info(
                    "delete old tipping - %s send %s for %s  " %
                    (tip['sender'], tip['amount'], tip['receiver']))
                user_function.remove_pending_tip(tip['id'])
    else:
        bot_logger.logger.info("no pending tipping")
Exemple #30
0
def downvote_deleter():
    reddit = get_reddit()
    redis_client = get_redis_client()
    logging.info('Monitoring downvotes')
    while True:
        for comment_id in redis_client.smembers('comments'):
            try:
                comment = Comment(reddit, id=comment_id.decode(
                    'utf-8'))  # redis-py bug, not decoding to UTF-8
                if comment.score < 1:
                    comment.delete()
                    redis_client.srem('comments', comment_id)
                    logging.info(f'Removed downvoted comment {comment.id}')
            except praw.exceptions.PRAWException as e:
                logging.exception(e)
        time.sleep(60)