def notify_new_coverage(self, agenda, wire_item): user_dict = get_user_dict() company_dict = get_company_dict() notify_user_ids = filter_active_users(agenda.get('watches', []), user_dict, company_dict, events_only=True) for user_id in notify_user_ids: user = user_dict[str(user_id)] send_coverage_notification_email(user, agenda, wire_item)
def notify_new_item(item, check_topics=True): if not item or item.get('type') == 'composite': return user_dict = get_user_dict() user_ids = [u['_id'] for u in user_dict.values()] company_dict = get_company_dict() company_ids = [c['_id'] for c in company_dict.values()] push_notification('new_item', item=item['_id']) if check_topics: if item.get('type') == 'text': notify_wire_topic_matches(item, user_dict, company_dict) else: notify_agenda_topic_matches(item, user_dict) notify_user_matches(item, user_dict, company_dict, user_ids, company_ids)
def notify_agenda_update(self, update, agenda, events_only=False): if agenda: user_dict = get_user_dict() company_dict = get_company_dict() notify_user_ids = filter_active_users(agenda.get('watches', []), user_dict, company_dict, events_only) users = [user_dict[str(user_id)] for user_id in notify_user_ids] for user in users: app.data.insert('notifications', [{ 'item': agenda['_id'], 'user': user['_id'] }]) send_agenda_notification_email( user, agenda, agenda_notifications[update]['message'], agenda_notifications[update]['subject'], ) push_notification('agenda_update', item=agenda, users=notify_user_ids)
def test_expired_company_does_not_restrict_activity(client, app): app.data.insert('companies', [{ '_id': '1', 'name': 'Company1', 'is_enabled': True }, { '_id': '2', 'name': 'Company2', 'is_enabled': False }, { '_id': '3', 'name': 'Company3', 'is_enabled': True, 'expiry_date': datetime.utcnow() - timedelta(days=1) }]) with app.test_request_context(): companies = get_company_dict() assert '1' in companies assert '2' not in companies assert '3' in companies
def notify_agenda_update(self, update_agenda, original_agenda, item=None, events_only=False, related_planning_removed=None, coverage_updated=None): agenda = deepcopy(update_agenda) if agenda and original_agenda.get('state') != WORKFLOW_STATE.KILLED: user_dict = get_user_dict() company_dict = get_company_dict() coverage_watched = None for c in (original_agenda.get('coverages') or []): if len(c.get('watches') or []) > 0: coverage_watched = True break notify_user_ids = filter_active_users(original_agenda.get('watches', []), user_dict, company_dict, events_only) users = [user_dict[str(user_id)] for user_id in notify_user_ids] # Only one push-notification push_notification('agenda_update', item=agenda, users=notify_user_ids) if len(notify_user_ids) == 0 and not coverage_watched: return def get_detailed_coverage(cov): plan = next((p for p in (agenda.get('planning_items') or []) if p['guid'] == cov.get('planning_id')), None) if plan and plan.get('state') != WORKFLOW_STATE.KILLED: detail_cov = next((c for c in (plan.get('coverages') or []) if c.get('coverage_id') == cov.get('coverage_id')), None) if detail_cov: detail_cov['watches'] = cov.get('watches') return detail_cov original_cov = next((c for c in original_agenda.get('coverages') if c['coverage_id'] == cov['coverage_id']), cov) cov['watches'] = original_cov.get('watches') or [] return cov def fill_all_coverages(skip_coverages=[], cancelled=False, use_original_agenda=False): fill_list = coverage_updates['unaltered_coverages'] if not cancelled else \ coverage_updates['cancelled_coverages'] for coverage in (agenda if not use_original_agenda else original_agenda).get('coverages') or []: if not next((s for s in skip_coverages if s.get('coverage_id') == coverage.get('coverage_id')), None): detailed_coverage = get_detailed_coverage(coverage) if detailed_coverage: fill_list.append(detailed_coverage) coverage_updates = { 'modified_coverages': [] if not coverage_updated else [coverage_updated], 'cancelled_coverages': [], 'unaltered_coverages': [] } only_new_coverages = len(coverage_updates['modified_coverages']) == 0 time_updated = False state_changed = False coverage_modified = False # Send notification for only these state changes notify_states = [WORKFLOW_STATE.CANCELLED, WORKFLOW_STATE.RESCHEDULED, WORKFLOW_STATE.POSTPONED, WORKFLOW_STATE.KILLED, WORKFLOW_STATE.SCHEDULED] if not coverage_updated: # If not story updates - but from planning side if not related_planning_removed: # Send notification if time got updated if original_agenda.get('dates') and agenda.get('dates'): time_updated = (original_agenda.get('dates') or {}).get('start').replace(tzinfo=None) != \ (agenda.get('dates') or {}).get('start').replace(tzinfo=None) or \ (original_agenda.get('dates') or {}).get('end').replace(tzinfo=None) != \ (agenda.get('dates') or {}).get('end').replace(tzinfo=None) if agenda.get('state') and agenda.get('state') != original_agenda.get('state'): state_changed = agenda.get('state') in notify_states if not state_changed: if time_updated: fill_all_coverages() else: for coverage in agenda.get('coverages') or []: existing_coverage = next((c for c in original_agenda.get('coverages') or [] if c['coverage_id'] == coverage['coverage_id']), None) detailed_coverage = get_detailed_coverage(coverage) if detailed_coverage: if not existing_coverage: if coverage['workflow_status'] != WORKFLOW_STATE.CANCELLED: coverage_updates['modified_coverages'].append(detailed_coverage) elif coverage.get('workflow_status') == WORKFLOW_STATE.CANCELLED and \ existing_coverage.get('workflow_status') != coverage.get('workflow_status'): coverage_updates['cancelled_coverages'].append(detailed_coverage) elif (coverage.get('delivery_state') != existing_coverage.get('delivery_state') and coverage.get('delivery_state') == 'published') or \ (coverage.get('workflow_status') != existing_coverage.get('workflow_status') and coverage.get('workflow_status') == 'completed') or \ (existing_coverage.get('scheduled') != coverage.get('scheduled')): coverage_updates['modified_coverages'].append(detailed_coverage) only_new_coverages = False elif detailed_coverage['coverage_id'] != \ (coverage_updated or {}).get('coverage_id'): coverage_updates['unaltered_coverages'].append(detailed_coverage) # Check for removed coverages - show it as cancelled if item and item.get('type') == 'planning': for original_cov in original_agenda.get('coverages') or []: updated_cov = next((c for c in (agenda.get('coverages') or []) if c.get('coverage_id') == original_cov.get('coverage_id')), None) if not updated_cov: coverage_updates['cancelled_coverages'].append(original_cov) else: fill_all_coverages(cancelled=False if agenda.get('state') == WORKFLOW_STATE.SCHEDULED else True, use_original_agenda=True) else: fill_all_coverages(related_planning_removed.get('coverages') or []) # Add removed coverages: for coverage in related_planning_removed.get('coverages') or []: detailed_coverage = get_detailed_coverage(coverage) if detailed_coverage: coverage_updates['cancelled_coverages'].append(detailed_coverage) if len(coverage_updates['modified_coverages']) > 0 or len(coverage_updates['cancelled_coverages']) > 0: coverage_modified = True if coverage_updated or related_planning_removed or time_updated or state_changed or coverage_modified: agenda['name'] = agenda.get('name', original_agenda.get('name')) agenda['definition_short'] = agenda.get('definition_short', original_agenda.get('definition_short')) agenda['ednote'] = agenda.get('ednote', original_agenda.get('ednote')) agenda['state_reason'] = agenda.get('state_reason', original_agenda.get('state_reason')) subject = '{} -{} updated'.format(agenda['name'] or agenda['headline'] or agenda['slugline'], ' Coverage' if coverage_modified else '') action = 'been updated.' if state_changed: action = 'been {}.'.format(agenda.get('state') if agenda.get('state') != WORKFLOW_STATE.KILLED else 'removed from the Agenda calendar') if len(coverage_updates['modified_coverages']) > 0 and only_new_coverages and \ len(coverage_updates['cancelled_coverages']) == 0: action = 'new coverage(s).' message = 'The {} you have been following has {}'.format( 'event' if agenda.get('event') else 'coverage plan', action ) if agenda.get('state_reason'): reason_prefix = agenda.get('state_reason').find(':') if reason_prefix > 0: message = '{} {}'.format( message, agenda['state_reason'][(reason_prefix+1):len(agenda['state_reason'])]) # append coverage watching users too - except for unaltered_coverages for c in coverage_updates['cancelled_coverages'] + coverage_updates['modified_coverages']: if c.get('watches'): notify_user_ids = filter_active_users(c['watches'], user_dict, company_dict, events_only) users = users + [user_dict[str(user_id)] for user_id in notify_user_ids] # Send notifications to users for user in users: app.data.insert('notifications', [{ 'item': agenda.get('_id'), 'user': user['_id'] }]) send_agenda_notification_email( user, agenda, message, subject, original_agenda, coverage_updates, related_planning_removed, coverage_updated, time_updated, )
def test_active_users_and_active_companies(client, app): app.data.insert('users', [ { '_id': '1', 'email': '*****@*****.**', 'last_name': 'bar1', 'first_name': 'foo1', 'user_type': 'public', 'is_approved': True, 'is_enabled': True, 'is_validated': True, 'company': '1' }, { '_id': '2', 'email': '*****@*****.**', 'last_name': 'bar2', 'first_name': 'foo2', 'user_type': 'public', 'is_approved': True, 'is_enabled': False, 'is_validated': True, 'company': '1' }, { '_id': '3', 'email': '*****@*****.**', 'last_name': 'bar3', 'first_name': 'foo3', 'user_type': 'administrator', 'is_approved': True, 'is_enabled': True, 'is_validated': True, 'company': '2' }, { '_id': '4', 'email': '*****@*****.**', 'last_name': 'bar4', 'first_name': 'foo4', 'user_type': 'administrator', 'is_approved': True, 'is_enabled': True, 'is_validated': True, 'company': '3' }, ]) app.data.insert('companies', [{ '_id': '1', 'name': 'Company1', 'is_enabled': True }, { '_id': '2', 'name': 'Company2', 'is_enabled': False }, { '_id': '3', 'name': 'Company3', 'is_enabled': True, 'expiry_date': datetime.utcnow() - timedelta(days=1) }]) with app.test_request_context(): users = get_user_dict() companies = get_company_dict() assert '1' in users assert '2' not in users assert '3' not in users assert '1' in companies assert '2' not in companies