示例#1
0
def send_quote(submission: praw.models.Submission,
               quotes_list: list,
               last_quote: str = ''):
    """Generate a random quote from a list, and comment it on a post.

    Args:
        submission -- post to comment on
        quotes_list -- list of quotes to pick from
        last_quote -- if you provide this, the function will try not to send the last quote again
    Returns:
        The string quote that was sent.
    """
    # try not to send the same quote twice in a row
    if last_quote and len(quotes_list) > 1:
        try:
            quotes_list.remove(last_quote)
        except ValueError:
            pass

    quote = random.choice(quotes_list)
    print(f'Chose quote {quote}')
    submission.reply(quote)
    print('Sent quote')

    return quote
示例#2
0
def removeDoubleDippers(connection: sqlite3.Connection,
                        submission: praw.models.Submission,
                        logger: logging.Logger):
    try:
        reply = submission.reply(DOUBLE_DIPPING_REPLY)
        reply.mod.distinguish(how="yes", sticky=True)

        if (submission.author
                is not None) and (submission.title
                                  is not None) and CREATE_MOD_MAIL:
            subject = "Removed double dipping post (Rule #4)"
            body = f"Automatically removed post \"[{submission.title}]({submission.permalink})\" " \
                   f"by u/{submission.author.name} for rule #4 violation. "
            sql.insertBotMessageIntoDB(connection, subject, body)
            logger.debug(
                f"Inserted mod mail into the db for submission: {submission.title}"
            )
    except Exception as e:
        logger.warning("Unable to send modmail")
        logger.warning("Printing stack trace")
        logger.warning(e)
    finally:
        submission.mod.remove()
        logger.info(
            f"=== Removed post by u/{submission.author}: \"{submission.title}\" for double dipping. "
            f"ID = {submission.id}")
示例#3
0
def homerun(gamechat: praw.models.Submission, play: dict) -> dict:
    """Post a comment to the game thread for a homerun play.

    Args:
        gamechat (Submission): The destination game thread.
        play (dict): The homerun play data.

    Returns:
        dict: The posted comment metadata as a datastore-able dict.
    """
    try:
        pitcher = play['matchup']['pitcher']['fullName']
        batter = play['matchup']['batter']['fullName']
        runs = play['result']['rbi']

        event = play['playEvents'][-1]
        pitch_type = event['details']['type']['description']
        pitch_speed = event['pitchData']['startSpeed']
        speed = event['hitData']['launchSpeed']
        angle = event['hitData']['launchAngle']
        distance = event['hitData']['totalDistance']
    except (KeyError, AttributeError) as err:
        raise DataObjectError(f"{err.__class__.__name__}: {err}")

    body = f"# HR\n\n**{batter}** {random.choice(DONGER_VERBS)} a **{pitch_speed} mph {pitch_type}** from **{pitcher}** for a **{runs}-run** home run.\n\nLaunch Speed: **{speed} mph**. Launch Angle: **{angle}°**. Distance: **{distance} ft**.\n\n{_BYLINE}"
    comment = gamechat.reply(body)

    return _build_obj(comment)
示例#4
0
def due_up(gamechat: praw.models.Submission, due_up: dict) -> dict:
    """Post a comment to the game thread for the players due up.

    Args:
        gamechat (Submission): The destination game thread.
        due_up (dict): The due up players data.

    Returns:
        dict: The posted comment metadata as a datastore-able dict.
    """
    try:
        inning = due_up['inning']
        half = due_up['inningHalf']

        batters_up = []
        for batter in due_up['batters']:
            hand = batter['batSide']
            name = batter['fullName']
            batters_up.append(f"{hand} {name}")
    except KeyError as err:
        raise DataObjectError(f"{err.__class__.__name__}: {err}")

    batters_up_str = '\n\n'.join(batters_up)
    body = f"**Due Up ({half[:3]} {inning})**\n\n{batters_up_str}\n\n{_BYLINE}"
    comment = gamechat.reply(body)

    return _build_obj(comment)
示例#5
0
def isDoubleDipping(submission: praw.models.Submission) -> bool:
    if not submission.is_self:
        duplicates = submission.duplicates()
        for duplicate in duplicates:
            # This is pretty loose criteria. It intentionally does not check for reposts of other users links.
            # It also excludes posts made in SUBREDDIT
            if (duplicate.author == submission.author) and (
                    duplicate.subreddit.id != subreddit.id):
                return True

    return False
示例#6
0
def firstReviewPass(submission: praw.models.Submission,
                    connection: sqlite3.Connection, logger: logging.Logger):
    if submission is None:
        logger.debug("Submission is None. Ignoring.")
        return False

    logger.info(
        f"Working on \"{submission.title}\" by u/{submission.author}. ID = {submission.id}"
    )

    # TODO add shit for voting

    # Give standard reply for posts that aren't questions
    if isAQuestion(submission):
        logger.info(
            f"Gave no reply to \"{submission.title}\" by u/{submission.author}."
        )
        return False

    # Check for double dipping (first pass)
    if isDoubleDipping(submission):
        removeDoubleDippers(connection, submission, logger)
        return False

    # Actions to perform if the post is not double dipping and is not a question
    body = STANDARD_REPLY
    votingEligibility = findVotingEligibility(submission, logger)
    logger.info(
        f"Gave standard reply to \"{submission.title}\" by u/{submission.author}."
    )
    reply = submission.reply(body)
    reply.mod.distinguish(how="yes", sticky=True)
    reply.downvote()

    # Add to db
    sql.insertSubmissionIntoDB(connection, submission, reply, VOTING_OPTIONS,
                               votingEligibility)
    sql.incrementReviewState(connection, submission.id)

    # If the post is voteable then it adds the voting text and the voting table
    if votingEligibility:
        logger.info(
            f"\"{submission.title}\" by u/{submission.author} is voteable. Adding voting text and vote table"
        )
        body = createBodyWithNewVotingTable(connection, submission,
                                            body + VOTING_TEXT)
        reply.edit(body)

    return True
示例#7
0
    def apply(self, submission: praw.models.Submission):
        """Determine if a submission is eligible to be stickied for this Rule."""
        if not self.check(submission):
            return False

        created = datetime.utcfromtimestamp(submission.created_utc)
        if _hours_since(created) > self.max_age_hrs:
            return False

        user_karma = submission.author.comment_karma
        if user_karma < self.min_karma:
            submission.mod.remove()
            try:
                submission.subreddit.message("[StickyBot] User Comment Karma Below Threshold", f"[This submission]({submission.permalink}) is eligible for sticky according to rule '{self.label}' but the user's comment karma is below the rule's threshold of {self.min_karma}. Please approve and manually sticky the submission if it is permissible.")
                comment = submission.reply("Your submission is pending moderator approval due to your comment karma being below the threshold for this type of submission. Message the moderators if you have any questions.")
                comment.mod.distinguish()
            except prawcore.exceptions.InsufficientScope:
                logging.warn("Lacking scope to notify moderators of removed eligible sticky.")
            return False

        return True
示例#8
0
def strikeout(gamechat: praw.models.Submission, play: dict) -> dict:
    """Post a comment to the game thread for a strikeout play.

    Args:
        gamechat (Submission): The destination game thread.
        play (dict): The strikeout play data.

    Returns:
        dict: The posted comment metadata as a datastore-able dict.
    """
    try:
        pitcher = play['matchup']['pitcher']['fullName']
        batter = play['matchup']['batter']['fullName']

        event = play['playEvents'][-1]
        k = 'ꓘ' if event['details']['code'].lower() == 'c' else 'K'
        pitch_type = event['details']['type']['description']
        count_b = event['count']['balls']

        pitch_data = event['pitchData']
        speed = pitch_data['startSpeed']

        breaks = pitch_data.get('breaks', {})
        spin_rate = breaks.get('spinRate')
        break_length = breaks.get('breakLength')

        pitch_details = [e['details'] for e in play['playEvents'] if 'pitchData' in e]
        sequence = ', '.join(f"{d['type']['code']} *({d['code'].strip('*').lower()})*" for d in pitch_details)
    except (KeyError, AttributeError) as err:
        raise DataObjectError(f"{err.__class__.__name__}: {err}")

    if spin_rate and break_length:
        break_details = f"Spin Rate: **{spin_rate} rpm**. Break Length: **{break_length} in**.\n\n"
    else:
        break_details = ''

    body = f"# {k}\n\n**{pitcher}** strikes out **{batter}** on a **{count_b}-2** count with a **{speed} mph** {pitch_type}.\n\n{break_details}*Sequence ({len(pitch_details)}):* {sequence}\n\n{_BYLINE}"
    comment = gamechat.reply(body)

    return _build_obj(comment)
示例#9
0
def boxscore_linedrive(gamechat: praw.models.Submission, evo: dict):
    """Post a comment to the game thread for a low hp hit.

    Args:
        gamechat (Submission): The destination game thread.
        evo (dict): The exit velocity data of the play.

    Returns:
        dict: The posted comment metadata as a datastore-able dict.
    """
    try:
        desc = evo['des']
        speed = evo['hit_speed']
        angle = evo['hit_angle']
        distance = evo['hit_distance']
        xba = evo['xba']
    except KeyError as err:
        raise DataObjectError(f"{err.__class__.__name__}: {err}")

    body = f"*Looks like a line drive in the box score...*\n\n{desc}\n\nLaunch Speed: **{speed} mph**. Launch Angle: **{angle}°**. Distance: **{distance} ft**. Expected Batting Average: ***{xba}***.\n\n{_BYLINE}"
    comment = gamechat.reply(body)

    return _build_obj(comment)
示例#10
0
 def post_submission(self, submission: praw.models.Submission) -> None:
     """
     Crossposts a submission to the post subreddit; sends replies to crosspost to original author
     :param submission: submission to crosspost
     """
     submission.crosspost(subreddit=self.post_subreddit.display_name, send_replies=True)