class CodeOnlyAnswerPicker(PostPicker):

    def __init__(self):
        super().__init__()
        self.cr = CodeReview()

    @property
    def url(self):
        return URL

    def accept(self, post_id):
        """
        memo: deleted answers are excluded by Stack API
        memo: deleted questions are excluded by Stack API

        :param post_id: id of an answer
        :return: messages to send, or falsy to reject
        """
        logging.info('fetching answer {}'.format(post_id))
        try:
            answer = self.cr.answer(post_id)
        except ValueError as e:
            logging.error('error when fetching answer: '.format(e))
            return None

        if answer.is_accepted:
            logging.info('answer is accepted, skip: {}'.format(answer.id))
            return None

        if answer.score != 0:
            logging.info('answer has score != 0, skip: {}'.format(answer.id))
            return None

        logging.info('fetching question {}'.format(answer.question_id))
        try:
            question = self.cr.question(answer.question_id)
        except ValueError as e:
            logging.error('error when fetching answer: '.format(e))
            return None

        if 'closed_date' in question.json:
            logging.warning('question closed, skip: {}'.format(answer.url))
            return None

        return [INTRO_MESSAGE, answer.url]
Example #2
0
class NarutoPicker(PostPicker):

    def __init__(self):
        super().__init__()
        self.cr = CodeReview()

    @property
    def url(self):
        return URL

    def accept(self, post_id):
        """
        memo: deleted answers are excluded by Stack API
        memo: deleted questions are excluded by Stack API

        :param post_id: id of an answer
        :return: messages to send, or falsy to reject
        """
        logging.info('fetching answer {}'.format(post_id))
        try:
            answer = self.cr.answer(post_id)
        except ValueError as e:
            logging.error('error when fetching answer: '.format(e))
            return None

        if not answer.is_accepted:
            logging.warning('answer not accepted, skip: {}'.format(answer.url))
            return None

        if answer.score != 0:
            logging.warning('score not zero, skip: {}'.format(answer.url))
            return None

        question = self.cr.question(answer.question_id)

        if 'closed_date' in question.json:
            logging.warning('question closed, skip: {}'.format(answer.url))
            return None

        if question.owner_id == answer.owner_id:
            logging.warning('answer owner is the same as question owner, skip: {}'.format(answer.url))
            return None

        return format_post(DESCRIPTION, question.title, answer.url, question.tags)
Example #3
0
class RipeZombiePicker(PostPicker):

    def __init__(self):
        super().__init__()
        self.cr = CodeReview()

    @property
    def url(self):
        return URL

    def accept(self, post_id):
        """
        memo: deleted answers are excluded by Stack API
        memo: deleted questions are excluded by Stack API

        :param post_id: id of a question
        :return: messages to send, or falsy to reject
        """
        logging.info('fetching question {}'.format(post_id))
        try:
            question = self.cr.question(post_id)
        except ValueError as e:
            logging.error('error when fetching question: '.format(e))
            return None

        if 'closed_date' in question.json:
            logging.warning('question closed, skip: {}'.format(question.url))
            return None

        score_0_exists = False

        for answer in question.answers:
            if answer.score > 0:
                logging.warning('answer with postitive score exists, skip: {}'.format(answer.url))
                return None

            if answer.is_accepted:
                logging.warning('accepted answer exists, skip: {}'.format(answer.url))
                return None

            if answer.score == 0:
                score_0_exists = True

        if not score_0_exists:
            logging.warning('no answer with 0 score, skip: {}'.format(question.url))
            return None

        return format_post(DESCRIPTION, question.title, question.url, question.tags)
Example #4
0
 def __init__(self):
     super().__init__()
     self.cr = CodeReview()
class TumbleweedCandidatePicker(PostPicker):

    def __init__(self):
        super().__init__()
        self.cr = CodeReview()

    @property
    def url(self):
        return URL

    def accept(self, post_id):
        """
        memo: deleted questions are excluded by Stack API

        :param post_id: id of a question
        :return: messages to send, or falsy to reject
        """
        logging.info('fetching question {}'.format(post_id))
        try:
            question = self.cr.question(post_id)
        except ValueError as e:
            logging.error('error when fetching question: '.format(e))
            return None

        if 'closed_date' in question.json:
            logging.warning('question closed, skip: {}'.format(question.url))
            return None

        if question.score != 0:
            logging.warning('question has non-zero score, skip: {}'.format(question.url))
            return None

        if question.answers:
            logging.warning('question has answers, skip: {}'.format(question.url))
            return None

        if question.comments.fetch():
            logging.warning('question has comments, skip: {}'.format(question.url))
            return None

        if self.recently_awarded_tumbleweed(question.owner_id, question.creation_date):
            logging.warning('owner has recently received tumbleweed, skip: {}'.format(question.url))
            return None

        return format_post(DESCRIPTION, question.title, question.url, question.tags)

    def recently_awarded_tumbleweed(self, user_id, date):
        badge_id = self.cr.badge(name='Tumbleweed').id
        fromdate = int(date.timestamp())
        url = 'https://api.stackexchange.com/2.2/badges/{}/recipients'.format(badge_id)
        data = {
            'fromdate': fromdate,
            'site': 'codereview',
        }
        response = requests.get(url, data)
        if not response.ok:
            return self.has_tumbleweed(user_id)

        items = json.loads(response.content.decode())['items']
        return user_id in [item['user']['user_id'] for item in items]

    def has_tumbleweed(self, owner_id):
        user = self.cr.user(owner_id)
        return any([badge.name == 'Tumbleweed' for badge in user.badges.fetch()])