Exemplo n.º 1
0
def project_pre_delete(sender, document, *args, **kwargs):
    """
    Delete related documents when a User is deleted
    :param sender: Class
    :param document: Project Object
    :return: Nothing
    """
    # delete sprints
    Sprint.objects(project=document).delete()
    # delete members
    ProjectMember.objects(project=document).delete()
    # delete tickets
    Ticket.objects(project=document).delete()
    # delete columns
    Column.objects(project=document).delete()
Exemplo n.º 2
0
    def post(self, project_pk, column):
        """
        Order Tickets in Columns
        :param project_pk: Project ID
        :param column: Column ID
        :return: Order
        """
        data = request.get_json(silent=True)

        if not data:
            raise api_errors.InvalidAPIUsage(api_errors.INVALID_JSON_BODY_MSG)

        project = get_project_request(project_pk)

        col = Column.get_by_id(column)
        if not col:
            raise api_errors.MissingResource(api_errors.INVALID_COLUMN_MSG)

        if project.project_type == 'S':
            sprint = get_sprint_request(data.get('sprint'))
            TicketCT.order_items(data.get('order'), sprint=sprint)
        else:
            TicketCT.order_items(data.get('order'))

        # save activity
        save_notification(project_pk=project_pk,
                          verb='ticket_column_order',
                          data=data)
        return data, 200
Exemplo n.º 3
0
 def get(self, project_pk):
     """
     :param project_pk: Project ID
     :return: List of columns
     """
     prj = get_project_request(project_pk)
     return Column.get_by_project(prj), 200
Exemplo n.º 4
0
    def get(self, project_pk, column_pk):
        """
        Get Column Instance

        :param project_pk: Project that belongs
        :param column_pk: Id of the column
        :return: Object Column
        """
        get_project_request(project_pk)
        return Column.get_by_id(column_pk)
Exemplo n.º 5
0
    def post(self, project_pk):
        """
        Update order of columns

        :param project_pk: project id
        :return: same data sent
        """
        prj = get_project_request(project_pk)

        data = request.get_json(silent=True)
        if not data:
            raise api_errors.InvalidAPIUsage(
                api_errors.INVALID_JSON_BODY_MSG
            )

        Column.order_items(data)

        # save activity
        save_notification(project_pk=prj.id,
                          verb='order_columns',
                          data=data)
        return data, 200
Exemplo n.º 6
0
    def put(self, project_pk, column_pk):
        """
        Update a column instance

        :param project_pk: Project that belongs
        :param column_pk: Id of the column
        :return: The updated resource
        """

        col = Column.get_by_id(column_pk)
        if not col:
            raise api_errors.MissingResource(
                api_errors.INVALID_COLUMN_MSG
            )

        data = request.get_json(silent=True)

        if not data:
            raise api_errors.InvalidAPIUsage(
                api_errors.INVALID_JSON_BODY_MSG
            )

        col.title = data.get('title')
        col.color_max_cards = data.get('color_max_cards', '#FF0000')
        col.done_column = data.get('done_column', False)
        col.max_cards = data.get('max_cards', 9999)

        # check set other columns of the project to done_column in False
        if col.done_column:
            Column.clear_done_columns(project_pk)
        col.save()

        # save activity
        save_notification(project_pk=project_pk,
                          verb='update_column',
                          data=col.to_dict())

        return col, 200
Exemplo n.º 7
0
    def post(self):
        """
        Create Project
        """
        data = request.get_json(silent=True)
        if not data:
            raise api_errors.InvalidAPIUsage(
                api_errors.INVALID_JSON_BODY_MSG
            )

        prj = Project(name=data.get('name'),
                      owner=g.user.to_dbref())
        prj.active = data.get('active')
        prj.private = data.get('private')
        prj.prefix = data.get('prefix', data.get('name')[:3].upper())
        prj.description = data.get('description')
        prj.project_type = data.get('project_type', 'S')

        # Add initial config
        prj.sprint_duration = 15
        prj.save()

        # add owner as member
        pm = ProjectMember(project=prj)
        pm.member = prj.owner
        pm.is_owner = True
        pm.save()

        # Add 3 columns states
        col_names = ['ToDo', 'In Progress', 'Done']
        for index, c in enumerate(col_names):
            col = Column()
            col.title = c
            col.project = prj
            if index == len(col_names) - 1:
                col.done_column = True
            col.save()

        # save activity
        save_notification(project_pk=prj.pk,
                          verb='new_project',
                          data=prj.to_dict())

        return prj, 201
Exemplo n.º 8
0
    def get(self, project_pk, sprint_id):
        """
        Get tickets fro a Sprint
        :param project_pk: Project ID
        :param sprint_id: Sprint ID
        :return: List of Tickets
        """

        prj = get_project_request(project_pk)
        sprint = get_sprint_request(sprint_id)

        # first get all the columns
        ticket_list = []
        columns = Column.get_by_project(prj)

        if columns:
            ticket_transitions = TicketCT.get_transitions_in_cols(columns)
            tickets_in_cols = []
            for tt in ticket_transitions:
                tickets_in_cols.append(tt.ticket)

            # exclude from sprint
            tickets = SprintTicketOrder.list_spo(sprint, tickets_in_cols)

            for t in tickets:
                if t.ticket.__class__.__name__ != 'DBRef':
                    tkt = t.ticket_repr
                    tkt['order'] = t.order
                    tkt['badges'] = {
                        'comments': Comment.get_by_ticket(t.ticket).count(),
                        'files': len(t.ticket.files)
                    }
                    assignments = []
                    for ass in t.ticket.assigned_to:
                        if ass.__class__.__name__ != 'DBRef':
                            val = ass.to_dict()
                            val['member'] = ass.member.to_dict()
                            assignments.append(val)
                    tkt['assigned_to'] = assignments
                    ticket_list.append(tkt)
        return ticket_list, 200
Exemplo n.º 9
0
    def delete(self, project_pk, column_pk):
        """
        Delete a column resource

        :param project_pk: Project that belongs
        :param column_pk:Id of the column
        :return: Nothing
        """
        prj = get_project_request(project_pk)
        col = Column.get_by_id(column_pk)
        if not col:
            raise api_errors.MissingResource(
                api_errors.INVALID_COLUMN_MSG
            )
        # save activity
        save_notification(project_pk=prj.id,
                          verb='delete_column',
                          data=col.to_dict())

        col.delete()
        return {}, 204
Exemplo n.º 10
0
    def get(self, project_pk):
        """
        Get Tickets for backlog board

        :param project_pk: Project ID
        :return: List of tickets
        """
        tickets = []
        col_ids = []

        prj = get_project_request(project_pk)

        column_list = Column.get_by_project(prj)
        for c in column_list:
            col_ids.append(str(c.pk))

        tct_list = TicketCT.get_transitions_in_cols(col_ids)
        for t in tct_list:
            tickets.append(str(t.ticket.pk))

        results = Ticket.get_tickets_backlog(prj, not_tickets=tickets)
        return results, 200
Exemplo n.º 11
0
    def post(self, project_pk):
        """
        Move Ticket to Column or Backlog
        :param project_pk: Project ID
        :return: Ticket Transition
        """
        project = get_project_request(project_pk)

        data = request.get_json(silent=True)
        if not data:
            raise api_errors.InvalidAPIUsage(api_errors.INVALID_JSON_BODY_MSG)

        tkt = get_ticket_request(data.get('ticket'))

        result = {}
        if data.get('backlog'):
            latest_tran = TicketCT.get_latest_transition(tkt)
            if latest_tran:
                latest_tran.latest_state = False
                latest_tran.save()

            SprintTicketOrder.order_items(data.get('order'),
                                          data.get('backlog'))
            # save activity
            save_notification(project_pk=project_pk,
                              verb='ticket_transition',
                              data=data)

            result = latest_tran.to_json(), 200

        else:
            # Search already state
            col = Column.get_by_id(data.get('column'))

            if not col:
                raise api_errors.MissingResource(api_errors.INVALID_COLUMN_MSG)

            user = User.get_by_id(current_user.id)
            if not user:
                raise api_errors.MissingResource(
                    api_errors.INVALID_USER_ID_MSG)

            transition = TicketCT()
            transition.ticket = tkt
            transition.column = col
            transition.order = TicketCT.get_next_order_index(col)

            if project.project_type == 'S':
                sprint = get_sprint_request(data.get('sprint'))
                latest_tran = TicketCT.get_latest_transition(tkt, sprint)

                transition.sprint = sprint
            else:
                latest_tran = TicketCT.get_latest_transition(tkt)

            if latest_tran:
                latest_tran.latest_state = False
                latest_tran.save()

            transition.latest_state = True
            transition.who = user
            transition.save()

            if project.project_type == 'S':
                sprint = get_sprint_request(data.get('sprint'))
                TicketCT.order_items(data.get('order'),
                                     sprint=sprint,
                                     column=col)
            else:
                TicketCT.order_items(data.get('order'), column=col)

            # save activity
            save_notification(project_pk=project_pk,
                              verb='ticket_transition',
                              data=transition.to_dict())

            result = transition.to_json(), 201
        return result
Exemplo n.º 12
0
class ProjectImport(AuthResource):
    """
    Import Data Project
    """

    def post(self, project_pk):
        """
        Import cards and columns

        :param project_pk: Project ID
        :return: List of Tickets and Columns imported
        """
        project = get_project_request(project_pk)
        try:
            body = json.loads(request.form.get('data'))
        except ValueError, e:
            raise api_errors.InvalidAPIUsage(
                api_errors.INVALID_JSON_BODY_MSG
            )

        imported_file = request.files.get('file')

        if not imported_file:
            raise api_errors.InvalidAPIUsage(
                api_errors.REQUIRED_MSG
            )

        data = json.loads(imported_file.stream.read().decode('utf-8'),
                          encoding='UTF-8')

        import_args = body.get('data')
        tickets = []
        last_ticket = Ticket.get_last_ticket(project_pk)
        starting_number = last_ticket.number if last_ticket else 1
        amazon_url = 'https://trello-attachments.s3.amazonaws.com/'

        if import_args.get('include_cards'):
            for card in data.get('cards'):
                t = Ticket()
                t.title = card.get('name')
                t.description = card.get('desc')
                t.labels = [l.get('name') for l in card.get('labels')]
                t.closed = card.get('closed')

                for att in card.get('attachments'):
                    location = att.get('url')
                    if amazon_url in location:
                        file_location = urllib2.urlopen(location)
                        file_data = file_location.read()
                        if file_data:
                            att_file = Attachment()
                            att_file.name = att.get('name')
                            att_file.size = att.get('bytes')
                            att_file.type = att.get('mimeType')
                            att_file.data = base64.b64encode(file_data)
                            att_file.save()
                            t.files.append(att_file)
                t.project = project
                t.number = starting_number
                t.order = starting_number - 1
                # by default user story
                t.type = 'U'
                t.points = 0
                tickets.append(t)
                starting_number += 1

        columns = []
        if import_args.get('include_cols'):
            for col in data.get('lists'):
                if not col.get('closed'):
                    new_col = Column()
                    new_col.title = col.get('name')
                    new_col.project = project
                    columns.append(new_col)

        if tickets:
            Ticket.objects.insert(tickets, load_bulk=False)
        if columns:
            Column.objects.insert(columns, load_bulk=False)

        # save activity
        save_notification(project_pk=project_pk,
                          verb='import',
                          data=data)

        return [tickets, columns], 200
Exemplo n.º 13
0
    def post(self, project_pk):
        """
        :param project_pk: Project ID
        :return: Column Resource created
        """
        data = request.get_json(silent=True)
        if not data:
            raise api_errors.InvalidAPIUsage(
                api_errors.INVALID_JSON_BODY_MSG
            )

        project = get_project_request(project_pk)

        col = Column()
        col.order = Column.objects.count()
        col.project = project
        col.title = data.get('title')
        col.color_max_cards = data.get('color_max_cards', '#FF0000')
        col.done_column = data.get('done_column', False)
        col.max_cards = data.get('max_cards', 9999)

        # Check if already exists one Done column
        if col.done_column:
            columns = Column.get_by_project(project)
            for c in columns:
                if c.done_column:
                    c.done_column = False
                    c.save()
        col.save()

        # save activity
        save_notification(project_pk=project.pk,
                          verb='new_column',
                          data=col.to_dict())

        return col, 200