示例#1
0
    def _find_and_respond_to_twitter_events(self) -> None:
        """Looks for TwitterEvent objects that have not yet been responded to and
        begins the process of creating a response. Additionally, failed events are
        rerun to provide a correct response, particularly useful in cases where
        external apis are down for maintenance.
        """

        interval = (
            self.PRODUCTION_APP_RATE_LIMITING_INTERVAL_IN_SECONDS if self._is_production()
            else self.DEVELOPMENT_CLIENT_RATE_LIMITING_INTERVAL_IN_SECONDS)

        self._events_iteration += 1
        LOG.debug(
            f'Looking up twitter events on iteration {self._events_iteration}')

        # set up timer
        twitter_events_thread = threading.Timer(
            interval, self._find_and_respond_to_twitter_events)
        self._lookup_threads.append(twitter_events_thread)

        # start timer
        twitter_events_thread.start()

        try:
            new_events: list[TwitterEvent] = TwitterEvent.get_all_by(
                is_duplicate=False,
                responded_to=False,
                response_in_progress=False)

            LOG.debug(f'new events: {new_events}')

            failed_events: list[TwitterEvent] = TwitterEvent.get_all_by(
                is_duplicate=False,
                error_on_lookup=True,
                responded_to=True,
                response_in_progress=False)

            failed_events_that_need_response: list[TwitterEvent] = self._filter_failed_twitter_events(failed_events)

            events_to_respond_to: [list[TwitterEvent]] = new_events + failed_events_that_need_response

            LOG.debug(f'events to respond to: {events_to_respond_to}')

            for event in events_to_respond_to:
                self._process_twitter_event(event=event)

        except Exception as e:

            LOG.error(e)
            LOG.error(str(e))
            LOG.error(e.args)
            logging.exception("stack trace")

        finally:
            TwitterEvent.query.session.close()
示例#2
0
    def _find_and_respond_to_twitter_events(self):
        """Looks for TwitterEvent objects that have not yet been responded to and
        begins the process of creating a response. Additionally, failed events are
        rerun to provide a correct response, particularly useful in cases where
        external apis are down for maintenance.
        """

        interval = 3.0 if self._is_production() else self.DEVELOPMENT_TIME_INTERVAL

        self.events_iteration += 1
        LOG.debug(
            f'Looking up twitter events on iteration {self.events_iteration}')

        # start timer
        threading.Timer(
            interval, self._find_and_respond_to_twitter_events).start()

        try:
            new_events: [List[TwitterEvent]] = TwitterEvent.get_all_by(
                is_duplicate=False,
                responded_to=False,
                response_in_progress=False)

            LOG.debug(f'new events: {new_events}')

            failed_events: [List[TwitterEvent]] = TwitterEvent.get_all_by(
                is_duplicate=False,
                error_on_lookup=True,
                responded_to=True,
                response_in_progress=False)

            LOG.debug(f'failed events: {failed_events}')

            events_to_respond_to: [List[TwitterEvent]] = new_events + failed_events

            LOG.debug(f'events to respond to: {events_to_respond_to}')

            for event in events_to_respond_to:

                LOG.debug(f'Beginning response for event: {event.id}')

                # search for duplicates
                is_event_duplicate: bool = TwitterEvent.query.filter_by(
                    event_type=event.event_type,
                    event_id=event.event_id,
                    user_handle=event.user_handle,
                    responded_to=True
                ).filter(
                    TwitterEvent.id != event.id).count() > 0

                if is_event_duplicate:
                    event.is_duplicate = True

                    TwitterEvent.query.session.commit()

                    LOG.info(f'Event {event.id} is a duplicate, skipping.')

                else:

                    event.response_in_progress = True
                    TwitterEvent.query.session.commit()

                    try:
                        message_source = LookupSource(event.event_type)

                        # build request
                        lookup_request: Type[BaseLookupRequest] = self.reply_argument_builder.build_reply_data(
                            message=event,
                            message_source=message_source)

                        # Reply to the event.
                        reply_event = self.aggregator.initiate_reply(
                            lookup_request=lookup_request)
                        success = reply_event.get('success', False)

                        if success:
                            # Need username for statuses
                            reply_event['username'] = event.user_handle

                            # There's need to tell people that there was an error more than once
                            if not (reply_event.get(
                                    'error_on_lookup') and event.error_on_lookup):

                                try:
                                    self._process_response(reply_event)
                                except tweepy.error.TweepError as e:
                                    reply_event['error_on_lookup'] = True

                            # We've responded!
                            event.response_in_progress = False
                            event.responded_to = True

                            # Update error status
                            if reply_event.get('error_on_lookup'):
                                event.error_on_lookup = True
                            else:
                                event.error_on_lookup = False

                        TwitterEvent.query.session.commit()

                    except ValueError as e:
                        LOG.error(
                            f'Encountered unknown event type. '
                            f'Response is not possible.')

        except Exception as e:

            LOG.error(e)
            LOG.error(str(e))
            LOG.error(e.args)
            logging.exception("stack trace")

        finally:
            TwitterEvent.query.session.close()