示例#1
0
    def perform(self, *args, **kwargs):
        all_vehicles: bool = kwargs.get('all_vehicles') or False
        is_dry_run: bool = kwargs.get('is_dry_run') or False

        if all_vehicles:
            plate_lookups = PlateLookup.get_all_by(
                count_towards_frequency=True)
        else:
            plate_lookups = PlateLookup.get_all_by(
                boot_eligible=True,
                count_towards_frequency=True)

        threads = []
        num_threads = 100
        chunk_length = math.ceil(len(plate_lookups)/num_threads)

        for n in range(0, num_threads):
            chunk_begin = n * chunk_length
            chunk_plate_lookups = plate_lookups[chunk_begin:(chunk_begin + chunk_length)]
            print(f'this thread will handle lookups: {[l.id for l in chunk_plate_lookups]}')
            threads.append(threading.Thread(target=self.update_lookups, args=(chunk_plate_lookups,)))

        for thread in threads:
            thread.start()

        for thread in threads:
            thread.join()

        if not is_dry_run:
            PlateLookup.query.session.commit()
 def _query_for_lookup_frequency(self, plate_query: PlateQuery) -> int:
     """How many times has this plate been queried before?"""
     return len(
         PlateLookup.get_all_by(plate=plate_query.plate,
                                plate_types=plate_query.plate_types,
                                state=plate_query.state,
                                count_towards_frequency=True))
示例#3
0
    def _query_for_previous_lookup(
            self, plate_query: PlateQuery) -> Optional[PlateLookup]:
        """ See if we've seen this vehicle before. """

        lookups_for_vehicle: List[PlateLookup] = PlateLookup.get_all_by(
            plate=plate_query.plate,
            state=plate_query.state,
            plate_types=plate_query.plate_types,
            count_towards_frequency=True)

        if lookups_for_vehicle:
            lookups_for_vehicle.sort(key=lambda x: x.created_at, reverse=True)

            return lookups_for_vehicle[0]

        else:
            return None
示例#4
0
    def _perform_plate_lookup(
            self, campaigns: List[Campaign], plate_query: PlateQuery,
            unique_identifier: str) -> OpenDataServiceResponse:

        LOG.debug('Performing lookup for plate.')

        nyc_open_data_service: OpenDataService = OpenDataService()
        open_data_response: OpenDataServiceResponse = nyc_open_data_service.look_up_vehicle(
            plate_query=plate_query)

        LOG.debug(f'Violation data: {open_data_response}')

        if open_data_response.success:

            open_data_plate_lookup: OpenDataServicePlateLookup = open_data_response.data

            bus_lane_camera_violations = 0
            red_light_camera_violations = 0
            speed_camera_violations = 0

            for violation_type_summary in open_data_plate_lookup.violations:
                if violation_type_summary['title'] in self.CAMERA_VIOLATIONS:
                    violation_count = violation_type_summary['count']

                    if violation_type_summary['title'] == 'Bus Lane Violation':
                        bus_lane_camera_violations = violation_count
                    if violation_type_summary[
                            'title'] == 'Failure To Stop At Red Light':
                        red_light_camera_violations = violation_count
                    elif violation_type_summary[
                            'title'] == 'School Zone Speed Camera Violation':
                        speed_camera_violations = violation_count

            camera_streak_data: CameraStreakData = open_data_plate_lookup.camera_streak_data

            # If this came from message, add it to the plate_lookups table.
            if plate_query.message_source and plate_query.message_id and plate_query.created_at:
                new_lookup = PlateLookup(
                    boot_eligible=camera_streak_data.max_streak >= 5
                    if camera_streak_data else False,
                    bus_lane_camera_violations=bus_lane_camera_violations,
                    created_at=plate_query.created_at,
                    message_id=plate_query.message_id,
                    message_source=plate_query.message_source,
                    num_tickets=open_data_plate_lookup.num_violations,
                    plate=plate_query.plate,
                    plate_types=plate_query.plate_types,
                    red_light_camera_violations=red_light_camera_violations,
                    speed_camera_violations=speed_camera_violations,
                    state=plate_query.state,
                    unique_identifier=unique_identifier,
                    username=plate_query.username)

                # Iterate through included campaigns to tie lookup to each
                for campaign in campaigns:
                    # insert join record for campaign lookup
                    new_lookup.campaigns.append(campaign)

                # Insert plate lookup
                PlateLookup.query.session.add(new_lookup)
                PlateLookup.query.session.commit()

        else:
            LOG.info(f'open data plate lookup failed')

        return open_data_response
示例#5
0
 def _query_for_lookup_frequency(self, plate_query: PlateQuery) -> int:
     return len(
         PlateLookup.get_all_by(plate=plate_query.plate,
                                plate_types=plate_query.plate_types,
                                state=plate_query.state,
                                count_towards_frequency=True))
    def perform(self, *args, **kwargs):
        is_dry_run: bool = kwargs.get('is_dry_run') or False
        use_dvaa_thresholds: bool = kwargs.get('use_dvaa_thresholds') or False
        use_only_visible_tweets: bool = kwargs.get('use_only_visible_tweets') or False

        tweet_detection_service = TweetDetectionService()
        tweeter = TrafficViolationsTweeter()

        eastern = pytz.timezone('US/Eastern')
        utc = pytz.timezone('UTC')

        now = datetime.now()

        # If today is leap day, there were no lookups a year ago today
        if (now.day == self.LEAP_DAY_DATE and
            now.month == self.LEAP_DAY_MONTH):
            return

        # If today is March 1, and last year was a leap year, show lookups
        # from the previous February 29.
        one_year_after_leap_day = True if (
            now.day == self.POST_LEAP_DAY_DATE and
            now.month == self.POST_LEAP_DAY_MONTH and
            self._is_leap_year(now.year - 1)) else False

        top_of_the_hour_last_year = now.replace(
            microsecond=0,
            minute=0,
            second=0) - relativedelta(years=1)

        top_of_the_next_hour_last_year = (
            top_of_the_hour_last_year + relativedelta(hours=1))

        if use_dvaa_thresholds:
            threshold_attribute: str = 'boot_eligible_under_dvaa_threshold'
        else:
            threshold_attribute: str = 'boot_eligible_under_rdaa_threshold'

        base_query: list[Tuple[int]] = PlateLookup.query.session.query(
            func.max(PlateLookup.id).label('most_recent_vehicle_lookup')
        ).filter(
            or_(
                  and_(PlateLookup.created_at >= top_of_the_hour_last_year,
                       PlateLookup.created_at < top_of_the_next_hour_last_year,
                       getattr(PlateLookup, threshold_attribute) == True,
                       PlateLookup.count_towards_frequency == True),
                  and_(one_year_after_leap_day,
                       PlateLookup.created_at >= (top_of_the_hour_last_year - relativedelta(days=1)),
                       PlateLookup.created_at < (top_of_the_next_hour_last_year - relativedelta(days=1)),
                       getattr(PlateLookup, threshold_attribute) == True,
                       PlateLookup.count_towards_frequency == True)
                )
        )

        if use_only_visible_tweets:
            base_query = base_query.filter(
                PlateLookup.message_source == lookup_sources.LookupSource.STATUS.value)

        recent_plate_lookup_ids = base_query.group_by(
            PlateLookup.plate,
            PlateLookup.state
        ).all()

        lookup_ids_to_update: list[int] = [id[0] for id in recent_plate_lookup_ids]

        lookups_to_update: list[PlateLookup] = PlateLookup.get_all_in(
            id=lookup_ids_to_update)

        if not lookups_to_update:
            LOG.debug(f'No vehicles for which to perform retrospective job '
                      f'between {top_of_the_hour_last_year} and '
                      f'and {top_of_the_next_hour_last_year}.')

        for previous_lookup in lookups_to_update:

            LOG.debug(f'Performing retrospective job for '
                      f'{L10N.VEHICLE_HASHTAG.format(previous_lookup.state, previous_lookup.plate)} ')

            plate_query: PlateQuery = PlateQuery(created_at=now,
                                                 message_source=previous_lookup.message_source,
                                                 plate=previous_lookup.plate,
                                                 plate_types=previous_lookup.plate_types,
                                                 state=previous_lookup.state)

            nyc_open_data_service: OpenDataService = OpenDataService()
            data_before_query: OpenDataServiceResponse = nyc_open_data_service.look_up_vehicle(
                plate_query=plate_query,
                until=previous_lookup.created_at)

            lookup_before_query: OpenDataServicePlateLookup = data_before_query.data
            camera_streak_data_before_query: CameraStreakData = lookup_before_query.camera_streak_data['Mixed']

            data_after_query: OpenDataServiceResponse = nyc_open_data_service.look_up_vehicle(
                plate_query=plate_query,
                since=previous_lookup.created_at,
                until=previous_lookup.created_at + relativedelta(years=1))


            lookup_after_query: OpenDataServicePlateLookup = data_after_query.data

            new_bus_lane_camera_violations: Optional[int] = None
            new_speed_camera_violations: Optional[int] = None
            new_red_light_camera_violations: Optional[int] = None

            for violation_type_summary in lookup_after_query.violations:
                if violation_type_summary['title'] in self.CAMERA_VIOLATIONS:
                    violation_count = violation_type_summary['count']

                    if violation_type_summary['title'] == 'Bus Lane Violation':
                        new_bus_lane_camera_violations = violation_count
                    if violation_type_summary['title'] == 'Failure To Stop At Red Light':
                        new_red_light_camera_violations = violation_count
                    if violation_type_summary['title'] == 'School Zone Speed Camera Violation':
                        new_speed_camera_violations = violation_count

            if new_bus_lane_camera_violations is None:
                new_bus_lane_camera_violations = 0

            if new_red_light_camera_violations is None:
                new_red_light_camera_violations = 0

            if new_speed_camera_violations is None:
                new_speed_camera_violations = 0

            new_boot_eligible_violations = (new_red_light_camera_violations +
                                            new_speed_camera_violations)

            if new_boot_eligible_violations > 0:
                vehicle_hashtag = L10N.VEHICLE_HASHTAG.format(
                    previous_lookup.state, previous_lookup.plate)
                previous_lookup_created_at = utc.localize(
                    previous_lookup.created_at)
                previous_lookup_date = previous_lookup_created_at.astimezone(eastern).strftime(
                    L10N.REPEAT_LOOKUP_DATE_FORMAT)
                previous_lookup_time = previous_lookup_created_at.astimezone(eastern).strftime(
                    L10N.REPEAT_LOOKUP_TIME_FORMAT)

                red_light_camera_violations_string = (
                    f'{new_red_light_camera_violations} | Red Light Camera Violations\n'
                    if new_red_light_camera_violations > 0 else '')

                speed_camera_violations_string = (
                    f'{new_speed_camera_violations} | Speed Safety Camera Violations\n'
                    if new_speed_camera_violations > 0 else '')

                reckless_driver_summary_string = (
                    f'{vehicle_hashtag} was originally '
                    f'queried on {previous_lookup_date} '
                    f'at {previous_lookup_time}')

                # assume we can't link
                can_link_tweet = False

                # Where did this come from?
                if previous_lookup.message_source == lookup_sources.LookupSource.STATUS.value:
                    # Determine if tweet is still visible:
                    if tweet_detection_service.tweet_exists(id=previous_lookup.message_id,
                                                            username=previous_lookup.username):
                        can_link_tweet = True

                if can_link_tweet:
                    reckless_driver_summary_string += L10N.PREVIOUS_LOOKUP_STATUS_STRING.format(
                        previous_lookup.username,
                        previous_lookup.username,
                        previous_lookup.message_id)
                else:
                    reckless_driver_summary_string += '.'

                if use_only_visible_tweets and not can_link_tweet:
                    # If we're only displaying tweets we can quote tweet,
                    # skip this one since we can'tt.
                    continue

                reckless_driver_update_string = (
                    f'From {camera_streak_data_before_query.min_streak_date} to '
                    f'{camera_streak_data_before_query.max_streak_date}, this vehicle '
                    f'received {camera_streak_data_before_query.max_streak} camera '
                    f'violations. Over the past 12 months, this vehicle '
                    f'received {new_boot_eligible_violations} new camera violation'
                    f"{'' if new_boot_eligible_violations == 1 else 's'}: \n\n"
                    f'{red_light_camera_violations_string}'
                    f'{speed_camera_violations_string}')

                messages: list[str] = [
                    reckless_driver_summary_string,
                    reckless_driver_update_string]

                if not is_dry_run:
                    success: bool = tweeter.send_status(
                        message_parts=messages,
                        on_error_message=(
                            f'Error printing reckless driver update. '
                            f'Tagging @bdhowald.'))

                    if success:
                        LOG.debug('Reckless driver retrospective job '
                                  'ran successfully.')
                else:
                    print(reckless_driver_update_string)
    def _perform_plate_lookup(
            self, campaigns: list[Campaign], plate_query: PlateQuery,
            unique_identifier: str) -> OpenDataServiceResponse:

        LOG.debug('Performing lookup for plate.')

        nyc_open_data_service: OpenDataService = OpenDataService()
        open_data_response: OpenDataServiceResponse = nyc_open_data_service.look_up_vehicle(
            plate_query=plate_query)

        LOG.debug(f'Violation data: {open_data_response}')

        if open_data_response.success:

            open_data_plate_lookup: OpenDataServicePlateLookup = open_data_response.data

            bus_lane_camera_violations = 0
            red_light_camera_violations = 0
            speed_camera_violations = 0

            for violation_type_summary in open_data_plate_lookup.violations:
                if violation_type_summary['title'] in self.CAMERA_VIOLATIONS:
                    violation_count = violation_type_summary['count']

                    if violation_type_summary['title'] == 'Bus Lane Violation':
                        bus_lane_camera_violations = violation_count
                    if violation_type_summary[
                            'title'] == 'Failure To Stop At Red Light':
                        red_light_camera_violations = violation_count
                    elif violation_type_summary[
                            'title'] == 'School Zone Speed Camera Violation':
                        speed_camera_violations = violation_count

            camera_streak_data: CameraStreakData = open_data_plate_lookup.camera_streak_data

            # If this came from message, add it to the plate_lookups table.
            if plate_query.message_source and plate_query.message_id and plate_query.created_at:
                new_lookup = PlateLookup(
                    boot_eligible_under_dvaa_threshold=
                    (camera_streak_data['Failure to Stop at Red Light'].
                     max_streak >= thresholds.
                     DANGEROUS_VEHICLE_ABATEMENT_ACT_RED_LIGHT_CAMERA_THRESHOLD
                     if camera_streak_data['Failure to Stop at Red Light'] else
                     False or
                     camera_streak_data['School Zone Speed Camera Violation'].
                     max_streak >= thresholds.
                     DANGEROUS_VEHICLE_ABATEMENT_ACT_SCHOOL_ZONE_SPEED_CAMERA_THRESHOLD
                     if
                     camera_streak_data['School Zone Speed Camera Violation']
                     else False),
                    boot_eligible_under_rdaa_threshold=(
                        camera_streak_data['Mixed'].max_streak >=
                        thresholds.RECKLESS_DRIVER_ACCOUNTABILITY_ACT_THRESHOLD
                        if camera_streak_data['Mixed'] else False),
                    bus_lane_camera_violations=bus_lane_camera_violations,
                    created_at=plate_query.created_at,
                    message_id=plate_query.message_id,
                    message_source=plate_query.message_source,
                    num_tickets=open_data_plate_lookup.num_violations,
                    plate=plate_query.plate,
                    plate_types=plate_query.plate_types,
                    red_light_camera_violations=red_light_camera_violations,
                    responded_to=True,
                    speed_camera_violations=speed_camera_violations,
                    state=plate_query.state,
                    unique_identifier=unique_identifier,
                    username=plate_query.username)

                # Iterate through included campaigns to tie lookup to each
                for campaign in campaigns:
                    # insert join record for campaign lookup
                    new_lookup.campaigns.append(campaign)

                # Insert plate lookup
                PlateLookup.query.session.add(new_lookup)
                PlateLookup.query.session.commit()

        else:
            LOG.info('open data plate lookup failed')

        return open_data_response
    def test_print_reckless_driver_retrospective(
            self,
            mocked_tweet_detection_service_tweet_exists,
            mocked_traffic_violations_tweeter,
            mocked_plate_lookup_get_all_in,
            mocked_open_data_service_look_up_vehicle,
            can_link_tweet=True,
            dry_run=False,
            new_camera_violations_string='10 new camera violations',
            red_light_camera_tickets_after_previous_lookup=3,
            red_light_camera_tickets_before_previous_lookup=5,
            speed_camera_tickets_after_previous_lookup=7,
            speed_camera_tickets_before_previous_lookup=15,
            use_dvaa_thresholds: bool = False,
            use_only_visible_tweets: bool = False):

        job = RecklessDriverRetrospectiveJob()

        mocked_tweet_detection_service_tweet_exists.return_value = can_link_tweet

        plate = 'ABCDEFG'
        plate_types = 'COM,PAS'
        state = 'NY'

        now = datetime.now()
        previous_message_id = random.randint(1000000000000000000,
                                             2000000000000000000)
        previous_message_source = 'status'
        previous_num_tickets = 123
        previous_username = '******'

        rdaa_max_streak = (red_light_camera_tickets_before_previous_lookup +
                           speed_camera_tickets_before_previous_lookup)
        rdaa_min_streak_date = datetime(2018, 11, 26, 0, 0,
                                        0).strftime('%B %-d, %Y')
        rdaa_max_streak_date = datetime(2019, 11, 22, 0, 0,
                                        0).strftime('%B %-d, %Y')

        dvaa_red_light_camera_max_streak = red_light_camera_tickets_before_previous_lookup
        dvaa_red_light_camera_min_streak_date = datetime(
            2018, 9, 14, 0, 0, 0).strftime('%B %-d, %Y')
        dvaa_red_light_camera_max_streak_date = datetime(
            2019, 12, 17, 0, 0, 0).strftime('%B %-d, %Y')

        dvaa_speed_camera_max_streak = speed_camera_tickets_before_previous_lookup
        dvaa_speed_camera_min_streak_date = datetime(2018, 11, 26, 0, 0,
                                                     0).strftime('%B %-d, %Y')
        dvaa_speed_camera_max_streak_date = datetime(2019, 11, 22, 0, 0,
                                                     0).strftime('%B %-d, %Y')

        plate_lookup_to_return = PlateLookup(
            bus_lane_camera_violations=2,
            created_at=datetime(2020, 1, 3, 14, 37, 12),
            message_id=previous_message_id,
            message_source=previous_message_source,
            num_tickets=previous_num_tickets,
            plate=plate,
            plate_types=plate_types,
            red_light_camera_violations=
            red_light_camera_tickets_before_previous_lookup,
            speed_camera_violations=speed_camera_tickets_before_previous_lookup,
            state=state,
            username=previous_username)

        below_dvaa_thresholds = (dvaa_red_light_camera_max_streak < 5
                                 and dvaa_speed_camera_max_streak < 15)

        new_camera_violations_exist = (
            red_light_camera_tickets_after_previous_lookup +
            speed_camera_tickets_after_previous_lookup) > 0

        if use_dvaa_thresholds and below_dvaa_thresholds:
            # We don't expect a lookup here.
            expect_response = False
            plate_lookups = []

        elif use_only_visible_tweets and not can_link_tweet:
            # We don't expect a lookup here.
            expect_response = False
            plate_lookups = [plate_lookup_to_return]

        elif not new_camera_violations_exist:
            # We don't expect a lookup here.
            expect_response = False
            plate_lookups = [plate_lookup_to_return]

        elif dry_run:
            # We don't expect a lookup here.
            expect_response = False
            plate_lookups = [plate_lookup_to_return]

        else:
            expect_response = True
            plate_lookups = [plate_lookup_to_return]

        mocked_plate_lookup_get_all_in.return_value = plate_lookups

        open_data_plate_lookup_before_previous_lookup = OpenDataServicePlateLookup(
            boroughs=[],
            camera_streak_data={
                'Failure to Stop at Red Light':
                CameraStreakData(
                    min_streak_date=dvaa_red_light_camera_min_streak_date,
                    max_streak=dvaa_red_light_camera_max_streak,
                    max_streak_date=dvaa_red_light_camera_max_streak_date),
                'Mixed':
                CameraStreakData(min_streak_date=rdaa_min_streak_date,
                                 max_streak=rdaa_max_streak,
                                 max_streak_date=rdaa_max_streak_date),
                'School Zone Speed Camera Violation':
                CameraStreakData(
                    min_streak_date=dvaa_speed_camera_min_streak_date,
                    max_streak=dvaa_speed_camera_max_streak,
                    max_streak_date=dvaa_speed_camera_max_streak_date),
            },
            fines=FineData(),
            num_violations=150,
            plate=plate,
            plate_types=plate_types,
            state=state,
            violations=[{
                'count': red_light_camera_tickets_before_previous_lookup,
                'title': 'Failure To Stop At Red Light'
            }, {
                'count': speed_camera_tickets_before_previous_lookup,
                'title': 'School Zone Speed Camera Violation'
            }],
            years=[])

        open_data_response_before_previous_lookup = OpenDataServiceResponse(
            data=open_data_plate_lookup_before_previous_lookup, success=True)

        open_data_plate_lookup_after_previous_lookup = OpenDataServicePlateLookup(
            boroughs=[],
            camera_streak_data={
                'Failure to Stop at Red Light':
                CameraStreakData(
                    min_streak_date=dvaa_red_light_camera_min_streak_date,
                    max_streak=dvaa_red_light_camera_max_streak,
                    max_streak_date=dvaa_red_light_camera_max_streak_date),
                'Mixed':
                CameraStreakData(min_streak_date=rdaa_min_streak_date,
                                 max_streak=rdaa_max_streak,
                                 max_streak_date=rdaa_max_streak_date),
                'School Zone Speed Camera Violation':
                CameraStreakData(
                    min_streak_date=dvaa_speed_camera_min_streak_date,
                    max_streak=dvaa_speed_camera_max_streak,
                    max_streak_date=dvaa_speed_camera_max_streak_date),
            },
            fines=FineData(),
            num_violations=150,
            plate=plate,
            plate_types=plate_types,
            state=state,
            violations=[{
                'count': red_light_camera_tickets_after_previous_lookup,
                'title': 'Failure To Stop At Red Light'
            }, {
                'count': speed_camera_tickets_after_previous_lookup,
                'title': 'School Zone Speed Camera Violation'
            }],
            years=[])

        open_data_response_after_previous_lookup = OpenDataServiceResponse(
            data=open_data_plate_lookup_after_previous_lookup, success=True)

        mocked_open_data_service_look_up_vehicle.side_effect = [
            open_data_response_before_previous_lookup,
            open_data_response_after_previous_lookup
        ]

        can_link_tweet_string = (
            f' by @BarackObama: '
            f'https://twitter.com/BarackObama/status/{previous_message_id}'
            if can_link_tweet else '')
        red_light_camera_tickets_diff_string = (
            f'{red_light_camera_tickets_after_previous_lookup} | Red Light Camera Violations\n'
            if red_light_camera_tickets_after_previous_lookup else '')

        speed_camera_tickets_diff_string = (
            f'{speed_camera_tickets_after_previous_lookup} | Speed Safety Camera Violations\n'
            if speed_camera_tickets_after_previous_lookup else '')

        summary_string = (
            f'#NY_ABCDEFG was originally queried on January 3, 2020 at 09:37AM'
            f'{can_link_tweet_string}.')

        update_string = (
            f'From November 26, 2018 to November 22, 2019, this vehicle '
            f'received 20 camera violations. Over the past 12 months, this '
            f'vehicle received {new_camera_violations_string}: \n\n'
            f'{red_light_camera_tickets_diff_string}'
            f'{speed_camera_tickets_diff_string}')

        job.run(is_dry_run=dry_run,
                use_only_visible_tweets=use_only_visible_tweets)

        if expect_response:
            mocked_traffic_violations_tweeter().send_status.assert_called_with(
                message_parts=[summary_string, update_string],
                on_error_message=(f'Error printing reckless driver update. '
                                  f'Tagging @bdhowald.'))
        else:
            mocked_traffic_violations_tweeter().send_status.assert_not_called()
    def test_print_reckless_driver_retrospective(self,
                                 mocked_tweet_detection_service_tweet_exists,
                                 mocked_traffic_violations_tweeter,
                                 mocked_plate_lookup_get_all_in,
                                 mocked_plate_lookup_query,
                                 mocked_open_data_service_look_up_vehicle,
                                 can_link_tweet=False,
                                 dry_run=False,
                                 new_camera_violations_string='10 new camera violations',
                                 red_light_camera_tickets_after_previous_lookup=3,
                                 speed_camera_tickets_after_previous_lookup=7,
                                 red_light_camera_tickets_before_previous_lookup=8,
                                 speed_camera_tickets_before_previous_lookup=12):

        job = RecklessDriverRetrospectiveJob()

        # mocked_plate_lookup_query.session.query(
        # ).filter().group_by().all.return_value = [1,2,3]

        mocked_tweet_detection_service_tweet_exists.return_value = can_link_tweet

        plate = 'ABCDEFG'
        plate_types = 'COM,PAS'
        state = 'NY'

        now = datetime.now()
        previous_message_id = random.randint(1000000000000000000, 2000000000000000000)
        previous_message_source = 'status'
        previous_num_tickets = 123
        previous_username = '******'

        max_streak = 20
        min_streak_date = datetime(2018, 11, 26, 0, 0, 0).strftime('%B %-d, %Y')
        max_streak_date = datetime(2019, 11, 22, 0, 0, 0).strftime('%B %-d, %Y')

        plate_lookups = [
            PlateLookup(
                bus_lane_camera_violations=2,
                created_at=datetime(2020, 1, 3, 14, 37, 12),
                message_id=previous_message_id,
                message_source=previous_message_source,
                num_tickets=previous_num_tickets,
                plate=plate,
                plate_types=plate_types,
                red_light_camera_violations=red_light_camera_tickets_before_previous_lookup,
                speed_camera_violations=speed_camera_tickets_before_previous_lookup,
                state=state,
                username=previous_username)]

        mocked_plate_lookup_get_all_in.return_value = plate_lookups

        open_data_plate_lookup_before_previous_lookup = OpenDataServicePlateLookup(
            boroughs=[],
            camera_streak_data=CameraStreakData(
                min_streak_date=min_streak_date,
                max_streak=max_streak,
                max_streak_date=max_streak_date),
            fines=FineData(),
            num_violations=150,
            plate=plate,
            plate_types=plate_types,
            state=state,
            violations=[
                {'count': red_light_camera_tickets_before_previous_lookup,
                 'title': 'Failure To Stop At Red Light'},
                {'count': speed_camera_tickets_before_previous_lookup, 'title':
                 'School Zone Speed Camera Violation'}],
            years=[])

        open_data_response_before_previous_lookup = OpenDataServiceResponse(
            data=open_data_plate_lookup_before_previous_lookup,
            success=True)


        open_data_plate_lookup_after_previous_lookup = OpenDataServicePlateLookup(
            boroughs=[],
            camera_streak_data=CameraStreakData(
                min_streak_date=min_streak_date,
                max_streak=max_streak,
                max_streak_date=max_streak_date),
            fines=FineData(),
            num_violations=150,
            plate=plate,
            plate_types=plate_types,
            state=state,
            violations=[
                {'count': red_light_camera_tickets_after_previous_lookup,
                 'title': 'Failure To Stop At Red Light'},
                {'count': speed_camera_tickets_after_previous_lookup, 'title':
                 'School Zone Speed Camera Violation'}],
            years=[])

        open_data_response_after_previous_lookup = OpenDataServiceResponse(
            data=open_data_plate_lookup_after_previous_lookup,
            success=True)

        mocked_open_data_service_look_up_vehicle.side_effect = [
            open_data_response_before_previous_lookup, open_data_response_after_previous_lookup]

        can_link_tweet_string = (
          f' by @BarackObama: '
          f'https://twitter.com/BarackObama/status/{previous_message_id}'
          if can_link_tweet else '')
        red_light_camera_tickets_diff_string = (
            f'{red_light_camera_tickets_after_previous_lookup} | Red Light Camera Violations\n'
            if red_light_camera_tickets_after_previous_lookup else '')

        speed_camera_tickets_diff_string = (
            f'{speed_camera_tickets_after_previous_lookup} | Speed Safety Camera Violations\n'
            if speed_camera_tickets_after_previous_lookup else '')

        summary_string = (
            f'#NY_ABCDEFG was originally queried on January 3, 2020 at 09:37AM'
            f'{can_link_tweet_string}.')

        update_string = (
            f'From November 26, 2018 to November 22, 2019, this vehicle '
            f'received 20 camera violations. Over the past 12 months, this '
            f'vehicle received {new_camera_violations_string}: \n\n'
            f'{red_light_camera_tickets_diff_string}'
            f'{speed_camera_tickets_diff_string}')

        reckless_string = (
            f'Thank you to @bradlander for making the Dangerous Driver '
            f'Abatement Act a reality.')

        job_should_be_run = (red_light_camera_tickets_after_previous_lookup +
            speed_camera_tickets_after_previous_lookup) > 0

        job.run(is_dry_run=dry_run)

        if not dry_run and job_should_be_run:
            mocked_traffic_violations_tweeter().send_status.assert_called_with(
                message_parts=[summary_string, update_string, reckless_string],
                on_error_message=(
                    f'Error printing reckless driver update. '
                    f'Tagging @bdhowald.'))