def test_get_timezone_offset_sydney(self): utc_dt = datetime(2015, 2, 8, 23, 0, 0, 0, pytz.UTC) offset = get_timezone_offset('Australia/Sydney', utc_dt) self.assertEqual(offset, '+1100') utc_dt = datetime(2015, 9, 8, 23, 0, 0, 0, pytz.UTC) offset = get_timezone_offset('Australia/Sydney', utc_dt) self.assertEqual(offset, '+1000')
def test_get_timezone_offset_wrong_input(self): utc_dt = "test" offset = get_timezone_offset("Europe/Prague", utc_dt) self.assertEqual(offset, "+0000") utc_dt = datetime(2015, 9, 8, 23, 0, 0, 0, pytz.UTC) offset = get_timezone_offset("Europe/Sydney", utc_dt) self.assertEqual(offset, "+0000")
def test_get_timezone_offset_wrong_input(self): utc_dt = 'test' offset = get_timezone_offset('Europe/Prague', utc_dt) self.assertEqual(offset, '+0000') utc_dt = datetime(2015, 9, 8, 23, 0, 0, 0, pytz.UTC) offset = get_timezone_offset('Europe/Sydney', utc_dt) self.assertEqual(offset, '+0000')
def test_get_timezone_offset_sydney(self): utc_dt = datetime(2015, 2, 8, 23, 0, 0, 0, pytz.UTC) offset = get_timezone_offset('Australia/Sydney', utc_dt) self.assertEqual(offset, '+1100') utc_dt = datetime(2015, 9, 8, 23, 0, 0, 0, pytz.UTC) offset = get_timezone_offset('Australia/Sydney', utc_dt) self.assertEqual(offset, '+1000')
def test_get_timezone_offset_wrong_input(self): utc_dt = 'test' offset = get_timezone_offset('Europe/Prague', utc_dt) self.assertEqual(offset, '+0000') utc_dt = datetime(2015, 9, 8, 23, 0, 0, 0, pytz.UTC) offset = get_timezone_offset('Europe/Sydney', utc_dt) self.assertEqual(offset, '+0000')
def test_get_timezone_offset_prague(self): utc_dt = datetime(2015, 2, 8, 23, 0, 0, 0, pytz.UTC) offset = get_timezone_offset('Europe/Prague', utc_dt) self.assertEqual(offset, '+0100') utc_dt = datetime(2015, 9, 8, 23, 0, 0, 0, pytz.UTC) offset = get_timezone_offset('Europe/Prague', utc_dt) self.assertEqual(offset, '+0200')
def test_get_timezone_offset_prague(self): utc_dt = datetime(2015, 2, 8, 23, 0, 0, 0, pytz.UTC) offset = get_timezone_offset('Europe/Prague', utc_dt) self.assertEqual(offset, '+0100') utc_dt = datetime(2015, 9, 8, 23, 0, 0, 0, pytz.UTC) offset = get_timezone_offset('Europe/Prague', utc_dt) self.assertEqual(offset, '+0200')
def get_pre_defined_date_filter(start, end): filterList = list() filterList.append({ 'range': { 'dates.start': { 'gte': start, 'lt': end, 'time_zone': get_timezone_offset(config.DEFAULT_TIMEZONE, utcnow()) } } }) filterList.append({ 'range': { 'dates.end': { 'gte': start, 'lt': end, 'time_zone': get_timezone_offset(config.DEFAULT_TIMEZONE, utcnow()) } } }) filterList.append({ 'and': { 'filters': [ { 'range': { 'dates.start': { 'lt': start, 'time_zone': get_timezone_offset(config.DEFAULT_TIMEZONE, utcnow()) }, }, }, { 'range': { 'dates.end': { 'gt': end, 'time_zone': get_timezone_offset(config.DEFAULT_TIMEZONE, utcnow()) }, }, }, ], }, }) return filterList
def get_highlighted_items(highlights_id): """Get items marked for given highlight and passing date range query.""" highlight = get_resource_service('highlights').find_one(req=None, _id=highlights_id) query = { 'query': { 'filtered': {'filter': {'and': [ {'range': {'versioncreated': {'gte': highlight.get('auto_insert', 'now/d'), 'time_zone': get_timezone_offset(config.DEFAULT_TIMEZONE, utcnow())}}}, {'term': {'highlights': str(highlights_id)}}, ]}} }, 'sort': [ {'versioncreated': 'desc'}, ], 'size': 200 } request = ParsedRequest() request.args = {'source': json.dumps(query), 'repo': 'archive,published'} return list(get_resource_service('search').get(req=request, lookup=None))
def get_highlighted_items(highlights_id): """Get items marked for given highlight and passing date range query.""" highlight = get_resource_service('highlights').find_one(req=None, _id=highlights_id) query = { 'query': { 'filtered': { 'filter': { 'and': [ { 'range': { 'versioncreated': { 'gte': highlight.get('auto_insert', 'now/d'), 'time_zone': get_timezone_offset( config.DEFAULT_TIMEZONE, utcnow()) } } }, { 'term': { 'highlights': str(highlights_id) } }, ] } } }, 'sort': [ { 'versioncreated': 'desc' }, ], 'size': 200 } request = ParsedRequest() request.args = {'source': json.dumps(query), 'repo': 'archive,published'} return list(get_resource_service('search').get(req=request, lookup=None))
def __init__(self, field: str, gt: str = None, gte: str = None, lt: str = None, lte: str = None, value_format: str = None, time_zone: str = None, start_of_week: int = None, date_range: DATE_RANGE = None, date: str = None): """Allows to easily set fields by name using kwargs""" self.field = field self.gt = gt self.gte = gte self.lt = lt self.lte = lte self.value_format = value_format self.time_zone = time_zone if time_zone else get_timezone_offset( app.config['DEFAULT_TIMEZONE'], utcnow()) self.start_of_week = int(start_of_week or 0) self.date_range = date_range self.date = str_to_date(date) if date else None
def _get_timezone_offset(self, params): if params.get('tz_offset') is not None: return params.get('tz_offset') return get_timezone_offset(config.DEFAULT_TIMEZONE, utcnow())
def get_time_zone(params: Dict[str, Any]): return params.get('tz_offset') or get_timezone_offset( app.config['DEFAULT_TIMEZONE'], utcnow())
def _get_planning_date_filters(self, request): """Get date filters for planning resource :param request: object representing the HTTP request """ params = request.args or MultiDict() date_filter_param, start_date, end_date = self._parse_date_params(params) if not (date_filter_param or start_date or end_date): return { 'nested': { 'path': '_planning_schedule', 'filter': { 'range': { '_planning_schedule.scheduled': { 'gte': 'now/d', 'time_zone': get_timezone_offset(config.DEFAULT_TIMEZONE, utcnow()) } } } } } start_of_week = self._get_start_of_week(params) date_filters = { 'range': { '_planning_schedule.scheduled': { 'time_zone': get_timezone_offset(config.DEFAULT_TIMEZONE, utcnow()) } } } if date_filter_param.lower() == 'today': date_filters['range']['_planning_schedule.scheduled']['gte'] = 'now/d' date_filters['range']['_planning_schedule.scheduled']['lt'] = 'now+24h/d' elif date_filter_param.lower() == 'tomorrow': date_filters['range']['_planning_schedule.scheduled']['gte'] = 'now+24h/d' date_filters['range']['_planning_schedule.scheduled']['lt'] = 'now+48h/d' elif date_filter_param.lower() == 'this_week': end_of_this_week = get_start_of_next_week(None, start_of_week) start_of_this_week = end_of_this_week - timedelta(days=7) date_filters['range']['_planning_schedule.scheduled']['gte'] = \ '{}||/d'.format(start_of_this_week.strftime(config.ELASTIC_DATE_FORMAT)) date_filters['range']['_planning_schedule.scheduled']['lt'] = \ '{}||/d'.format(end_of_this_week.strftime(config.ELASTIC_DATE_FORMAT)) elif date_filter_param.lower() == 'next_week': start_of_next_week = get_start_of_next_week(None, start_of_week) end_of_next_week = start_of_next_week + timedelta(days=7) date_filters['range']['_planning_schedule.scheduled']['gte'] = \ '{}||/d'.format(start_of_next_week.strftime(config.ELASTIC_DATE_FORMAT)) date_filters['range']['_planning_schedule.scheduled']['lt'] = \ '{}||/d'.format(end_of_next_week.strftime(config.ELASTIC_DATE_FORMAT)) else: if start_date: date_filters['range']['_planning_schedule.scheduled']['gte'] = start_date if end_date: date_filters['range']['_planning_schedule.scheduled']['lte'] = end_date return { 'nested': { 'path': '_planning_schedule', 'filter': date_filters, } }
def _get_events_date_filters(self, request): """Get date filters for events resource :param request: object representing the HTTP request """ params = request.args or MultiDict() date_filter_param, start_date, end_date = self._parse_date_params(params) if not (date_filter_param or start_date or end_date): return { 'range': { 'dates.end': { 'gte': 'now/d', 'time_zone': get_timezone_offset(config.DEFAULT_TIMEZONE, utcnow()) } } } start_of_week = self._get_start_of_week(params) date_filters = [] def get_pre_defined_date_filter(start, end): filterList = list() filterList.append({ 'range': { 'dates.start': { 'gte': start, 'lt': end, 'time_zone': get_timezone_offset(config.DEFAULT_TIMEZONE, utcnow()) } } }) filterList.append({ 'range': { 'dates.end': { 'gte': start, 'lt': end, 'time_zone': get_timezone_offset(config.DEFAULT_TIMEZONE, utcnow()) } } }) filterList.append({ 'and': { 'filters': [ { 'range': { 'dates.start': { 'lt': start, 'time_zone': get_timezone_offset(config.DEFAULT_TIMEZONE, utcnow()) }, }, }, { 'range': { 'dates.end': { 'gt': end, 'time_zone': get_timezone_offset(config.DEFAULT_TIMEZONE, utcnow()) }, }, }, ], }, }) return filterList if date_filter_param.lower() == 'today': date_filters = get_pre_defined_date_filter('now/d', 'now+24h/d') elif date_filter_param.lower() == 'tomorrow': date_filters = get_pre_defined_date_filter('now+24h/d', 'now+48h/d') elif date_filter_param.lower() == 'this_week': end_of_this_week = get_start_of_next_week(None, start_of_week) start_of_this_week = end_of_this_week - timedelta(days=7) date_filters = get_pre_defined_date_filter( '{}||/d'.format(start_of_this_week.strftime(config.ELASTIC_DATE_FORMAT)), '{}||/d'.format(end_of_this_week.strftime(config.ELASTIC_DATE_FORMAT)) ) elif date_filter_param.lower() == 'next_week': start_of_next_week = get_start_of_next_week(None, start_of_week) end_of_next_week = start_of_next_week + timedelta(days=7) date_filters = get_pre_defined_date_filter( '{}||/d'.format(start_of_next_week.strftime(config.ELASTIC_DATE_FORMAT)), '{}||/d'.format(end_of_next_week.strftime(config.ELASTIC_DATE_FORMAT)) ) else: if start_date and not end_date: date_filters.extend([ { 'range': { 'dates.start': { 'gte': start_date, 'time_zone': get_timezone_offset(config.DEFAULT_TIMEZONE, utcnow()) }, }, }, { 'range': { 'dates.end': { 'gte': start_date, 'time_zone': get_timezone_offset(config.DEFAULT_TIMEZONE, utcnow()) }, }, } ]) elif not start_date and end_date: date_filters.extend([ { 'range': { 'dates.end': { 'lte': end_date, 'time_zone': get_timezone_offset(config.DEFAULT_TIMEZONE, utcnow()) }, }, }, { 'range': { 'dates.start': { 'lte': end_date, 'time_zone': get_timezone_offset(config.DEFAULT_TIMEZONE, utcnow()) }, }, } ]) else: date_filters.extend([ { 'range': { 'dates.start': { 'gte': start_date, 'time_zone': get_timezone_offset(config.DEFAULT_TIMEZONE, utcnow()) }, 'dates.end': { 'lte': end_date, 'time_zone': get_timezone_offset(config.DEFAULT_TIMEZONE, utcnow()) }, }, }, { 'and': { 'filters': [ { 'range': { 'dates.start': { 'lt': start_date, 'time_zone': get_timezone_offset(config.DEFAULT_TIMEZONE, utcnow()) }, }, }, { 'range': { 'dates.end': { 'gt': end_date, 'time_zone': get_timezone_offset(config.DEFAULT_TIMEZONE, utcnow()) }, }, }, ], }, }, { 'or': { 'filters': [ { 'range': { 'dates.start': { 'gte': start_date, 'lte': end_date, 'time_zone': get_timezone_offset(config.DEFAULT_TIMEZONE, utcnow()) }, }, }, { 'range': { 'dates.end': { 'gte': start_date, 'lte': end_date, 'time_zone': get_timezone_offset(config.DEFAULT_TIMEZONE, utcnow()) }, }, }, ], }, } ]) return { 'or': { 'filters': date_filters } }
def generate_text_item(items, template_name, resource_type): template = get_resource_service( 'planning_export_templates').get_export_template( template_name, resource_type) archive_service = get_resource_service('archive') if not template: raise SuperdeskApiError.badRequestError('Invalid template selected') for item in items: # Create list of assignee with preference to coverage_provider, if not, assigned user item['published_archive_items'] = [] item['assignees'] = [] item['text_assignees'] = [] item['contacts'] = [] text_users = [] text_desks = [] users = [] desks = [] def enhance_coverage(planning, item, users): def _enhance_assigned_provider(coverage, item, assigned_to): """ Enhances the text_assignees with the contact details if it's assigned to an external provider """ if assigned_to.get('contact'): provider_contact = get_resource_service( 'contacts').find_one(req=None, _id=assigned_to.get('contact')) assignee_str = "{0} - {1} {2} ".format( assigned_to['coverage_provider']['name'], provider_contact.get('first_name', ''), provider_contact.get('last_name', '')) phone_number = [ n.get('number') for n in provider_contact.get('mobile', []) + provider_contact.get('contact_phone', []) ] if len(phone_number): assignee_str += ' ({0})'.format(phone_number[0]) # If there is an internal note on the coverage that is different to the internal note # on the planning if (coverage.get('planning', {})).get('internal_note', '') \ and item.get('internal_note', '') !=\ (coverage.get('planning', {})).get('internal_note', ''): assignee_str += ' ({0})'.format( (coverage.get('planning', {})).get('internal_note', '')) item['text_assignees'].append(assignee_str) else: item['text_assignees'].append( assigned_to['coverage_provider']['name']) for c in (planning.get('coverages') or []): is_text = c.get('planning', {}).get('g2_content_type', '') == 'text' completed = ( c.get('assigned_to') or {}).get('state') == ASSIGNMENT_WORKFLOW_STATE.COMPLETED assigned_to = c.get('assigned_to') or {} user = None desk = None if assigned_to.get('coverage_provider'): item['assignees'].append( assigned_to['coverage_provider']['name']) if is_text and not completed: _enhance_assigned_provider(c, item, assigned_to) elif assigned_to.get('user'): user = assigned_to['user'] users.append(user) elif assigned_to.get('desk'): desk = assigned_to.get('desk') desks.append(desk) # Get abstract from related text item if coverage is 'complete' if is_text: if completed: results = list( archive_service.get_from_mongo( req=None, lookup={ 'assignment_id': ObjectId( c['assigned_to']['assignment_id']), 'state': { '$in': ['published', 'corrected'] }, 'pubstatus': 'usable', 'rewrite_of': None })) if len(results) > 0: item['published_archive_items'].append({ 'archive_text': get_first_paragraph_text( results[0].get('abstract')) or '', 'archive_slugline': results[0].get('slugline') or '' }) elif c.get('news_coverage_status', {}).get('qcode') == 'ncostat:int': if user: text_users.append({ 'user': user, 'note': (c.get('planning', {})).get( 'internal_note', '') if (c.get('planning', {})).get( 'internal_note', '') != item.get('internal_note') else None }) else: text_desks.append(desk) item['contacts'] = get_contacts_from_item(item) if resource_type == 'planning': enhance_coverage(item, item, users) else: for p in (item.get('plannings') or []): enhance_coverage(p, item, users) users = get_resource_service('users').find( where={'_id': { '$in': users }}) desks = get_resource_service('desks').find( where={'_id': { '$in': desks }}) for u in users: name = u.get( 'display_name', "{0} {1}".format(u.get('first_name'), u.get('last_name'))) item['assignees'].append(name) text_user = next( (_i for _i in text_users if _i['user'] == str(u.get('_id'))) or [], None) if text_user: item['text_assignees'].append( '{0} ({1})'.format(name, text_user.get('note')) if text_user.get('note') else '{0}'.format(name)) for d in desks: item['assignees'].append(d['name']) if str(d['_id']) in text_desks: item['text_assignees'].append(d['name']) set_item_place(item) item['description_text'] = item.get('description_text') or ( item.get('event') or {}).get('definition_short') item['slugline'] = item.get('slugline') or (item.get('event') or {}).get('name') # Handle dates and remote time-zones if item.get('dates') or (item.get('event') or {}).get('dates'): dates = item.get('dates') or item.get('event').get('dates') item['schedule'] = utc_to_local(config.DEFAULT_TIMEZONE, dates.get('start')) if get_timezone_offset(config.DEFAULT_TIMEZONE, utcnow()) !=\ get_timezone_offset(dates.get('tz'), utcnow()): item['schedule'] = "{} ({})".format( item['schedule'].strftime('%H%M'), item['schedule'].tzname()) else: item['schedule'] = item['schedule'].strftime('%H%M') agendas = [] if resource_type == 'planning': agendas = group_items_by_agenda(items) inject_internal_converages(items) labels = {} cv = get_resource_service('vocabularies').find_one( req=None, _id='g2_content_type') if cv: labels = {_type['qcode']: _type['name'] for _type in cv['items']} for item in items: item['coverages'] = [ labels.get( coverage.get('planning').get('g2_content_type'), coverage.get('planning').get('g2_content_type')) + (' (cancelled)' if coverage.get('workflow_status', '') == 'cancelled' else '') for coverage in item.get('coverages', []) if (coverage.get('planning') or {}).get('g2_content_type') ] article = {} for key, value in template.items(): if value.endswith(".html"): article[key.replace('_template', '')] = render_template(value, items=items, agendas=agendas) else: article[key] = render_template_string(value, items=items, agendas=agendas) return article
def get_utc_offset(self): return get_timezone_offset(app.config['DEFAULT_TIMEZONE'], utcnow())
def generate_text_item(items, template_name, resource_type): template = get_resource_service( 'planning_export_templates').get_export_template( template_name, resource_type) if not template: raise SuperdeskApiError.badRequestError('Invalid template selected') for item in items: # Create list of assignee with preference to coverage_provider, if not, assigned user item['published_archive_items'] = [] item['assignees'] = [] item['text_assignees'] = [] item['contacts'] = [] text_users = [] text_desks = [] users = [] desks = [] if item['type'] == 'planning': enhance_coverage(item, item, users, desks, text_users, text_desks) else: for p in (item.get('plannings') or []): enhance_coverage(p, item, users, desks, text_users, text_desks) users = get_resource_service('users').find( where={'_id': { '$in': users }}) desks = get_resource_service('desks').find( where={'_id': { '$in': desks }}) for u in users: name = u.get( 'display_name', "{0} {1}".format(u.get('first_name'), u.get('last_name'))) item['assignees'].append(name) text_user = next( (_i for _i in text_users if _i['user'] == str(u.get('_id'))) or [], None) if text_user: item['text_assignees'].append( '{0} ({1})'.format(name, text_user.get('note')) if text_user.get('note') else '{0}'.format(name)) for d in desks: item['assignees'].append(d['name']) if str(d['_id']) in text_desks: item['text_assignees'].append(d['name']) set_item_place(item) item['description_text'] = item.get('description_text') or ( item.get('event') or {}).get('definition_short') item['slugline'] = item.get('slugline') or (item.get('event') or {}).get('name') # Handle dates and remote time-zones if item.get('dates') or (item.get('event') or {}).get('dates'): dates = item.get('dates') or item.get('event').get('dates') item['schedule'] = utc_to_local(config.DEFAULT_TIMEZONE, dates.get('start')) if get_timezone_offset(config.DEFAULT_TIMEZONE, utcnow()) !=\ get_timezone_offset(dates.get('tz'), utcnow()): item['schedule'] = "{} ({})".format( item['schedule'].strftime('%H%M'), item['schedule'].tzname()) else: item['schedule'] = item['schedule'].strftime('%H%M') agendas = group_items_by_agenda(items) inject_internal_coverages(items) labels = {} cv = get_resource_service('vocabularies').find_one(req=None, _id='g2_content_type') if cv: labels = {_type['qcode']: _type['name'] for _type in cv['items']} for item in items: item['coverages'] = [ labels.get( (coverage.get('planning') or {}).get('g2_content_type'), (coverage.get('planning') or {}).get('g2_content_type')) + (' (cancelled)' if coverage.get('workflow_status', '') == 'cancelled' else '') for coverage in item.get('coverages', []) if (coverage.get('planning') or {}).get('g2_content_type') ] article = {} for key, value in template.items(): if value.endswith(".html"): article[key.replace('_template', '')] = render_template(value, items=items, agendas=agendas) else: article[key] = render_template_string(value, items=items, agendas=agendas) return article