def _set_dates(self, agenda_event, tz, start, end):
        """
        Translate the date formats to those used by Agenda
        :param agenda_event:
        :param tz:
        :param start:
        :param end:
        :return:
        """
        datefromlocal = utc_to_local(tz, start)
        datetolocal = utc_to_local(tz, end)

        if datefromlocal is None:
            return

        agenda_event['DateFrom'] = datefromlocal.strftime('%Y-%m-%d')
        # If the to date is different to the from date
        if datefromlocal.strftime('%Y-%m-%d') != datetolocal.strftime('%Y-%m-%d'):
            agenda_event['DateTo'] = datetolocal.strftime('%Y-%m-%d')

        from_time = datefromlocal.strftime('%H:%M')
        to_time = datetolocal.strftime('%H:%M')

        # All day events in Agenda only have a Date
        if not from_time == '00:00' and not to_time == '24:59' and datefromlocal.strftime(
                '%Y-%m-%d') == datetolocal.strftime('%Y-%m-%d'):
            agenda_event['TimeFrom'] = from_time
            agenda_event['TimeTo'] = to_time

        # Need to get the UTC offset
        offset_str = datefromlocal.strftime('%z')
        agenda_event['TimeFromZone'] = offset_str[0:3] + ':' + offset_str[3:5]
        offset_str = datetolocal.strftime('%z')
        agenda_event['TimeToZone'] = offset_str[0:3] + ':' + offset_str[3:5]
    def _set_dates(self, agenda_event, tz, start, end):
        """
        Translate the date formats to those used by Agenda
        :param agenda_event:
        :param tz:
        :param start:
        :param end:
        :return:
        """
        datefromlocal = utc_to_local(tz, start)
        datetolocal = utc_to_local(tz, end)

        if datefromlocal is None:
            return

        agenda_event['DateFrom'] = datefromlocal.strftime('%Y-%m-%d')
        # If the to date is different to the from date
        if datefromlocal.strftime('%Y-%m-%d') != datetolocal.strftime(
                '%Y-%m-%d'):
            agenda_event['DateTo'] = datetolocal.strftime('%Y-%m-%d')

        from_time = datefromlocal.strftime('%H:%M')
        to_time = datetolocal.strftime('%H:%M')

        # All day events in Agenda only have a Date
        if not from_time == '00:00' and not to_time == '24:59' and datefromlocal.strftime(
                '%Y-%m-%d') == datetolocal.strftime('%Y-%m-%d'):
            agenda_event['TimeFrom'] = from_time
            agenda_event['TimeTo'] = to_time

        # Need to get the UTC offset
        offset_str = datefromlocal.strftime('%z')
        agenda_event['TimeFromZone'] = offset_str[0:3] + ':' + offset_str[3:5]
        offset_str = datetolocal.strftime('%z')
        agenda_event['TimeToZone'] = offset_str[0:3] + ':' + offset_str[3:5]
Esempio n. 3
0
    def update_recurring_events(self, updates, original, update_method):
        historic, past, future = self.get_recurring_timeline(original)

        # Determine if the selected event is the first one, if so then
        # act as if we're changing future events
        if len(historic) == 0 and len(past) == 0:
            update_method = UPDATE_FUTURE

        if update_method == UPDATE_FUTURE:
            new_series = [original] + future
        else:
            new_series = past + [original] + future

        # Release the Lock on the selected Event
        remove_lock_information(updates)

        # Get the timezone from the original Event (as the series was created with that timezone in mind)
        timezone = original['dates']['tz']

        # First find the hour and minute of the start date in local time
        start_time = utc_to_local(timezone, updates['dates']['start']).time()

        # Next convert that to seconds since midnight (which gives us a timedelta instance)
        delta_since_midnight = datetime.combine(date.min,
                                                start_time) - datetime.min

        # And calculate the new duration of the events
        duration = updates['dates']['end'] - updates['dates']['start']

        for event in new_series:
            if not event.get(config.ID_FIELD):
                continue

            new_updates = {'dates': deepcopy(event['dates'])} \
                if event.get(config.ID_FIELD) != original.get(config.ID_FIELD) else updates

            # Calculate midnight in local time for this occurrence
            start_of_day_local = utc_to_local(timezone, event['dates']['start'])\
                .replace(hour=0, minute=0, second=0)

            # Then convert midnight in local time to UTC
            start_date_time = local_to_utc(timezone, start_of_day_local)

            # Finally add the delta since midnight
            start_date_time += delta_since_midnight

            # Set the new start and end times
            new_updates['dates']['start'] = start_date_time
            new_updates['dates']['end'] = start_date_time + duration

            # Set '_planning_schedule' on the Event item
            self.set_planning_schedule(new_updates)

            if event.get(config.ID_FIELD) != original.get(config.ID_FIELD):
                new_updates['skip_on_update'] = True
                self.patch(event[config.ID_FIELD], new_updates)
                app.on_updated_events_update_time(
                    new_updates, {'_id': event[config.ID_FIELD]})
Esempio n. 4
0
    def add_to_send_list(self, alert_monitoring, profile, now, one_hour_ago,
                         two_hours_ago, four_hours_ago, yesterday, last_week):
        last_run_time = parse_date_str(
            profile['last_run_time']) if profile.get('last_run_time') else None
        if last_run_time:
            last_run_time = utc_to_local(app.config['DEFAULT_TIMEZONE'],
                                         last_run_time)

        # Convert time to current date for range comparision
        if profile['schedule'].get('time'):
            hour_min = profile['schedule']['time'].split(':')
            schedule_today_plus_five_mins = utc_to_local(
                app.config['DEFAULT_TIMEZONE'], utcnow())
            schedule_today_plus_five_mins = schedule_today_plus_five_mins.replace(
                hour=int(hour_min[0]), minute=int(hour_min[1]))
            schedule_today_plus_five_mins = schedule_today_plus_five_mins + datetime.timedelta(
                minutes=5)

            # Check if the time window is according to schedule
            if (profile['schedule']['interval'] == 'daily'
                    and self.is_within_five_minutes(
                        schedule_today_plus_five_mins, now)
                    and self.is_past_range(last_run_time, yesterday)):
                alert_monitoring['daily']['w_lists'].append(profile)
                return

            # Check if the time window is according to schedule
            # Check if 'day' is according to schedule
            if (profile['schedule']['interval'] == 'weekly'
                    and self.is_within_five_minutes(
                        schedule_today_plus_five_mins, now)
                    and schedule_today_plus_five_mins.strftime('%a').lower()
                    == profile['schedule']['day']
                    and self.is_past_range(last_run_time, last_week)):
                alert_monitoring['weekly']['w_lists'].append(profile)
                return
        else:
            # Check if current time is within 'hourly' window
            if now.minute > 4:
                return

            if profile['schedule'][
                    'interval'] == 'one_hour' and self.is_past_range(
                        last_run_time, one_hour_ago):
                alert_monitoring['one']['w_lists'].append(profile)
                return

            if profile['schedule']['interval'] == 'two_hour' and now.hour % 2 == 0 and \
                    self.is_past_range(last_run_time, two_hours_ago):
                alert_monitoring['two']['w_lists'].append(profile)
                return

            if profile['schedule']['interval'] == 'four_hour' and now.hour % 4 == 0 and  \
                    self.is_past_range(last_run_time, four_hours_ago):
                alert_monitoring['four']['w_lists'].append(profile)
                return
Esempio n. 5
0
    def test_utc_to_local(self):
        # with day light saving on
        utc_dt = datetime(2015, 2, 8, 23, 0, 0, 0, pytz.UTC)
        local_dt = utc_to_local('Australia/Sydney', utc_dt)
        self.assertEqual(utc_dt.hour - local_dt.hour, 13)

        # without day light saving
        utc_dt = datetime(2015, 6, 8, 23, 0, 0, 0, pytz.UTC)
        local_dt = utc_to_local('Australia/Sydney', utc_dt)
        self.assertEqual(utc_dt.hour - local_dt.hour, 14)
Esempio n. 6
0
    def test_utc_to_local(self):
        # with day light saving on
        utc_dt = datetime(2015, 2, 8, 23, 0, 0, 0, pytz.UTC)
        local_dt = utc_to_local('Australia/Sydney', utc_dt)
        self.assertEqual(utc_dt.hour - local_dt.hour, 13)

        # without day light saving
        utc_dt = datetime(2015, 6, 8, 23, 0, 0, 0, pytz.UTC)
        local_dt = utc_to_local('Australia/Sydney', utc_dt)
        self.assertEqual(utc_dt.hour - local_dt.hour, 14)
Esempio n. 7
0
def set_item_details(items):
    for item in items:
        # Prioritise the Event's slugline/name before Planning item's
        item["title"] = item.get("slugline") or \
            item.get("name") or \
            ''

        # Prioritise the Event's description before Planning item's
        event = item.get("event") or item
        item["description"] = event.get("definition_long") or \
            event.get("definition_short") or \
            item.get("description_text") or \
            ''

        if item["type"] == "planning":
            # Use the Event dates if available
            # otherwise fall back to the Planning date
            if (item.get("event") or {}).get("dates"):
                item["dates"] = item["event"]["dates"]

                # Attach Events location/links for sorting/displaying
                item["location"] = item["event"].get("location")
                item["links"] = item["event"].get("links")
            else:
                item["dates"] = {
                    "start": item["planning_date"],
                    "tz": app.config["DEFAULT_TIMEZONE"]
                }

        if len(item.get("location") or []):
            # Set the items Location details if available
            try:
                item["country"] = item["location"][0]["address"][
                    "country"].lower()
                item["locality"] = item["location"][0]["address"][
                    "locality"].lower()
            except (IndexError, KeyError):
                pass

        # Construct the date string here so we don't have to use
        # {% if %} {% else %} statements in the template
        tz = item["dates"]["tz"]
        start_local = utc_to_local(tz, item["dates"]["start"])
        start_local_str = start_local.strftime('%I:%M %P')
        end_local = utc_to_local(
            tz, item["dates"]["end"]) if item["dates"].get("end") else None
        end_local_str = end_local.strftime('%I:%M %P') if end_local else None
        tz_name = start_local.tzname()

        if end_local:
            item[
                "local_date"] = f'{start_local_str} - {end_local_str} ({tz_name})'
        else:
            item["local_date"] = f'{start_local_str} ({tz_name})'
Esempio n. 8
0
def _is_same_news_cycle(a, b):
    return True  # not sure if we will need this cycle thing so keeping it for now
    CYCLE_TZ = "America/New_York"
    CYCLE_START_HOUR = 2

    edt_time_a = utc_to_local(CYCLE_TZ, a["firstcreated"])
    edt_time_b = utc_to_local(CYCLE_TZ, b["firstcreated"])

    min_dt = min(edt_time_a, edt_time_b)
    max_dt = max(edt_time_a, edt_time_b)

    if min_dt.hour < CYCLE_START_HOUR and max_dt.hour >= CYCLE_START_HOUR:
        return False

    return min_dt.date() == max_dt.date()
Esempio n. 9
0
    def should_export(self, schedule, now_local):
        last_sent = None
        if schedule.get('_last_sent'):
            last_sent = utc_to_local(app.config['DEFAULT_TIMEZONE'],
                                     schedule['_last_sent']).replace(
                                         minute=0, second=0, microsecond=0)

        schedule_hour = schedule.get('hour', -1)
        schedule_day = schedule.get('day', -1)
        schedule_week_days = schedule.get('week_days') or []

        # Is this export to be run today (Day of the month)?
        # -1 = every day
        if schedule_day > -1 and schedule_day != now_local.day:
            return False

        # Is this export to be run on this week day (i.e. Monday, Wednesday etc)?
        # None or [] = every week day
        week_day = now_local.strftime('%A')
        if len(schedule_week_days) > 0 and week_day not in schedule_week_days:
            return False

        # Is this export to be run on this hour (i.e. 8am)
        # -1 = every hour
        if schedule_hour > -1 and schedule_hour != now_local.hour:
            return False

        # This export has not been run on this hour
        if last_sent is not None and now_local <= last_sent:
            return False

        return True
Esempio n. 10
0
    def get_monitoring_file(self, date_items_dict, monitoring_profile=None):
        _file = tempfile.NamedTemporaryFile()
        if not date_items_dict:
            return _file

        current_date = utc_to_local(app.config['DEFAULT_TIMEZONE'], utcnow()).strftime('%d/%m/%Y')
        doc = Document()
        section = Section()
        ss = doc.StyleSheet
        p1 = Paragraph(ss.ParagraphStyles.Heading1)
        p1.append('{} Monitoring: {} ({})'.format(app.config.get('MONITORING_REPORT_NAME', 'Newsroom'),
                                                  monitoring_profile['name'], current_date))
        section.append(p1)

        for d in date_items_dict.keys():
            date_p = Paragraph(ss.ParagraphStyles.Normal)
            date_p.append(LINE, d.strftime('%d/%m/%Y'))
            section.append(date_p)
            for item in date_items_dict[d]:
                self.format_item(item, ss, monitoring_profile, section)

        doc.Sections.append(section)
        app.customize_rtf_file(doc)

        doc.write(_file.name)
        return _file
Esempio n. 11
0
    def _gen_summary_header(first_item, total_stories, new_stories):
        return '''<p>SUMMARY FOR {}
Total number of stories transmitted - {}
Total New Stories - {}</p>'''.format(
            utc_to_local(app.config['DEFAULT_TIMEZONE'],
                         first_item.get('versioncreated')).strftime('%d%b%y'),
            total_stories, new_stories['count']).replace('\n', '<br>')
Esempio n. 12
0
def get_local_end_of_day(context, day=None, timezone=None):
    tz = pytz.timezone(timezone or context.app.config['DEFAULT_TIMEZONE'])
    day = day or utc_to_local(tz.zone, utcnow())

    return tz.localize(
        datetime.combine(day, time(23, 59, 59)), is_dst=None
    ).astimezone(pytz.utc)
Esempio n. 13
0
    def run(self, immediate=False):
        self.log_msg = 'Monitoring Scheduled Alerts: {}'.format(utcnow())
        logger.info('{} Starting to send alerts.'.format(self.log_msg))

        lock_name = get_lock_id(
            'newsroom', 'monitoring_{0}'.format(
                'scheduled' if not immediate else 'immediate'))
        if not lock(lock_name, expire=610):
            logger.error('{} Job already running'.format(self.log_msg))
            return

        try:
            now_local = utc_to_local(app.config['DEFAULT_TIMEZONE'], utcnow())
            app.config['SERVER_NAME'] = urlparse(
                app.config['CLIENT_URL']).netloc or None
            celery.conf['SERVER_NAME'] = app.config['SERVER_NAME']

            now_to_minute = now_local.replace(second=0, microsecond=0)

            if immediate:
                self.immediate_worker(now_to_minute)
            else:
                self.scheduled_worker(now_to_minute)
        except Exception as e:
            logger.exception(e)

        unlock(lock_name)
        remove_locks()

        logger.info('{} Completed sending Monitoring Scheduled Alerts.'.format(
            self.log_msg))
Esempio n. 14
0
    def _get_dc_images_by_field(self, archive, value):
        url = app.config.get('DC_URL')

        if not self.dc_headers:
            try:
                self._dc_login()
            except Exception as ex:
                logger.exception(ex)
                return None

        here_now = utc_to_local(app.config['DEFAULT_TIMEZONE'], utcnow())
        start = (here_now - timedelta(days=2)).strftime('%Y%m%d')

        retries = 0
        while retries < 3:
            try:
                response = requests.get(
                    url + '/archives/{}?search_docs[query]='
                    '({}%3D{})%26(MODDATE%3E{})'
                    '&search_docs[format]=full'.format(
                        archive, app.config['DC_SEARCH_FIELD'], value, start),
                    headers={'cookie': self.dc_headers.get('Set-Cookie')})
                response.raise_for_status()
                break
            except requests.exceptions.RequestException as e:
                logger.exception(e)
                try:
                    self._dc_login()
                except requests.exceptions.RequestException:
                    logger.error('DC login failed')
                retries += 1
        if retries == 3:
            logger.error('Failed to get image by field from DC {}'.format(id))
            return None
        return etree.fromstring(response.content)
    def export_events_to_text(self, items, format='utf-8', template=None, tz_offset=None):
        for item in items:
            item['formatted_state'] = item['state'] if item.get('state') in [WORKFLOW_STATE.CANCELLED,
                                                                             WORKFLOW_STATE.RESCHEDULED,
                                                                             WORKFLOW_STATE.POSTPONED] else None
            location = item['location'][0] if len(item.get('location') or []) > 0 else None
            if location:
                format_address(location)
                item['formatted_location'] = location.get('name') if not location.get('formatted_address') else \
                    '{0}, {1}'.format(location.get('name'), location['formatted_address'])

            item['contacts'] = []
            for contact in get_contacts_from_item(item):
                contact_info = ['{0} {1}'.format(contact.get('first_name'), contact.get('last_name'))]
                phone = None
                if (contact.get('job_title')):
                    contact_info[0] = contact_info[0] + ' ({})'.format(contact['job_title'])
                if (len(contact.get('contact_email') or [])) > 0:
                    contact_info.append(contact['contact_email'][0])

                if (len(contact.get('contact_phone') or [])) > 0:
                    phone = next((p for p in contact['contact_phone'] if p.get('public')), None)
                elif len(contact.get('mobile') or []) > 0:
                    phone = next((m for m in contact['mobile'] if m.get('public')), None)

                if phone:
                    contact_info.append(phone.get('number'))

                item['contacts'].append(", ".join(contact_info))

            date_time_format = "%a %d %b %Y, %H:%M"
            item['dates']['start'] = utc_to_local(config.DEFAULT_TIMEZONE, item['dates']['start'])
            item['dates']['end'] = utc_to_local(config.DEFAULT_TIMEZONE, item['dates']['end'])
            item['schedule'] = "{0}-{1}" .format(item['dates']['start'].strftime(date_time_format),
                                                 item['dates']['end'].strftime("%H:%M"))
            if ((item['dates']['end'] - item['dates']['start']).total_seconds() / 60) >= (24 * 60):
                item['schedule'] = "{0} to {1}".format(item['dates']['start'].strftime(date_time_format),
                                                       item['dates']['end'].strftime(date_time_format))

            if tz_offset:
                tz_browser = tz.tzoffset('', int(tz_offset))
                item['browser_start'] = (item['dates']['start']).astimezone(tz_browser)
                item['browser_end'] = (item['dates']['end']).astimezone(tz_browser)

            set_item_place(item)

        return str.encode(render_template(template, items=items), format)
    def test_callback(self):
        item = {
            '_id':
            'foo',
            'guid':
            'foo',
            'type':
            'text',
            'state':
            CONTENT_STATE.PUBLISHED,
            'task': {},
            'profile':
            self.profiles[1],
            'versioncreated':
            self.now - timedelta(minutes=5),
            'headline':
            'foo BELGANIGHT bar (test)',
            'body_html':
            ''.join([
                '<p>foo</p>',
                '<p>Disclaimer:</p>',
                '<p>bar</p>',
            ]),
        }

        with self.assertRaises(StopDuplication):
            macro.callback(item)

        # test metadata
        self.assertEqual(self.profiles[0], item['profile'])
        self.assertEqual(2, item['urgency'])
        self.assertIn(
            {
                'name': 'BELGA/AG',
                'qcode': 'BELGA/AG',
                'scheme': 'credits',
            }, item['subject'])

        # test published
        published = self.app.data.find_one('published',
                                           req=None,
                                           original_id=item['_id'])
        self.assertIsNotNone(published)
        self.assertEqual(CONTENT_STATE.SCHEDULED, published['state'])

        # test schedule
        schedule = published[SCHEDULE_SETTINGS]['utc_publish_schedule']
        self.assertGreaterEqual(self.now + timedelta(minutes=31), schedule)
        self.assertLessEqual(self.now + timedelta(minutes=29), schedule)
        self.assertEqual('Europe/Brussels',
                         published[SCHEDULE_SETTINGS]['time_zone'])
        self.assertEqual(
            utc_to_local('Europe/Brussels',
                         self.now + timedelta(minutes=30)).replace(tzinfo=utc),
            published['publish_schedule'])

        # test content
        self.assertEqual('foo bar', published['headline'])
        self.assertEqual('<p>foo</p>', published['body_html'])
    def _set_revision_history(self, article):
        """Get revision history of published article

        :param dict article:
        """
        query = {
            'query': {
                'filtered': {
                    'filter': {
                        'bool': {
                            'must': {
                                'term': {
                                    'item_id': article.get('item_id')
                                }
                            }
                        }
                    }
                }
            },
            'sort': [{
                'versioncreated': {
                    'order': 'asc'
                }
            }]
        }

        req = ParsedRequest()
        repos = 'published,archived'
        req.args = {
            'source': json.dumps(query),
            'repo': repos,
            'aggregations': 0
        }
        revisions = list(
            get_resource_service('search').get(req=req, lookup=None))
        revisions_tag = []

        for rev in revisions:
            local_date = utc_to_local(
                config.DEFAULT_TIMEZONE,
                rev.get('firstpublished') if rev.get(ITEM_STATE)
                == CONTENT_STATE.PUBLISHED else rev.get('versioncreated'))
            date_string = datetime.strftime(local_date,
                                            '%b XXX, %Y %H:%M %Z').replace(
                                                'XXX', str(local_date.day))
            if rev.get(ITEM_STATE) == CONTENT_STATE.PUBLISHED:
                revisions_tag.append('<li>{} {}</li>'.format(
                    'First published', date_string))
            else:
                revision_markup = '{} {}'.format('Revision published',
                                                 date_string)
                ednote = get_text(rev.get('ednote') or '',
                                  content='html').strip()
                if rev.get(ITEM_STATE) == CONTENT_STATE.CORRECTED and ednote:
                    revision_markup += '<br><i>{}</i>'.format(ednote)
                revisions_tag.append('<li>{}</li>'.format(revision_markup))

        article['_revision_history'] = '<ul>{}</ul>'.format(
            ''.join(revisions_tag)) if revisions_tag else ''
    def _duplicate_planning(self, original):
        new_plan = deepcopy(original)
        if new_plan.get('event_item') and new_plan.get(
                ITEM_STATE) == WORKFLOW_STATE.CANCELLED:
            # if the event is cancelled remove the link to the associated event
            event = get_resource_service('events').find_one(
                req=None, _id=new_plan.get('event_item'))
            if event and event.get(ITEM_STATE) == WORKFLOW_STATE.CANCELLED:
                del new_plan['event_item']

        if (new_plan.get('expired') and new_plan.get('event_item')) or \
                new_plan.get(ITEM_STATE) == WORKFLOW_STATE.RESCHEDULED:
            # If the Planning item has expired and is associated with an Event
            # then we remove the link to the associated Event as the Event would have
            # been expired also.
            # If associated event is rescheduled then remove the associated event
            del new_plan['event_item']

        for f in ('_id', 'guid', 'lock_user', 'lock_time', 'original_creator',
                  '_planning_schedule'
                  'lock_session', 'lock_action', '_created', '_updated',
                  '_etag', 'pubstatus', 'expired', 'featured', 'state_reason',
                  '_updates_schedule'):
            new_plan.pop(f, None)

        new_plan[ITEM_STATE] = WORKFLOW_STATE.DRAFT
        new_plan['guid'] = generate_guid(type=GUID_NEWSML)

        planning_datetime = utc_to_local(config.DEFAULT_TIMEZONE,
                                         new_plan.get('planning_date'))
        local_datetime = utc_to_local(config.DEFAULT_TIMEZONE, utcnow())
        if planning_datetime.date() < local_datetime.date():
            new_plan['planning_date'] = new_plan['planning_date'] + (
                local_datetime.date() - planning_datetime.date())

        for cov in new_plan.get('coverages') or []:
            cov.pop('assigned_to', None)
            cov.get('planning', {}).pop('workflow_status_reason', None)
            cov.pop('scheduled_updates', None)
            cov.get('planning',
                    {})['scheduled'] = new_plan.get('planning_date')
            cov['coverage_id'] = TEMP_ID_PREFIX + 'duplicate'
            cov['workflow_status'] = WORKFLOW_STATE.DRAFT
            cov['news_coverage_status'] = {'qcode': 'ncostat:int'}

        return new_plan
Esempio n. 19
0
    def _check_complete(self, assignments):
        """
        Using the photos API Look for any images that have a configured field that match the id of
        the assignment that have been created in the last day
        :param assignments:
        :return: A list of dictionaries that contain the assignment and matching image
        """
        complete_assignments = list()

        # Restrict the search for potentialy complete assignments to the last couple of days
        here_now = utc_to_local(app.config['DEFAULT_TIMEZONE'], utcnow())
        start = (here_now - timedelta(days=5)).strftime('%Y-%m-%d')
        end = (here_now + timedelta(days=1)).strftime('%Y-%m-%d')

        service = superdesk.get_resource_service('aapmm')
        rq = ParsedRequest()
        for assignment in assignments:
            rq.args = {
                'source':
                json.dumps({
                    "query": {
                        "filtered": {
                            "query": {
                                "query_string": {
                                    "query":
                                    "{}:{}".format(
                                        app.config['DC_SEARCH_FIELD'],
                                        assignment.get('_id'))
                                }
                            }
                        }
                    },
                    "post_filter": {
                        'and': [{
                            'range': {
                                'firstcreated': {
                                    'gte': start,
                                    'lte': end
                                }
                            }
                        }]
                    }
                })
            }
            images = service.get(req=rq, lookup=None)
            # there may be multiple images that make up the assignment, we only need on to mark the
            # assignment as complete
            if images.count() > 0:
                complete_assignments.append({
                    'assignment': assignment,
                    'image': images[0]
                })
        logger.warning(
            'Found {} completed assignments on the photos system'.format(
                len(complete_assignments)))
        return complete_assignments
Esempio n. 20
0
    def send_email_alert(self, items, subject, m, recipients):
        """
        Send an email alert with the details in the body of the email. If a logo image is set in the
        monitoring_report_logo_path settings it will be attached to the email and can be referenced in the
        monitoring_export.html template as <img src="CID:logo" />
        :param items:
        :param subject:
        :param m:
        :param recipients:
        :return:
        """
        from newsroom.email import send_email

        general_settings = get_settings_collection().find_one(
            GENERAL_SETTINGS_LOOKUP)

        data = {
            'date_items_dict':
            get_date_items_dict(items),
            'monitoring_profile':
            m,
            'current_date':
            utc_to_local(app.config['DEFAULT_TIMEZONE'],
                         utcnow()).strftime('%d/%m/%Y'),
            'monitoring_report_name':
            app.config.get('MONITORING_REPORT_NAME', 'Newsroom')
        }

        # Attach logo to email if defined
        logo = None
        if general_settings and general_settings['values'].get(
                'monitoring_report_logo_path'):
            image_filename = general_settings['values'].get(
                'monitoring_report_logo_path')
            if os.path.exists(image_filename):
                with open(image_filename, 'rb') as img:
                    bts = base64.b64encode(img.read())
                    logo = [{
                        'file':
                        bts,
                        'file_name':
                        'logo{}'.format(os.path.splitext(image_filename)[1]),
                        'content_type':
                        'image/{}'.format(
                            os.path.splitext(image_filename)[1].replace(
                                '.', '')),
                        'headers': [('Content-ID', '<logo>')]
                    }]

        send_email(recipients,
                   subject,
                   text_body=render_template('monitoring_export.txt', **data),
                   html_body=render_template('monitoring_export.html', **data),
                   attachments_info=logo)
def brief_internal_routing(item: dict, **kwargs):
    guid = item.get('guid', 'unknown')
    logger.info('macro started item=%s', guid)

    try:
        assert str(item['profile']) == str(
            _get_profile_id(TEXT_PROFILE)), 'profile is not text'
        assert get_word_count(item['body_html']) < 301, 'body is too long'
    except AssertionError as err:
        logger.info('macro stop on assert item=%s error=%s', guid, err)
        raise StopDuplication()
    except KeyError as err:
        logger.error(err)
        raise StopDuplication()

    item.setdefault('subject', [])
    item['urgency'] = 2
    item['profile'] = _get_profile_id(BRIEF_PROFILE)
    item['subject'] = _get_product_subject(
        _get_brief_subject(item.get('subject')))
    item['status'] = CONTENT_STATE.SCHEDULED
    item['operation'] = 'publish'

    _fix_headline(item)
    _fix_body_html(item)

    # schedule +30m
    UTC_FIELD = 'utc_{}'.format(PUBLISH_SCHEDULE)
    try:
        published_at = item[SCHEDULE_SETTINGS][UTC_FIELD]
    except KeyError:
        published_at = utcnow()
    item[SCHEDULE_SETTINGS] = {
        'time_zone': 'Europe/Brussels',
    }
    item[PUBLISH_SCHEDULE] = utc_to_local(item[SCHEDULE_SETTINGS]['time_zone'],
                                          published_at + timedelta(minutes=30))
    update_schedule_settings(item, PUBLISH_SCHEDULE, item[PUBLISH_SCHEDULE])
    item[PUBLISH_SCHEDULE] = item[PUBLISH_SCHEDULE].replace(tzinfo=None)

    # publish
    try:
        internal_destination_auto_publish(item)
    except StopDuplication:
        logger.info('macro done item=%s', guid)
    except DocumentError as err:
        logger.error('validation error when creating brief item=%s error=%s',
                     guid, err)
    except Exception as err:
        logger.exception(err)

    # avoid another item to be created
    raise StopDuplication()
Esempio n. 22
0
 def _format_datetime(self, datetime, rel=False, local=False):
     if not datetime:
         return DEFAULT_DATETIME
     datetime = to_datetime(datetime)
     if rel or local:
         datetime = utc_to_local(cp.TZ, datetime)
     fmt = '%Y-%m-%dT%H:%M:%S{}'.format('%z' if rel else '', )
     formatted = datetime.strftime(fmt)
     if rel:
         return formatted[:-2] + ':' + formatted[
             -2:]  # add : to timezone offset
     return formatted
Esempio n. 23
0
def set_item_dates(item, event):
    """Set the item's dates to be used for sorting"""

    if item["type"] == "planning":
        # Use the Event dates if available
        # otherwise fall back to the Planning date
        if event.get("dates"):
            item["dates"] = item["event"]["dates"]
        else:
            item["dates"] = {
                "start": item["planning_date"],
                "tz": app.config["DEFAULT_TIMEZONE"]
            }

    # Construct the date string here so we don't have to use
    # {% if %} {% else %} statements in the template
    tz = item["dates"].get("tz") or app.config["DEFAULT_TIMEZONE"]
    start_local = utc_to_local(tz, item["dates"]["start"])
    start_local_str = start_local.strftime("%I:%M %P")
    end_local = utc_to_local(
        tz, item["dates"]["end"]) if item["dates"].get("end") else None
    end_local_str = end_local.strftime("%I:%M %P") if end_local else None
    tz_name = start_local.tzname()

    # If the `tz_name` doesn't include a timezone code,
    # then prefix with GMT
    if tz_name.startswith("+"):
        tz_name = f"GMT{tz_name}"

    item["local_date"] = start_local
    if end_local:
        item["local_time"] = f"{start_local_str} - {end_local_str} ({tz_name})"
    else:
        item["local_time"] = f"{start_local_str} ({tz_name})"

    # Set the date string used for grouping
    # in the format YYYY-MM-DD
    item["local_date_str"] = start_local.strftime("%Y-%m-%d")
def get_next_run(schedule, now_utc=None):
    """Get next run time based on schedule.

    Schedule is day of week and time.

    :param dict schedule: dict with `day_of_week` and `create_at` params
    :param now_utc
    :return datetime
    """
    if not schedule.get("is_active", False):
        return None

    if now_utc is None:
        now_utc = utcnow()

    now_utc = now_utc.replace(second=0)

    # Derive the first cron_list entry from the create_at and day_of_week
    if "create_at" in schedule and "cron_list" not in schedule:
        time = schedule.get("create_at").split(":")
        cron_days = ",".join(schedule.get("day_of_week", "*")) if len(
            schedule.get("day_of_week")) else "*"
        cron_entry = "{} {} * * {}".format(time[1], time[0], cron_days)
        schedule["cron_list"] = [cron_entry]
        schedule.pop("create_at", None)

    # adjust current time to the schedule's timezone
    tz_name = schedule.get("time_zone", "UTC")
    if tz_name != "UTC":
        current_local_datetime = utc_to_local(
            tz_name, now_utc)  # convert utc to local time
        cron = croniter(schedule.get("cron_list")[0], current_local_datetime)
        next_run = local_to_utc(tz_name, cron.get_next(datetime))
        for cron_entry in schedule.get("cron_list"):
            next_candidate = local_to_utc(
                tz_name,
                croniter(cron_entry,
                         current_local_datetime).get_next(datetime))
            if next_candidate < next_run:
                next_run = next_candidate
    else:
        cron = croniter(schedule.get("cron_list")[0], now_utc)
        next_run = cron.get_next(datetime)
        for cron_entry in schedule.get("cron_list"):
            next_candidate = croniter(cron_entry, now_utc).get_next(datetime)
            if next_candidate < next_run:
                next_run = next_candidate

    return next_run
Esempio n. 25
0
def get_next_run(schedule, now_utc=None):
    """Get next run time based on schedule.

    Schedule is day of week and time.

    :param dict schedule: dict with `day_of_week` and `create_at` params
    :param now_utc
    :return datetime
    """
    if not schedule.get('is_active', False):
        return None

    if now_utc is None:
        now_utc = utcnow()

    now_utc = now_utc.replace(second=0)

    # Derive the first cron_list entry from the create_at and day_of_week
    if 'create_at' in schedule and 'cron_list' not in schedule:
        time = schedule.get('create_at').split(':')
        cron_days = ','.join(schedule.get('day_of_week', '*')) if len(
            schedule.get('day_of_week')) else '*'
        cron_entry = '{} {} * * {}'.format(time[1], time[0], cron_days)
        schedule['cron_list'] = [cron_entry]
        schedule.pop('create_at', None)

    # adjust current time to the schedule's timezone
    tz_name = schedule.get('time_zone', 'UTC')
    if tz_name != 'UTC':
        current_local_datetime = utc_to_local(
            tz_name, now_utc)  # convert utc to local time
        cron = croniter(schedule.get('cron_list')[0], current_local_datetime)
        next_run = local_to_utc(tz_name, cron.get_next(datetime))
        for cron_entry in schedule.get('cron_list'):
            next_candidate = local_to_utc(
                tz_name,
                croniter(cron_entry,
                         current_local_datetime).get_next(datetime))
            if next_candidate < next_run:
                next_run = next_candidate
    else:
        cron = croniter(schedule.get('cron_list')[0], now_utc)
        next_run = cron.get_next(datetime)
        for cron_entry in schedule.get('cron_list'):
            next_candidate = croniter(cron_entry, now_utc).get_next(datetime)
            if next_candidate < next_run:
                next_run = next_candidate

    return next_run
Esempio n. 26
0
def test_send_weekly_alerts(client, app):
    now = utcnow()
    now = utc_to_local(app.config['DEFAULT_TIMEZONE'], now)
    test_login_succeeds_for_admin(client)
    w = app.data.find_one('monitoring', None, _id='5db11ec55f627d8aa0b545fb')
    assert w is not None
    app.data.update(
        'monitoring', ObjectId('5db11ec55f627d8aa0b545fb'), {
            'schedule': {
                'interval': 'weekly',
                'time': (now - timedelta(minutes=1)).strftime('%H:%M'),
                'day': now.strftime('%a').lower(),
            }
        }, w)
    app.data.insert('items', [{
        '_id': 'foo_yesterday',
        'headline': 'product yesterday',
        'products': [{
            'code': '12345'
        }],
        "versioncreated": now - timedelta(hours=22)
    }])
    app.data.insert('items', [{
        '_id': 'foo_last_hour',
        'headline': 'product three hours',
        'products': [{
            'code': '12345'
        }],
        "versioncreated": now - timedelta(hours=3)
    }])
    app.data.insert('items', [{
        '_id': 'foo_four_days',
        'headline': 'product four days',
        'products': [{
            'code': '12345'
        }],
        "versioncreated": now - timedelta(days=4)
    }])
    with app.mail.record_messages() as outbox:
        MonitoringEmailAlerts().run()
        assert len(outbox) == 1
        assert outbox[0].recipients == [
            '*****@*****.**', '*****@*****.**'
        ]
        assert outbox[0].sender == 'newsroom@localhost'
        assert outbox[0].subject == 'Monitoring Subject'
        assert 'Newsroom Monitoring: W1' in outbox[0].body
        assert 'monitoring-export.pdf' in outbox[0].attachments[0]
Esempio n. 27
0
    def get_monitoring_file(self, date_items_dict, monitoring_profile=None):
        _file = tempfile.NamedTemporaryFile()
        if not date_items_dict:
            return _file

        current_date = utc_to_local(app.config['DEFAULT_TIMEZONE'],
                                    utcnow()).strftime('%d/%m/%Y')
        doc = Document()
        section = Section()
        ss = doc.StyleSheet

        general_settings = get_settings_collection().find_one(
            GENERAL_SETTINGS_LOOKUP)
        if general_settings and general_settings['values'].get(
                'monitoring_report_logo_path'):
            image_filename = general_settings['values'].get(
                'monitoring_report_logo_path')
            if os.path.exists(image_filename):
                try:
                    image = LogoImage(general_settings['values'].get(
                        'monitoring_report_logo_path'))
                    section.append(Paragraph(image))
                except Exception as e:
                    logger.exception(e)
                    logger.error(
                        'Failed to open logo image {}'.format(image_filename))
            else:
                logger.error(
                    'Unable to find logo image {}'.format(image_filename))

        p1 = Paragraph(ss.ParagraphStyles.Heading1)
        p1.append('{} Monitoring: {} ({})'.format(
            app.config.get('MONITORING_REPORT_NAME', 'Newsroom'),
            monitoring_profile['name'], current_date))
        section.append(p1)

        for d in date_items_dict.keys():
            date_p = Paragraph(ss.ParagraphStyles.Normal)
            date_p.append(LINE, d.strftime('%d/%m/%Y'))
            section.append(date_p)
            for item in date_items_dict[d]:
                self.format_item(item, ss, monitoring_profile, section)

        doc.Sections.append(section)
        app.customize_rtf_file(doc)

        doc.write(_file.name)
        return _file
Esempio n. 28
0
    def run(self, now=None):
        if now:
            now_utc = now if isinstance(now, datetime) else local_to_utc(
                app.config['DEFAULT_TIMEZONE'],
                datetime.strptime(now, '%Y-%m-%dT%H'))
        else:
            now_utc = utcnow()

        now_local = utc_to_local(app.config['DEFAULT_TIMEZONE'], now_utc)

        logger.info('Starting to send scheduled reports: {}'.format(now_utc))

        schedules = self.get_schedules()

        if len(schedules) < 1:
            logger.info('No enabled schedules found, not continuing')
            return

        # Set now to the beginning of the hour (in local time)
        now_local = now_local.replace(minute=0, second=0, microsecond=0)

        for scheduled_report in schedules:
            schedule_id = str(scheduled_report.get('_id'))

            try:
                if not self.should_send_report(scheduled_report, now_local):
                    logger.info(
                        'Scheduled Report {} not scheduled to be sent'.format(
                            schedule_id))
                    continue

                logger.info('Attempting to send Scheduled Report {}'.format(
                    schedule_id))
                self._send_report(scheduled_report)

                # Update the _last_sent of the schedule
                get_resource_service('scheduled_reports').system_update(
                    scheduled_report.get('_id'), {'_last_sent': now_utc},
                    scheduled_report)
            except Exception as e:
                logger.error(
                    'Failed to generate report for {}. Error: {}'.format(
                        schedule_id, str(e)))
                logger.exception(e)

        logger.info('Completed sending scheduled reports: {}'.format(now_utc))
    def _set_revision_history(self, article):
        """Get revision history of published article

        :param dict article:
        """
        query = {
            'query': {
                'filtered': {
                    'filter': {
                        'bool': {
                            'must': {
                                'term': {'item_id': article.get('item_id')}
                            }
                        }
                    }
                }
            },
            'sort': [
                {'versioncreated': {'order': 'asc'}}
            ]
        }

        req = ParsedRequest()
        repos = 'published,archived'
        req.args = {'source': json.dumps(query), 'repo': repos, 'aggregations': 0}
        revisions = list(get_resource_service('search').get(req=req, lookup=None))
        revisions_tag = []

        for rev in revisions:
            local_date = utc_to_local(
                config.DEFAULT_TIMEZONE,
                rev.get('firstpublished') if rev.get(ITEM_STATE) == CONTENT_STATE.PUBLISHED
                else rev.get('versioncreated')
            )
            date_string = datetime.strftime(local_date, '%b XXX, %Y %H:%M %Z').replace('XXX', str(local_date.day))
            if rev.get(ITEM_STATE) == CONTENT_STATE.PUBLISHED:
                revisions_tag.append('<li>{} {}</li>'.format('First published', date_string))
            else:
                revision_markup = '{} {}'.format('Revision published', date_string)
                ednote = get_text(rev.get('ednote') or '', content='html').strip()
                if rev.get(ITEM_STATE) == CONTENT_STATE.CORRECTED and ednote:
                    revision_markup += '<br><i>{}</i>'.format(ednote)
                revisions_tag.append('<li>{}</li>'.format(revision_markup))

        article['_revision_history'] = '<ul>{}</ul>' .format(''.join(revisions_tag)) if revisions_tag else ''
Esempio n. 30
0
def set_photo_coverage_href(coverage, planning_item):
    if app.config.get('MULTIMEDIA_WEBSITE_SEARCH_URL') and \
            coverage['planning']['g2_content_type'] == 'picture' and \
            coverage['workflow_status'] == 'completed':
        slugline = coverage.get('planning',
                                {}).get('slugline',
                                        planning_item.get('slugline'))
        # converting the coverage schedule date to local time
        local_date = datetime.strftime(
            utc_to_local(
                app.config.get('DEFAULT_TIMEZONE'),
                datetime.strptime(coverage['planning']['scheduled'],
                                  '%Y-%m-%dT%H:%M:%S%z')),
            '%Y-%m-%dT%H:%M:%S%z')
        q = '{"DateRange":[{"Start":"%s"}],"DateCreatedFilter":"true"}' % local_date[:
                                                                                     10]
        return '{}"{}"?q={}'.format(
            app.config.get('MULTIMEDIA_WEBSITE_SEARCH_URL'), slugline, q)
    def on_create(self, docs):
        for doc in docs:
            date = utc_to_local(doc.get('tz') or app.config['DEFAULT_TIMEZONE'], doc.get('date'))
            _id = date.strftime(ID_DATE_FORMAT)

            items = self.find(where={'_id': _id})
            if items.count() > 0:
                raise SuperdeskApiError.badRequestError(
                    message="Featured story already exists for this date.")

            self.validate_featured_attrribute(doc.get('items'))
            doc['_id'] = _id
            self.post_featured_planning(doc)
            # set the author
            set_original_creator(doc)

            # set timestamps
            update_dates_for(doc)
def get_next_run(schedule, now_utc=None):
    """Get next run time based on schedule.

    Schedule is day of week and time.

    :param dict schedule: dict with `day_of_week` and `create_at` params
    :param now_utc
    :return datetime
    """
    if not schedule.get('is_active', False):
        return None

    if now_utc is None:
        now_utc = utcnow()

    now_utc = now_utc.replace(second=0)

    # Derive the first cron_list entry from the create_at and day_of_week
    if 'create_at' in schedule and 'cron_list' not in schedule:
        time = schedule.get('create_at').split(':')
        cron_days = ','.join(schedule.get('day_of_week', '*')) if len(schedule.get('day_of_week')) else '*'
        cron_entry = '{} {} * * {}'.format(time[1], time[0], cron_days)
        schedule['cron_list'] = [cron_entry]
        schedule.pop('create_at', None)

    # adjust current time to the schedule's timezone
    tz_name = schedule.get('time_zone', 'UTC')
    if tz_name != 'UTC':
        current_local_datetime = utc_to_local(tz_name, now_utc)  # convert utc to local time
        cron = croniter(schedule.get('cron_list')[0], current_local_datetime)
        next_run = local_to_utc(tz_name, cron.get_next(datetime))
        for cron_entry in schedule.get('cron_list'):
            next_candidate = local_to_utc(tz_name, croniter(cron_entry, current_local_datetime).get_next(datetime))
            if next_candidate < next_run:
                next_run = next_candidate
    else:
        cron = croniter(schedule.get('cron_list')[0], now_utc)
        next_run = cron.get_next(datetime)
        for cron_entry in schedule.get('cron_list'):
            next_candidate = croniter(cron_entry, now_utc).get_next(datetime)
            if next_candidate < next_run:
                next_run = next_candidate

    return next_run
Esempio n. 33
0
    def should_send_report(scheduled_report, now_local):
        # Set now to the beginning of the hour (in local time)
        now_to_hour = now_local.replace(minute=0, second=0, microsecond=0)

        last_sent = None
        if scheduled_report.get('_last_sent'):
            last_sent = utc_to_local(
                app.config['DEFAULT_TIMEZONE'],
                scheduled_report.get('_last_sent')).replace(minute=0,
                                                            second=0,
                                                            microsecond=0)

        # Fix issue with incorrect schedule attributes being stored
        get_resource_service('scheduled_reports').set_schedule(
            scheduled_report)
        schedule = scheduled_report.get('schedule') or {}
        schedule_hour = schedule.get('hour', -1)
        schedule_day = schedule.get('day', -1)
        schedule_week_days = schedule.get('week_days') or []

        # Is this report to be run today (Day of the month)?
        # -1 = every day
        if schedule_day > -1 and schedule_day != now_to_hour.day:
            return False

        # Is this report to be run on this week day (i.e. Monday, Wednesday etc)?
        # None or [] = every week day
        week_day = now_to_hour.strftime('%A')
        if len(schedule_week_days) > 0 and week_day not in schedule_week_days:
            return False

        # Is this report to be run on this hour (i.e. 8am)
        # -1 = every hour
        if schedule_hour > -1 and schedule_hour != now_to_hour.hour:
            return False

        # This report has not been run on this hour
        if last_sent is not None and now_to_hour <= last_sent:
            return False

        return True
Esempio n. 34
0
    def get_monitoring_file(self, date_items_dict, monitoring_profile):
        if not monitoring_profile or not date_items_dict:
            return

        data = {
            'date_items_dict':
            date_items_dict,
            'monitoring_profile':
            monitoring_profile,
            'current_date':
            utc_to_local(app.config['DEFAULT_TIMEZONE'],
                         utcnow()).strftime('%d/%m/%Y'),
            'monitoring_report_name':
            app.config.get('MONITORING_REPORT_NAME', 'Newsroom')
        }
        exported_html = str.encode(
            render_template('monitoring_export.html', **data), 'utf-8')
        pdf_context = pisa.CreatePDF(exported_html)
        _file = pdf_context.dest
        _file.seek(0)
        return _file
 def _get_date(self, article, field):
     return utc_to_local(config.DEFAULT_TIMEZONE or 'UTC', article.get(field) or utcnow())
    def setUp(self):
        local_time = utc_to_local(self.app.config['DEFAULT_TIMEZONE'], utcnow())

        self.desks = [
            {'name': 'authoring', 'source': 'aap', 'desk_type': 'authoring'},
            {'name': 'production', 'source': 'aap', 'desk_type': 'production'},
            {'name': 'production2', 'source': 'aap', 'desk_type': 'production'}
        ]

        self.app.data.insert('desks', self.desks)

        self.articles = [
            {
                '_id': '1', 'type': 'text', 'abstract': 'abstract item 1', 'slugline': 'slugline item 1',
                'dateline': {
                    'text': 'Sydney, 01 Jan AAP -',
                    'located': {
                        'city': 'Sydney'
                    }
                },
                'state': 'in_progress',
                'versioncreated': local_time + timedelta(minutes=-1),
                'task': {
                    'desk': self.desks[0].get('_id')
                }
            },
            {
                '_id': '2', 'type': 'text', 'abstract': 'abstract "item 2"', 'slugline': 'slugline item 2',
                'dateline': {
                    'text': 'Sydney, 01 Jan AAP -',
                    'located': {
                        'city': 'Sydney'
                    }
                },
                'state': 'submitted',
                'versioncreated': local_time + timedelta(minutes=-2),
                'task': {
                    'desk': self.desks[1].get('_id'),
                    'last_authoring_desk': self.desks[0].get('_id')
                }
            },
            {
                '_id': '2a', 'type': 'text', 'abstract': 'abstract item 2a', 'slugline': 'slugline item 2a',
                'dateline': {
                    'text': 'Sydney, 01 Jan AAP -',
                    'located': {
                        'city': 'Sydney'
                    }
                },
                'state': 'published',
                'versioncreated': local_time + timedelta(minutes=-5),
                'task': {
                    'desk': self.desks[1].get('_id'),
                    'last_authoring_desk': self.desks[0].get('_id')
                }
            },
            {
                '_id': '3', 'type': 'text', 'abstract': 'abstract item 3', 'slugline': 'slugline item 3',
                'dateline': {
                    'text': 'Sydney, 01 Jan AAP -',
                    'located': {
                        'city': 'Sydney'
                    }
                },
                'state': 'submitted',
                'versioncreated': local_time + timedelta(days=-2),
                'task': {
                    'desk': self.desks[1].get('_id'),
                    'last_authoring_desk': self.desks[0].get('_id')
                }
            },
            {
                '_id': '4', 'type': 'text', 'abstract': 'abstract item 4', 'slugline': 'slugline item 4',
                'dateline': {
                    'text': 'Sydney, 01 Jan AAP -',
                    'located': {
                        'city': 'Sydney'
                    }
                },
                'state': 'corrected',
                'versioncreated': local_time + timedelta(minutes=-1),
                'task': {
                    'desk': self.desks[1].get('_id')
                }
            },
            {
                '_id': '5', 'type': 'text', 'abstract': 'abstract item 5', 'slugline': 'slugline item 5',
                'dateline': {
                    'text': 'Sydney, 01 Jan AAP -',
                    'located': {
                        'city': 'Sydney'
                    }
                },
                'state': 'in_progress',
                'versioncreated': local_time + timedelta(minutes=-1),
                'task': {
                    'desk': self.desks[2].get('_id'),
                    'last_production_desk': self.desks[1].get('_id')
                }
            },
            {
                '_id': '6', 'type': 'text', 'abstract': 'abstract item 6', 'slugline': 'slugline item 6',
                'dateline': {
                    'text': 'Sydney, 01 Jan AAP -',
                    'located': {
                        'city': 'Sydney'
                    }
                },
                'state': 'published',
                'versioncreated': local_time + timedelta(days=-1),
                'task': {
                    'desk': self.desks[2].get('_id')
                }
            },
            {
                '_id': '7', 'type': 'text', 'abstract': 'abstract item 7', 'slugline': 'slugline item 7',
                'dateline': {
                    'text': 'Sydney, 01 Jan AAP -',
                    'located': {
                        'city': 'Sydney'
                    }
                },
                'state': 'published',
                'versioncreated': local_time + timedelta(minutes=-7),
                'task': {
                    'desk': self.desks[0].get('_id')
                }
            }
        ]

        self.published = [
            {
                'item_id': '2a', 'type': 'text', 'abstract': 'abstract item 2a', 'slugline': 'slugline item 2a',
                'dateline': {
                    'text': 'Sydney, 01 Jan AAP -',
                    'located': {
                        'city': 'Sydney'
                    }
                },
                'state': 'published',
                'versioncreated': local_time + timedelta(minutes=-5),
                'task': {
                    'desk': self.desks[1].get('_id'),
                    'last_authoring_desk': self.desks[0].get('_id')
                }
            },
            {
                'item_id': '4', 'type': 'text', 'abstract': 'abstract item 4', 'slugline': 'slugline item 4',
                'dateline': {
                    'text': 'Sydney, 01 Jan AAP -',
                    'located': {
                        'city': 'Sydney'
                    }
                },
                'state': 'corrected',
                'versioncreated': local_time + timedelta(minutes=-1),
                'task': {
                    'desk': self.desks[1].get('_id')
                }
            },
            {
                'item_id': '4', 'type': 'text', 'abstract': 'abstract item 4', 'slugline': 'slugline item 4',
                'dateline': {
                    'text': 'Sydney, 01 Jan AAP -',
                    'located': {
                        'city': 'Sydney'
                    }
                },
                'state': 'published',
                'versioncreated': local_time + timedelta(minutes=-5),
                'task': {
                    'desk': self.desks[1].get('_id')
                }
            },
            {
                'item_id': '6', 'type': 'text', 'abstract': 'abstract item 6', 'slugline': 'slugline item 6',
                'dateline': {
                    'text': 'Sydney, 01 Jan AAP -',
                    'located': {
                        'city': 'Sydney'
                    }
                },
                'state': 'published',
                'versioncreated': local_time + timedelta(days=-1),
                'task': {
                    'desk': self.desks[2].get('_id')
                }
            },
            {
                'item_id': '7', 'type': 'text', 'abstract': 'abstract item 7', 'slugline': 'slugline item 7',
                'dateline': {
                    'text': 'Sydney, 01 Jan AAP -',
                    'located': {
                        'city': 'Sydney'
                    }
                },
                'state': 'published',
                'versioncreated': local_time + timedelta(minutes=-7),
                'task': {
                    'desk': self.desks[0].get('_id')
                }
            }
        ]

        self.app.data.insert('archive', self.articles)
        self.app.data.insert('published', self.published)
    def create_query(self):
        if isinstance(self.desk_id, str):
            self.desk_id = ObjectId(self.desk_id)

        desk = get_resource_service('desks').find_one(req=None, _id=self.desk_id)

        if not desk:
            return {}, ''

        states = list(PUBLISH_STATES)
        states.extend([CONTENT_STATE.SUBMITTED, CONTENT_STATE.PROGRESS])
        # using the server default timezone.
        current_local_time = utc_to_local(config.DEFAULT_TIMEZONE, utcnow())

        query = {
            'query': {
                'filtered': {
                    'filter': {
                        'bool': {
                            'must': [
                                {
                                    'term': {ITEM_TYPE: CONTENT_TYPE.TEXT}
                                }
                            ],
                            'must_not': [
                                {
                                    'range': {
                                        'versioncreated': {
                                            "lte": current_local_time.strftime('%Y-%m-%dT00:00:00%z')
                                        }
                                    }
                                }
                            ]
                        }
                    }
                }
            },
            'sort': [
                {'versioncreated': 'desc'}
            ],
            'size': 200
        }

        desk_query = query['query']['filtered']['filter']['bool']['must']
        if desk.get('desk_type') == DeskTypes.authoring.value:
            desk_filter = {'or': []}

            # if published from authoring desk
            desk_filter['or'].append({'and': [
                {'term': {'task.desk': str(self.desk_id)}},
                {'terms': {ITEM_STATE: list(PUBLISH_STATES)}}
            ]})

            # if published send from authoring desk
            desk_filter['or'].append({'and': [
                {'term': {'task.last_authoring_desk': str(self.desk_id)}},
                {'terms': {ITEM_STATE: states}}
            ]})

            desk_query.append(desk_filter)
        else:
            # filtering only published states for production for now.
            desk_query.append({'term': {'task.desk': str(self.desk_id)}})
            desk_query.append({'terms': {ITEM_STATE: list(PUBLISH_STATES)}})

        return query, ['archive', 'published']
Esempio n. 38
0
 def get_date_time_string(datetime_utc, str_format='%X %d%b%y'):
     return utc_to_local(
         app.config['DEFAULT_TIMEZONE'],
         datetime_utc
     ).strftime(str_format)
 def _format_datetime(self, article_date, date_format='%Y-%m-%dT%H:%M:%S%z'):
     return datetime.strftime(utc_to_local(config.DEFAULT_TIMEZONE, article_date), date_format)