def _get_assignable_dict(people, notif): """Get dict data for assignable object in notification. Args: people (List[Person]): List o people objects who should receive the notification. notif (Notification): Notification that should be sent. Returns: dict: dictionary containing notification data for all people in the given list. """ obj = get_notification_object(notif) data = {} for person in people: # We should default to today() if no start date is found on the object. start_date = getattr(obj, "start_date", datetime.date.today()) data[person.email] = { "user": get_person_dict(person), notif.notification_type.name: { obj.id: { "title": obj.title, "start_date_statement": utils.get_digest_date_statement(start_date, "start", True), "url": get_object_url(obj), "notif_created_at": { notif.id: as_user_time(notif.created_at) } } } } return data
def _get_assignable_dict(people, notif): """Get dict data for assignable object in notification. Args: people (List[Person]): List o people objects who should receive the notification. notif (Notification): Notification that should be sent. Returns: dict: dictionary containing notification data for all people in the given list. """ obj = get_notification_object(notif) data = {} for person in people: # Requests have "requested_on" field instead of "start_date" and we should # default to today() if no appropriate field is found on the object. start_date = getattr(obj, "start_date", getattr(obj, "requested_on", datetime.date.today())) data[person.email] = { "user": get_person_dict(person), notif.notification_type.name: { obj.id: { "title": obj.title, "start_date_statement": utils.get_digest_date_statement( start_date, "start", True), "url": get_object_url(obj), } } } return data
def get_cycle_start_failed_data(notification, workflow): if workflow.status != "Active": return {} if (not workflow.next_cycle_start_date or workflow.next_cycle_start_date >= date.today()): return {} # this can only be if the cycle has successfully started result = {} workflow_admins = get_workflow_admins_dict(workflow) force = workflow.notify_on_change for wf_admin in workflow_admins.itervalues(): result[wf_admin["email"]] = { "user": wf_admin, "force_notifications": { notification.id: force }, "cycle_start_failed": { workflow.id: { "workflow_url": get_workflow_url(workflow), "start_date": workflow.next_cycle_start_date, "start_date_statement": utils.get_digest_date_statement( workflow.next_cycle_start_date, "start", True), "custom_message": workflow.notify_custom_message, "title": workflow.title, } } } return result
def get_workflow_starts_in_data(notification, workflow): if workflow.status != "Active": return {} if (not workflow.next_cycle_start_date or workflow.next_cycle_start_date < date.today()): return {} # this can only be if the cycle has successfully started result = {} workflow_owners = get_workflow_owners_dict(workflow.context_id) force = workflow.notify_on_change for user_roles in workflow.context.user_roles: wf_person = user_roles.person result[wf_person.email] = { "user": data_handlers.get_person_dict(wf_person), "force_notifications": { notification.id: force }, "cycle_starts_in": { workflow.id: { "workflow_owners": workflow_owners, "workflow_url": get_workflow_url(workflow), "start_date": workflow.next_cycle_start_date, "start_date_statement": utils.get_digest_date_statement( workflow.next_cycle_start_date, "start", True), "custom_message": workflow.notify_custom_message, "title": workflow.title, } } } return result
def _get_assignable_dict(people, notif): """Get dict data for assignable object in notification. Args: people (List[Person]): List o people objects who should receive the notification. notif (Notification): Notification that should be sent. Returns: dict: dictionary containing notification data for all people in the given list. """ obj = get_notification_object(notif) data = {} for person in people: # We should default to today() if no start date is found on the object. start_date = getattr(obj, "start_date", datetime.date.today()) data[person.email] = { "user": get_person_dict(person), notif.notification_type.name: { obj.id: { "title": obj.title, "start_date_statement": utils.get_digest_date_statement( start_date, "start", True), "url": get_object_url(obj), "notif_created_at": as_user_time(notif.created_at) } } } return data
def get_workflow_starts_in_data(notification, workflow): """Get workflow data for which cycle has started.""" if workflow.status != "Active": return {} if (not workflow.next_cycle_start_date or workflow.next_cycle_start_date < date.today()): return {} # this can only be if the cycle has successfully started result = {} force = workflow.notify_on_change people_with_role = ( workflow.get_persons_for_rolename("Admin") + workflow.get_persons_for_rolename("Workflow Member")) for wf_person in people_with_role: result[wf_person.email] = { "user": data_handlers.get_person_dict(wf_person), "force_notifications": { notification.id: force }, "cycle_starts_in": { workflow.id: { "workflow_url": get_workflow_url(workflow), "start_date": workflow.next_cycle_start_date, "start_date_statement": utils.get_digest_date_statement( workflow.next_cycle_start_date, "start", True), "custom_message": workflow.notify_custom_message, "title": workflow.title, } } } return result
def get_cycle_start_failed_data(notification, workflow): if workflow.status != "Active": return {} if (not workflow.next_cycle_start_date or workflow.next_cycle_start_date >= date.today()): return {} # this can only be if the cycle has successfully started result = {} workflow_owners = get_workflow_owners_dict(workflow.context_id) force = workflow.notify_on_change for wf_owner in workflow_owners.itervalues(): result[wf_owner["email"]] = { "user": wf_owner, "force_notifications": { notification.id: force }, "cycle_start_failed": { workflow.id: { "workflow_owners": workflow_owners, "workflow_url": get_workflow_url(workflow), "start_date": workflow.next_cycle_start_date, "start_date_statement": utils.get_digest_date_statement( workflow.next_cycle_start_date, "start", True), "custom_message": workflow.notify_custom_message, "title": workflow.title, } } } return result
def get_workflow_starts_in_data(notification, workflow): if workflow.status != "Active": return {} if (not workflow.next_cycle_start_date or workflow.next_cycle_start_date < date.today()): return {} # this can only be if the cycle has successfully started result = {} force = workflow.notify_on_change people_with_role = (workflow.get_persons_for_rolename("Admin") + workflow.get_persons_for_rolename("Workflow Member")) for wf_person in people_with_role: result[wf_person.email] = { "user": data_handlers.get_person_dict(wf_person), "force_notifications": { notification.id: force }, "cycle_starts_in": { workflow.id: { "workflow_url": get_workflow_url(workflow), "start_date": workflow.next_cycle_start_date, "start_date_statement": utils.get_digest_date_statement( workflow.next_cycle_start_date, "start", True), "custom_message": workflow.notify_custom_message, "title": workflow.title, } } } return result
def get_cycle_task_dict(cycle_task, del_rels_cache=None): object_titles = [] # every object should have a title or at least a name like person object for related_object in cycle_task.related_objects(): if related_object.type in ("CycleTaskGroup", "CycleTaskEntry"): # We can skip cycle task groups in notifications because they are # irrelevant for the completion of a given cycle task. continue object_titles.append( getattr(related_object, "title", "") or getattr(related_object, "name", "") or u"Untitled object") # related objects might have been deleted or unmapped, # check the revision history if del_rels_cache is not None: deleted_relationships = del_rels_cache.get(cycle_task.id, []) else: deleted_relationships_sources = db.session.query(Revision).filter( Revision.resource_type == "Relationship", Revision.action == "deleted", Revision.source_type == "CycleTaskGroupObjectTask", Revision.source_id == cycle_task.id) deleted_relationships_destinations = db.session.query(Revision).filter( Revision.resource_type == "Relationship", Revision.action == "deleted", Revision.destination_type == "CycleTaskGroupObjectTask", Revision.destination_id == cycle_task.id) deleted_relationships = deleted_relationships_sources.union( deleted_relationships_destinations).all() for deleted_relationship in deleted_relationships: removed_object_type, removed_object_id = _get_object_info_from_revision( deleted_relationship, "CycleTaskGroupObjectTask") object_data = db.session.query(Revision).filter( Revision.resource_type == removed_object_type, Revision.resource_id == removed_object_id, ).order_by(Revision.id.desc()).first() if object_data: object_titles.append(u"{} [removed from task]".format( object_data.content["display_name"])) else: logger.warning( "Unmapped %s id %s from CycleTask id %s has no revisions logged. ", removed_object_type, removed_object_id, cycle_task.id) return { "title": cycle_task.title, "related_objects": object_titles, "end_date": cycle_task.end_date.strftime("%m/%d/%Y"), "due_date_statement": utils.get_digest_date_statement(cycle_task.end_date, "due"), "cycle_task_url": get_cycle_task_url(), }
def get_cycle_task_dict(cycle_task, del_rels_cache=None): object_titles = [] # every object should have a title or at least a name like person object for related_object in cycle_task.related_objects: object_titles.append( getattr(related_object, "title", "") or getattr(related_object, "name", "") or u"Untitled object") # related objects might have been deleted or unmapped, # check the revision history if del_rels_cache is not None: deleted_relationships = del_rels_cache.get(cycle_task.id, []) else: deleted_relationships_sources = db.session.query(Revision).filter( Revision.resource_type == "Relationship", Revision.action == "deleted", Revision.source_type == "CycleTaskGroupObjectTask", Revision.source_id == cycle_task.id) deleted_relationships_destinations = db.session.query(Revision).filter( Revision.resource_type == "Relationship", Revision.action == "deleted", Revision.destination_type == "CycleTaskGroupObjectTask", Revision.destination_id == cycle_task.id) deleted_relationships = deleted_relationships_sources.union( deleted_relationships_destinations).all() for deleted_relationship in deleted_relationships: removed_object_type, removed_object_id = _get_object_info_from_revision( deleted_relationship, "CycleTaskGroupObjectTask") object_data = db.session.query(Revision).filter( Revision.resource_type == removed_object_type, Revision.resource_id == removed_object_id, ).order_by(Revision.id.desc()).first() object_titles.append(u"{} [removed from task]".format( object_data.content["display_name"])) # the filter expression to be included in the cycle task's URL and # automatically applied when user visits it filter_exp = u"id=" + unicode(cycle_task.cycle_id) return { "title": cycle_task.title, "related_objects": object_titles, "end_date": cycle_task.end_date.strftime("%m/%d/%Y"), "due_date_statement": utils.get_digest_date_statement(cycle_task.end_date, "due"), "cycle_task_url": get_cycle_task_url(cycle_task, filter_exp=filter_exp), }
def get_cycle_task_dict(cycle_task, del_rels_cache=None): object_titles = [] # every object should have a title or at least a name like person object for related_object in cycle_task.related_objects: object_titles.append(getattr(related_object, "title", "") or getattr(related_object, "name", "") or u"Untitled object") # related objects might have been deleted or unmapped, # check the revision history if del_rels_cache is not None: deleted_relationships = del_rels_cache.get(cycle_task.id, []) else: deleted_relationships_sources = db.session.query(Revision).filter( Revision.resource_type == "Relationship", Revision.action == "deleted", Revision.source_type == "CycleTaskGroupObjectTask", Revision.source_id == cycle_task.id ) deleted_relationships_destinations = db.session.query(Revision).filter( Revision.resource_type == "Relationship", Revision.action == "deleted", Revision.destination_type == "CycleTaskGroupObjectTask", Revision.destination_id == cycle_task.id ) deleted_relationships = deleted_relationships_sources.union( deleted_relationships_destinations).all() for deleted_relationship in deleted_relationships: removed_object_type, removed_object_id = _get_object_info_from_revision( deleted_relationship, "CycleTaskGroupObjectTask") object_data = db.session.query(Revision).filter( Revision.resource_type == removed_object_type, Revision.resource_id == removed_object_id, ).order_by(Revision.id.desc()).first() object_titles.append( u"{} [removed from task]".format(object_data.content["display_name"]) ) # the filter expression to be included in the cycle task's URL and # automatically applied when user visits it filter_exp = u"id=" + unicode(cycle_task.cycle_id) return { "title": cycle_task.title, "related_objects": object_titles, "end_date": cycle_task.end_date.strftime("%m/%d/%Y"), "due_date_statement": utils.get_digest_date_statement( cycle_task.end_date, "due"), "cycle_task_url": get_cycle_task_url(cycle_task, filter_exp=filter_exp), }
def get_cycle_task_dict(cycle_task, del_rels_cache=None): object_titles = [] # every object should have a title or at least a name like person object for related_object in cycle_task.related_objects(): if related_object.type in ("CycleTaskGroup", "CycleTaskEntry"): # We can skip cycle task groups in notifications because they are # irrelevant for the completion of a given cycle task. continue object_titles.append(getattr(related_object, "title", "") or getattr(related_object, "name", "") or u"Untitled object") # related objects might have been deleted or unmapped, # check the revision history if del_rels_cache is not None: deleted_relationships = del_rels_cache.get(cycle_task.id, []) else: deleted_relationships_sources = db.session.query(Revision).filter( Revision.resource_type == "Relationship", Revision.action == "deleted", Revision.source_type == "CycleTaskGroupObjectTask", Revision.source_id == cycle_task.id ) deleted_relationships_destinations = db.session.query(Revision).filter( Revision.resource_type == "Relationship", Revision.action == "deleted", Revision.destination_type == "CycleTaskGroupObjectTask", Revision.destination_id == cycle_task.id ) deleted_relationships = deleted_relationships_sources.union( deleted_relationships_destinations).all() for deleted_relationship in deleted_relationships: removed_object_type, removed_object_id = _get_object_info_from_revision( deleted_relationship, "CycleTaskGroupObjectTask") object_data = db.session.query(Revision).filter( Revision.resource_type == removed_object_type, Revision.resource_id == removed_object_id, ).order_by(Revision.id.desc()).first() object_titles.append( u"{} [removed from task]".format(object_data.content["display_name"]) ) return { "title": cycle_task.title, "related_objects": object_titles, "end_date": cycle_task.end_date.strftime("%m/%d/%Y"), "due_date_statement": utils.get_digest_date_statement( cycle_task.end_date, "due"), "cycle_task_url": get_cycle_task_url(), }
def get_cycle_task_dict(cycle_task, del_rels_cache=None, with_related=True): """Get dict representation for cycle task.""" if not with_related: object_titles = [] else: object_titles = get_cycle_task_related_objects(cycle_task) # related objects might have been deleted or unmapped, # check the revision history if del_rels_cache is not None: deleted_relationships = del_rels_cache.get(cycle_task.id, []) else: deleted_relationships_sources = db.session.query(Revision).filter( Revision.resource_type == "Relationship", Revision.action == "deleted", Revision.source_type == "CycleTaskGroupObjectTask", Revision.source_id == cycle_task.id) deleted_relationships_destinations = db.session.query(Revision).filter( Revision.resource_type == "Relationship", Revision.action == "deleted", Revision.destination_type == "CycleTaskGroupObjectTask", Revision.destination_id == cycle_task.id) deleted_relationships = deleted_relationships_sources.union( deleted_relationships_destinations).all() for deleted_relationship in deleted_relationships: removed_object_type, removed_object_id = _get_object_info_from_revision( deleted_relationship, "CycleTaskGroupObjectTask") object_data = db.session.query(Revision).filter( Revision.resource_type == removed_object_type, Revision.resource_id == removed_object_id, ).order_by(Revision.id.desc()).first() if object_data: object_titles.append(u"{} [removed from task]".format( object_data.content["display_name"])) else: logger.warning( "Unmapped %s id %s from CycleTask id %s has no revisions logged. ", removed_object_type, removed_object_id, cycle_task.id) return { "title": cycle_task.title, "related_objects": object_titles, "end_date": cycle_task.end_date.strftime("%m/%d/%Y"), "due_date_statement": utils.get_digest_date_statement(cycle_task.end_date, "due"), "cycle_task_url": get_cycle_tasks_url_by_slug(cycle_task.slug), }
def _get_assignable_dict(people, notif, ca_cache=None): """Get dict data for assignable object in notification. Args: people (List[Person]): List o people objects who should receive the notification. notif (Notification): Notification that should be sent. ca_cache (dict): prefetched CustomAttributeDefinition instances accessible by definition_type as a key Returns: dict: dictionary containing notification data for all people in the given list. """ obj = get_notification_object(notif) data = {} # we do not use definitions data if notification name not assessment update if notif.notification_type.name == "assessment_updated": definitions = AttributeInfo.get_object_attr_definitions( obj.__class__, ca_cache=ca_cache) else: definitions = None roles = _get_assignable_roles(obj) for person in people: # We should default to today() if no start date is found on the object. start_date = getattr(obj, "start_date", datetime.date.today()) data[person.email] = { "user": get_person_dict(person), notif.notification_type.name: { obj.id: { "title": obj.title, "start_date_statement": utils.get_digest_date_statement(start_date, "start", True), "url": get_object_url(obj), "notif_created_at": { notif.id: as_user_time(notif.created_at) }, "notif_updated_at": { notif.id: as_user_time(notif.updated_at) }, "updated_data": _get_updated_fields(obj, notif.created_at, definitions, roles) if notif.notification_type.name == "assessment_updated" else None, } } } return data
def get_cycle_task_dict(cycle_task, del_rels_cache=None): """Get dict representation for cycle task.""" object_titles = get_cycle_task_related_objects(cycle_task) # related objects might have been deleted or unmapped, # check the revision history if del_rels_cache is not None: deleted_relationships = del_rels_cache.get(cycle_task.id, []) else: deleted_relationships_sources = db.session.query(Revision).filter( Revision.resource_type == "Relationship", Revision.action == "deleted", Revision.source_type == "CycleTaskGroupObjectTask", Revision.source_id == cycle_task.id ) deleted_relationships_destinations = db.session.query(Revision).filter( Revision.resource_type == "Relationship", Revision.action == "deleted", Revision.destination_type == "CycleTaskGroupObjectTask", Revision.destination_id == cycle_task.id ) deleted_relationships = deleted_relationships_sources.union( deleted_relationships_destinations).all() for deleted_relationship in deleted_relationships: removed_object_type, removed_object_id = _get_object_info_from_revision( deleted_relationship, "CycleTaskGroupObjectTask") object_data = db.session.query(Revision).filter( Revision.resource_type == removed_object_type, Revision.resource_id == removed_object_id, ).order_by(Revision.id.desc()).first() if object_data: object_titles.append( u"{} [removed from task]".format(object_data.content["display_name"]) ) else: logger.warning( "Unmapped %s id %s from CycleTask id %s has no revisions logged. ", removed_object_type, removed_object_id, cycle_task.id ) return { "title": cycle_task.title, "related_objects": object_titles, "end_date": cycle_task.end_date.strftime("%m/%d/%Y"), "due_date_statement": utils.get_digest_date_statement( cycle_task.end_date, "due"), "cycle_task_url": get_cycle_task_url(), }
def _get_assignable_dict(people, notif): """Get dict data for assignable object in notification. Args: people (List[Person]): List o people objects who should receive the notification. notif (Notification): Notification that should be sent. Returns: dict: dictionary containing notification data for all people in the given list. """ obj = get_notification_object(notif) data = {} definitions = AttributeInfo.get_object_attr_definitions(obj.__class__) roles = _get_assignable_roles(obj) for person in people: # We should default to today() if no start date is found on the object. start_date = getattr(obj, "start_date", datetime.date.today()) data[person.email] = { "user": get_person_dict(person), notif.notification_type.name: { obj.id: { "title": obj.title, "start_date_statement": utils.get_digest_date_statement( start_date, "start", True), "url": get_object_url(obj), "notif_created_at": { notif.id: as_user_time(notif.created_at)}, "notif_updated_at": { notif.id: as_user_time(notif.updated_at)}, "updated_fields": _get_updated_fields(obj, notif.created_at, definitions, roles) if notif.notification_type.name == "assessment_updated" else None, } } } return data