예제 #1
0
def create_daily_stats(context, session):
    """Create the daily stats entity for today and tomorrow."""
    try:
        today = date.today()
        tomorrow = today + timedelta(days=1)
        for stat_date in [today, tomorrow]:
            statistic = session.query(DailyStatistic).get(stat_date)

            if statistic is None:
                statistic = DailyStatistic(stat_date)
                session.add(statistic)

        session.commit()
    except Exception as e:
        sentry.capture_job_exception(e)
예제 #2
0
def message_update_job(context, session):
    """Update all polls that are scheduled for an update."""
    try:
        context.job.enabled = False
        now = datetime.now()

        update_count = session.query(Update).filter(
            Update.next_update <= now).count()

        while update_count > 0:
            updates = (session.query(Update).filter(
                Update.next_update <= now).options(joinedload(
                    Update.poll)).order_by(
                        Update.next_update.asc()).limit(50).all())

            for update in updates:
                try:
                    send_updates(session,
                                 context.bot,
                                 update.poll,
                                 show_warning=True)
                    session.delete(update)
                    session.commit()
                except ObjectDeletedError:
                    # The update has already been handled somewhere else.
                    # This could be either a job or a person that voted in this very moment
                    session.rollback()
                except RetryAfter as e:
                    # Schedule an update after the RetryAfter timeout + 1 second buffer
                    update.next_update = now + timedelta(
                        seconds=int(e.retry_after) + 1)
                    try:
                        session.commit()
                    except StaleDataError:
                        # The update has already been handled somewhere else
                        session.rollback()

            # Update the count again.
            # Updates can be removed by normal operation as well
            update_count = (session.query(Update).filter(
                Update.next_update <= now).count())

    except Exception as e:
        sentry.capture_job_exception(e)

    finally:
        context.job.enabled = True
예제 #3
0
def delete_polls(context, session):
    """Delete polls from the database and their messages if requested."""
    try:
        context.job.enabled = False

        # Only delete a few polls at a time to prevent RAM usage spikes
        polls_to_delete = (session.query(Poll).filter(
            Poll.delete.isnot(None)).order_by(
                Poll.updated_at.asc()).limit(20).all())
        for poll in polls_to_delete:
            if poll.delete == PollDeletionMode.DB_ONLY.name:
                delete_poll(session, context, poll)
            elif poll.delete == PollDeletionMode.WITH_MESSAGES.name:
                delete_poll(session, context, poll, True)
            session.commit()

    except Exception as e:
        sentry.capture_job_exception(e)

    finally:
        context.job.enabled = True
예제 #4
0
def send_notifications_for_poll(context, session, poll, message_key):
    """Send the notifications for a single poll depending on the remaining time."""
    locale = poll.locale
    for notification in poll.notifications:
        try:
            # Get the chat and send the notification
            tg_chat = context.bot.get_chat(notification.chat_id)
            tg_chat.send_message(
                i18n.t(message_key, locale=locale, name=poll.name),
                parse_mode="markdown",
                reply_to_message_id=notification.poll_message_id,
            )

        except BadRequest as e:
            if e.message == "Chat not found":
                session.delete(notification)

        # Bot was removed from group
        except Unauthorized:
            session.delete(notification)

        except Exception as e:
            sentry.capture_job_exception(e)