コード例 #1
0
def update(*, db_session, task: Task, task_in: TaskUpdate) -> Task:
    """Update an existing task."""
    # ensure we add assignee as participant if they are not one already
    assignees = []
    for i in task_in.assignees:
        assignees.append(
            incident_flows.incident_add_or_reactivate_participant_flow(
                db_session=db_session,
                incident_id=task.incident.id,
                user_email=i.individual.email,
            )
        )

    task.assignees = assignees

    # we add owner as a participant if they are not one already
    if task_in.owner:
        task.owner = incident_flows.incident_add_or_reactivate_participant_flow(
            db_session=db_session,
            incident_id=task.incident.id,
            user_email=task_in.owner.individual.email,
        )

    update_data = task_in.dict(
        skip_defaults=True, exclude={"assignees", "owner", "creator", "incident", "tickets"}
    )

    for field in update_data.keys():
        setattr(task, field, update_data[field])

    db_session.add(task)
    db_session.commit()
    return task
コード例 #2
0
ファイル: service.py プロジェクト: weiplanet/dispatch
def update(*,
           db_session,
           task: Task,
           task_in: TaskUpdate,
           sync_external: bool = True) -> Task:
    """Update an existing task."""
    # ensure we add assignee as participant if they are not one already
    assignees = []
    for i in task_in.assignees:
        assignees.append(
            incident_flows.incident_add_or_reactivate_participant_flow(
                db_session=db_session,
                incident_id=task.incident.id,
                user_email=i.individual.email,
            ))

    task.assignees = assignees

    # we add owner as a participant if they are not one already
    if task_in.owner:
        # don't reactive participants if the tasks is already resolved
        if task_in.status != TaskStatus.resolved:
            task.owner = incident_flows.incident_add_or_reactivate_participant_flow(
                db_session=db_session,
                incident_id=task.incident.id,
                user_email=task_in.owner.individual.email,
            )

    update_data = task_in.dict(
        skip_defaults=True,
        exclude={"assignees", "owner", "creator", "incident", "tickets"})

    for field in update_data.keys():
        setattr(task, field, update_data[field])

    # if we have an external task plugin enabled, attempt to update the external resource as well
    # we don't currently have a good way to get the correct file_id (we don't store a task <-> relationship)
    # lets try in both the incident doc and PIR doc
    drive_task_plugin = plugin_service.get_active(db_session=db_session,
                                                  plugin_type="task")

    if drive_task_plugin:
        if sync_external:
            try:
                if task.incident.incident_document:
                    file_id = task.incident.incident_document.resource_id
                    drive_task_plugin.instance.update(file_id,
                                                      task.resource_id,
                                                      resolved=task.status)
            except Exception:
                if task.incident.incident_review_document:
                    file_id = task.incident.incident_review_document.resource_id
                    drive_task_plugin.instance.update(file_id,
                                                      task.resource_id,
                                                      resolved=task.status)

    db_session.add(task)
    db_session.commit()
    return task
コード例 #3
0
ファイル: events.py プロジェクト: vj-codes/dispatch
def member_joined_channel(
    user_email: str,
    incident_id: int,
    event: EventEnvelope,
    db_session=None,
):
    """Handles the member_joined_channel slack event."""
    participant = incident_flows.incident_add_or_reactivate_participant_flow(
        user_email=user_email, incident_id=incident_id, db_session=db_session)

    if event.event.inviter:
        # we update the participant's metadata
        if not dispatch_slack_service.is_user(event.event.inviter):
            # we default to the incident commander when we don't know how the user was added
            added_by_participant = participant_service.get_by_incident_id_and_role(
                db_session=db_session,
                incident_id=incident_id,
                role=ParticipantRoleType.incident_commander,
            )
            participant.added_by = added_by_participant
            participant.added_reason = (
                f"Participant added by {added_by_participant.individual.name}")

        else:
            inviter_email = get_user_email(client=slack_client,
                                           user_id=event.event.inviter)
            added_by_participant = participant_service.get_by_incident_id_and_email(
                db_session=db_session,
                incident_id=incident_id,
                email=inviter_email)
            participant.added_by = added_by_participant
            participant.added_reason = event.event.text

        db_session.add(participant)
        db_session.commit()
コード例 #4
0
def member_joined_channel(
    user_email: str,
    incident_id: int,
    event: EventEnvelope,
    db_session=None,
):
    """Handles the member_joined_channel slack event."""
    participant = incident_flows.incident_add_or_reactivate_participant_flow(
        user_email=user_email, incident_id=incident_id, db_session=db_session)

    # update participant metadata
    inviter_email = get_user_email(client=slack_client,
                                   user_id=event.event.inviter)
    added_by_participant = participant_service.get_by_incident_id_and_email(
        db_session=db_session, incident_id=incident_id, email=inviter_email)

    # default to IC when we don't know how the user was added
    if not added_by_participant:
        participant.added_by = participant_service.get_by_incident_id_and_role(
            db_session=db_session,
            incident_id=incident_id,
            role=ParticipantRoleType.incident_commander,
        )
        participant.added_reason = "User was automatically added by Dispatch."

    else:
        participant.added_by = added_by_participant
        participant.added_reason = event.event.text

    db_session.commit()
コード例 #5
0
def member_joined_channel(
    user_email: str,
    incident_id: int,
    event: EventEnvelope,
    db_session=None,
):
    """Handles the member_joined_channel slack event."""
    participant = incident_flows.incident_add_or_reactivate_participant_flow(
        user_email=user_email, incident_id=incident_id, db_session=db_session)

    # update participant metadata
    inviter_email = get_user_email(client=slack_client,
                                   user_id=event.event.inviter)
    added_by_participant = participant_service.get_by_incident_id_and_email(
        db_session=db_session, incident_id=incident_id, email=inviter_email)
    participant.added_by = added_by_participant
    participant.added_reason = event.event.text

    db_session.commit()
コード例 #6
0
def create(*, db_session, task_in: TaskCreate) -> Task:
    """Create a new task."""
    incident = incident_service.get(db_session=db_session,
                                    incident_id=task_in.incident.id)
    tickets = [
        ticket_service.get_or_create_by_weblink(db_session=db_session,
                                                weblink=t.weblink,
                                                resource_type="task-ticket")
        for t in task_in.tickets
    ]

    assignees = []
    for i in task_in.assignees:
        assignee = incident_flows.incident_add_or_reactivate_participant_flow(
            db_session=db_session,
            incident_id=incident.id,
            user_email=i.individual.email,
        )

        # due to the freeform nature of task assignment, we can sometimes pick up other emails
        # e.g. a google group that we cannot resolve to an individual assignee
        if assignee:
            assignees.append(assignee)

    creator_email = None
    if not task_in.creator:
        creator_email = task_in.owner.individual.email
    else:
        creator_email = task_in.creator.individual.email

    # add creator as a participant if they are not one already
    creator = incident_flows.incident_add_or_reactivate_participant_flow(
        db_session=db_session,
        incident_id=incident.id,
        user_email=creator_email,
    )

    # if we cannot find any assignees, the creator becomes the default assignee
    if not assignees:
        assignees.append(creator)

    # we add owner as a participant if they are not one already
    if task_in.owner:
        owner = incident_flows.incident_add_or_reactivate_participant_flow(
            db_session=db_session,
            incident_id=incident.id,
            user_email=task_in.owner.individual.email,
        )
    else:
        owner = incident.commander

    task = Task(
        **task_in.dict(
            exclude={"assignees", "owner", "incident", "creator", "tickets"}),
        creator=creator,
        owner=owner,
        assignees=assignees,
        incident=incident,
        tickets=tickets,
    )

    event_service.log(
        db_session=db_session,
        source="Dispatch Core App",
        description="New incident task created",
        details={"weblink": task.weblink},
        incident_id=incident.id,
    )

    db_session.add(task)
    db_session.commit()
    return task
コード例 #7
0
def create_or_update_task(db_session,
                          incident,
                          task: dict,
                          notify: bool = False):
    """Creates a new task in the database or updates an existing one."""
    incident_task = task_service.get_by_resource_id(db_session=db_session,
                                                    resource_id=task["id"])

    assignees = []
    for a in task["assignees"]:
        assignees.append(
            db_session.merge(
                incident_add_or_reactivate_participant_flow(
                    a, incident_id=incident.id, db_session=db_session)))

    description = task["description"][0]
    status = TaskStatus.open if not task["status"] else TaskStatus.resolved
    resource_id = task["id"]
    weblink = task["web_link"]

    # TODO we can build this out as our scraping gets more advanced
    tickets = [
        ticket_service.get_or_create_by_weblink(db_session=db_session,
                                                weblink=t["web_link"])
        for t in task["tickets"]
    ]

    if incident_task:
        # allways update tickets and assignees
        incident_task.assignees = assignees
        incident_task.tickets = tickets

        # only notify if it's newly resolved
        if status == TaskStatus.resolved:
            if incident_task.status != TaskStatus.resolved:
                incident_task.status = status

                if notify:
                    send_task_notification(
                        incident.conversation.channel_id,
                        INCIDENT_TASK_RESOLVED_NOTIFICATION,
                        assignees,
                        description,
                        weblink,
                    )

    else:
        # we add the task to the incident
        creator = db_session.merge(
            incident_add_or_reactivate_participant_flow(
                task["owner"], incident_id=incident.id, db_session=db_session))

        task = task_service.create(
            db_session=db_session,
            creator=creator,
            assignees=assignees,
            description=description,
            status=status,
            tickets=tickets,
            resource_id=resource_id,
            resource_type=INCIDENT_RESOURCE_INCIDENT_TASK,
            weblink=weblink,
        )
        incident.tasks.append(task)

        if notify:
            send_task_notification(
                incident.conversation.channel_id,
                INCIDENT_TASK_NEW_NOTIFICATION,
                assignees,
                description,
                weblink,
            )

    db_session.commit()