Beispiel #1
0
def update_lanes(board_dict, board_id):
    if 'lanes' not in board_dict:
        return
    board = boards_api.get(board_id)
    new_list_ids = [lane.list_id for lane in board_dict['lanes']]
    existing_list_ids = [lane.list_id for lane in board.lanes]
    for lane in board.lanes:
        if lane.list_id in new_list_ids:
            new_lane = get_lane(lane.list_id, board_dict)
            if lane.position != new_lane.position:
                del new_lane.worklist
                original = copy.deepcopy(lane)
                boards_api.update_lane(
                    board, lane, new_lane.as_dict(omit_unset=True))
                updated = {
                    "old": serialize_lane(original),
                    "new": serialize_lane(new_lane)
                }

                events_api.board_lanes_changed_event(board_id,
                                                     request.current_user_id,
                                                     updated=updated)

    for lane in board_dict['lanes']:
        if lane.list_id not in existing_list_ids:
            del lane.worklist
            boards_api.add_lane(board, lane.as_dict(omit_unset=True))
            events_api.board_lanes_changed_event(board_id,
                                                 request.current_user_id,
                                                 added=serialize_lane(lane))

    board = boards_api.get(board_id)
    del board_dict['lanes']
Beispiel #2
0
def update_lanes(board_dict, board_id):
    if 'lanes' not in board_dict:
        return
    board = boards_api.get(board_id)
    new_list_ids = [lane.list_id for lane in board_dict['lanes']]
    existing_list_ids = [lane.list_id for lane in board.lanes]
    for lane in board.lanes:
        if lane.list_id in new_list_ids:
            new_lane = get_lane(lane.list_id, board_dict)
            if lane.position != new_lane.position:
                del new_lane.worklist
                original = copy.deepcopy(lane)
                boards_api.update_lane(board, lane,
                                       new_lane.as_dict(omit_unset=True))
                updated = {
                    "old": serialize_lane(original),
                    "new": serialize_lane(new_lane)
                }

                events_api.board_lanes_changed_event(board_id,
                                                     request.current_user_id,
                                                     updated=updated)

    for lane in board_dict['lanes']:
        if lane.list_id not in existing_list_ids:
            lane.worklist = None
            boards_api.add_lane(board, lane.as_dict(omit_unset=True))
            events_api.board_lanes_changed_event(board_id,
                                                 request.current_user_id,
                                                 added=serialize_lane(lane))

    board = boards_api.get(board_id)
    del board_dict['lanes']
Beispiel #3
0
    def put(self, id, board):
        """Modify this board.

        :param id: The ID of the board.
        :param board: The new board within the request body.

        """
        user_id = request.current_user_id
        if not boards_api.editable(boards_api.get(id), user_id):
            raise exc.NotFound(_("Board %s not found") % id)

        board_dict = board.as_dict(omit_unset=True)
        update_lanes(board_dict, id)

        # This is not how we add due dates.
        if 'due_dates' in board_dict:
            del board_dict['due_dates']

        updated_board = boards_api.update(id, board_dict)

        if boards_api.visible(updated_board, user_id):
            board_model = wmodels.Board.from_db_model(updated_board)
            board_model.resolve_lanes(updated_board)
            board_model.resolve_permissions(updated_board)
            return board_model
        else:
            raise exc.NotFound(_("Board %s not found") % id)
Beispiel #4
0
    def put(self, id, board):
        """Modify this board.

        :param id: The ID of the board.
        :param board: The new board within the request body.

        """
        user_id = request.current_user_id
        if not boards_api.editable(boards_api.get(id), user_id):
            raise exc.NotFound(_("Board %s not found") % id)

        board_dict = board.as_dict(omit_unset=True)
        update_lanes(board_dict, id)

        # This is not how we add due dates.
        if 'due_dates' in board_dict:
            del board_dict['due_dates']

        updated_board = boards_api.update(id, board_dict)

        if boards_api.visible(updated_board, user_id):
            board_model = wmodels.Board.from_db_model(updated_board)
            board_model.resolve_lanes(updated_board)
            board_model.resolve_permissions(updated_board)
            return board_model
        else:
            raise exc.NotFound(_("Board %s not found") % id)
Beispiel #5
0
def get_all(title=None, creator_id=None, project_id=None, board_id=None,
            user_id=None, story_id=None, task_id=None, sort_field=None,
            sort_dir=None, session=None, **kwargs):
    if sort_field is None:
        sort_field = 'id'
    if sort_dir is None:
        sort_dir = 'asc'

    if board_id is not None:
        board = boards.get(board_id)
        return [lane.worklist for lane in board.lanes]

    query = _build_worklist_query(title=title,
                                  creator_id=creator_id,
                                  project_id=project_id,
                                  user_id=user_id,
                                  session=session)

    query.order_by(getattr(models.Worklist, sort_field), sort_dir)

    if story_id:
        worklists = query.all()
        worklists = [worklist for worklist in worklists
                     if has_item(worklist, 'story', story_id)]

    if task_id:
        if not story_id:
            worklists = query.all()
        worklists = [worklist for worklist in worklists
                     if has_item(worklist, 'task', task_id)]

    if story_id or task_id:
        return worklists
    return query.all()
Beispiel #6
0
def get_count(title=None, creator_id=None, project_id=None, board_id=None,
              user_id=None, story_id=None, task_id=None, subscriber_id=None,
              session=None, archived=False, current_user=None,
              hide_lanes=True, item_type=None, **kwargs):
    if board_id is not None:
        board = boards.get(board_id)
        if board is None:
            return 0
        lists = [lane.worklist for lane in board.lanes
                 if visible(lane.worklist, current_user)]
        return len(lists)

    query = _build_worklist_query(title=title,
                                  creator_id=creator_id,
                                  project_id=project_id,
                                  user_id=user_id,
                                  subscriber_id=subscriber_id,
                                  archived=archived,
                                  session=session,
                                  current_user=current_user,
                                  hide_lanes=hide_lanes,
                                  story_id=story_id,
                                  task_id=task_id,
                                  item_type=item_type)
    return query.count()
Beispiel #7
0
    def delete(self, id):
        """Archive this board.

        :param id: The ID of the board to be archived.

        """
        board = boards_api.get(id)
        user_id = request.current_user_id
        if not boards_api.editable(board, user_id):
            raise exc.NotFound(_("Board %s not found") % id)

        # We use copy here because we only need to check changes
        # to the related objects, just the board's own attributes.
        # Also, deepcopy trips up on the lanes' backrefs.
        original = copy.copy(board)
        updated = boards_api.update(id, {"archived": True})

        post_timeline_events(original, updated)

        for lane in board.lanes:
            original = copy.deepcopy(worklists_api.get(lane.worklist.id))
            worklists_api.update(lane.worklist.id, {"archived": True})

            if not original.archived:
                events_api.worklist_details_changed_event(
                    lane.worklist.id, user_id, 'archived', original.archived,
                    True)
Beispiel #8
0
    def delete(self, id):
        """Archive this board.

        :param id: The ID of the board to be archived.

        """
        board = boards_api.get(id)
        user_id = request.current_user_id
        if not boards_api.editable(board, user_id):
            raise exc.NotFound(_("Board %s not found") % id)

        # We use copy here because we only need to check changes
        # to the related objects, just the board's own attributes.
        # Also, deepcopy trips up on the lanes' backrefs.
        original = copy.copy(board)
        updated = boards_api.update(id, {"archived": True})

        post_timeline_events(original, updated)

        for lane in board.lanes:
            original = copy.deepcopy(worklists_api.get(lane.worklist.id))
            worklists_api.update(lane.worklist.id, {"archived": True})

            if not original.archived:
                events_api.worklist_details_changed_event(
                    lane.worklist.id, user_id, 'archived', original.archived,
                    True)
Beispiel #9
0
    def get_one(self, id):
        """Retrieve details about one board.

        :param id: The ID of the board.

        """
        board = boards_api.get(id)

        user_id = request.current_user_id
        story_cache = {
            story.id: story
            for story in stories_api.story_get_all(board_id=id,
                                                   current_user=user_id)
        }
        task_cache = {
            task.id: task
            for task in tasks_api.task_get_all(board_id=id,
                                               current_user=user_id)
        }
        if boards_api.visible(board, user_id):
            board_model = wmodels.Board.from_db_model(board)
            board_model.resolve_lanes(board, story_cache, task_cache)
            board_model.resolve_due_dates(board)
            board_model.resolve_permissions(board)
            return board_model
        else:
            raise exc.NotFound(_("Board %s not found") % id)
Beispiel #10
0
    def put(self, id, due_date):
        """Modify a due date.

        :param id: The ID of the due date to edit.
        :param due_date: The new due date within the request body.

        """
        if not due_dates_api.assignable(due_dates_api.get(id), request.current_user_id):
            raise exc.NotFound(_("Due date %s not found") % id)

        original_due_date = due_dates_api.get(id)

        due_date_dict = due_date.as_dict(omit_unset=True)
        editing = any(prop in due_date_dict for prop in ("name", "date", "private"))
        if editing and not due_dates_api.editable(original_due_date, request.current_user_id):
            raise exc.NotFound(_("Due date %s not found") % id)

        if due_date.creator_id and due_date.creator_id != original_due_date.creator_id:
            abort(400, _("You can't select the creator of a due date."))

        if "tasks" in due_date_dict:
            tasks = due_date_dict.pop("tasks")
            db_tasks = []
            for task in tasks:
                db_tasks.append(tasks_api.task_get(task.id, current_user=request.current_user_id))
            due_date_dict["tasks"] = db_tasks

        if "stories" in due_date_dict:
            stories = due_date_dict.pop("stories")
            db_stories = []
            for story in stories:
                db_stories.append(stories_api.story_get_simple(story.id, current_user=request.current_user_id))
            due_date_dict["stories"] = db_stories

        board = None
        worklist = None
        if "board_id" in due_date_dict:
            board = boards_api.get(due_date_dict["board_id"])

        if "worklist_id" in due_date_dict:
            worklist = worklists_api.get(due_date_dict["worklist_id"])

        updated_due_date = due_dates_api.update(id, due_date_dict)

        if board:
            updated_due_date.boards.append(board)

        if worklist:
            updated_due_date.worklists.append(worklist)

        if due_dates_api.visible(updated_due_date, request.current_user_id):
            due_date_model = wmodels.DueDate.from_db_model(updated_due_date)
            due_date_model.resolve_items(updated_due_date)
            due_date_model.resolve_permissions(updated_due_date, request.current_user_id)
            return due_date_model
        else:
            raise exc.NotFound(_("Due date %s not found") % id)
Beispiel #11
0
    def post(self, due_date):
        """Create a new due date.

        :param due_date: A due date within the request body.

        """
        due_date_dict = due_date.as_dict()
        user_id = request.current_user_id

        if due_date.creator_id and due_date.creator_id != user_id:
            abort(400, _("You can't select the creator of a due date."))
        due_date_dict.update({'creator_id': user_id})

        board_id = due_date_dict.pop('board_id')
        worklist_id = due_date_dict.pop('worklist_id')
        if 'stories' in due_date_dict:
            del due_date_dict['stories']
        if 'tasks' in due_date_dict:
            del due_date_dict['tasks']
        owners = due_date_dict.pop('owners')
        users = due_date_dict.pop('users')
        if not owners:
            owners = [user_id]
        if not users:
            users = []

        created_due_date = due_dates_api.create(due_date_dict)

        if board_id is not None:
            date = due_dates_api.get(created_due_date.id)
            date.boards.append(boards_api.get(board_id))

        if worklist_id is not None:
            date = due_dates_api.get(created_due_date.id)
            date.worklists.append(worklists_api.get(worklist_id))

        edit_permission = {
            'name': 'edit_due_date_%d' % created_due_date.id,
            'codename': 'edit_date',
            'users': owners
        }
        assign_permission = {
            'name': 'assign_due_date_%d' % created_due_date.id,
            'codename': 'assign_date',
            'users': users
        }
        due_dates_api.create_permission(created_due_date.id, edit_permission)
        due_dates_api.create_permission(created_due_date.id, assign_permission)

        created_due_date = due_dates_api.get(created_due_date.id)
        due_date_model = wmodels.DueDate.from_db_model(created_due_date)
        due_date_model.resolve_items(created_due_date)
        due_date_model.resolve_permissions(created_due_date,
                                           request.current_user_id)
        return due_date_model
Beispiel #12
0
    def post(self, due_date):
        """Create a new due date.

        :param due_date: A due date within the request body.

        """
        due_date_dict = due_date.as_dict()
        user_id = request.current_user_id

        if due_date.creator_id and due_date.creator_id != user_id:
            abort(400, _("You can't select the creator of a due date."))
        due_date_dict.update({'creator_id': user_id})

        board_id = due_date_dict.pop('board_id')
        worklist_id = due_date_dict.pop('worklist_id')
        if 'stories' in due_date_dict:
            del due_date_dict['stories']
        if 'tasks' in due_date_dict:
            del due_date_dict['tasks']
        owners = due_date_dict.pop('owners')
        users = due_date_dict.pop('users')
        if not owners:
            owners = [user_id]
        if not users:
            users = []

        created_due_date = due_dates_api.create(due_date_dict)

        if board_id is not None:
            date = due_dates_api.get(created_due_date.id)
            date.boards.append(boards_api.get(board_id))

        if worklist_id is not None:
            date = due_dates_api.get(created_due_date.id)
            date.worklists.append(worklists_api.get(worklist_id))

        edit_permission = {
            'name': 'edit_due_date_%d' % created_due_date.id,
            'codename': 'edit_date',
            'users': owners
        }
        assign_permission = {
            'name': 'assign_due_date_%d' % created_due_date.id,
            'codename': 'assign_date',
            'users': users
        }
        due_dates_api.create_permission(created_due_date.id, edit_permission)
        due_dates_api.create_permission(created_due_date.id, assign_permission)

        created_due_date = due_dates_api.get(created_due_date.id)
        due_date_model = wmodels.DueDate.from_db_model(created_due_date)
        due_date_model.resolve_items(created_due_date)
        due_date_model.resolve_permissions(created_due_date,
                                           request.current_user_id)
        return due_date_model
Beispiel #13
0
    def get(self, board_id):
        """Get board permissions for the current user.

        :param board_id: The ID of the board.

        """
        board = boards_api.get(board_id)
        if boards_api.visible(board, request.current_user_id):
            return boards_api.get_permissions(board, request.current_user_id)
        else:
            raise exc.NotFound(_("Board %s not found") % board_id)
Beispiel #14
0
    def get(self, board_id):
        """Get board permissions for the current user.

        :param board_id: The ID of the board.

        """
        board = boards_api.get(board_id)
        if boards_api.visible(board, request.current_user_id):
            return boards_api.get_permissions(board, request.current_user_id)
        else:
            raise exc.NotFound(_("Board %s not found") % board_id)
Beispiel #15
0
def update_lanes(board_dict, board_id):
    if 'lanes' not in board_dict:
        return
    board = boards_api.get(board_id)
    new_list_ids = [lane.list_id for lane in board_dict['lanes']]
    existing_list_ids = [lane.list_id for lane in board.lanes]
    for lane in board.lanes:
        if lane.list_id in new_list_ids:
            new_lane = get_lane(lane.list_id, board_dict)
            if lane.position != new_lane.position:
                del new_lane.worklist
                boards_api.update_lane(board, lane,
                                       new_lane.as_dict(omit_unset=True))
    for lane in board_dict['lanes']:
        if lane.list_id not in existing_list_ids:
            lane.worklist = None
            boards_api.add_lane(board, lane.as_dict(omit_unset=True))

    board = boards_api.get(board_id)
    del board_dict['lanes']
Beispiel #16
0
def update_lanes(board_dict, board_id):
    if 'lanes' not in board_dict:
        return
    board = boards_api.get(board_id)
    new_list_ids = [lane.list_id for lane in board_dict['lanes']]
    existing_list_ids = [lane.list_id for lane in board.lanes]
    for lane in board.lanes:
        if lane.list_id in new_list_ids:
            new_lane = get_lane(lane.list_id, board_dict)
            if lane.position != new_lane.position:
                del new_lane.worklist
                boards_api.update_lane(
                    board, lane, new_lane.as_dict(omit_unset=True))
    for lane in board_dict['lanes']:
        if lane.list_id not in existing_list_ids:
            lane.worklist = None
            boards_api.add_lane(board, lane.as_dict(omit_unset=True))

    board = boards_api.get(board_id)
    del board_dict['lanes']
Beispiel #17
0
    def put(self, board_id, permission):
        """Update a permission of the board.

        :param board_id: The ID of the board.
        :param permission: The new contents of the permission.

        """
        if boards_api.editable(boards_api.get(board_id),
                               request.current_user_id):
            return boards_api.update_permission(board_id, permission).codename
        else:
            raise exc.NotFound(_("Board %s not found") % board_id)
Beispiel #18
0
    def post(self, board_id, permission):
        """Add a new permission to the board.

        :param board_id: The ID of the board.
        :param permission: The dict to use to create the permission.

        """
        if boards_api.editable(boards_api.get(board_id),
                               request.current_user_id):
            return boards_api.create_permission(board_id)
        else:
            raise exc.NotFound(_("Board %s not found") % board_id)
Beispiel #19
0
    def put(self, board_id, permission):
        """Update a permission of the board.

        :param board_id: The ID of the board.
        :param permission: The new contents of the permission.

        """
        if boards_api.editable(boards_api.get(board_id),
                               request.current_user_id):
            return boards_api.update_permission(board_id, permission).codename
        else:
            raise exc.NotFound(_("Board %s not found") % board_id)
Beispiel #20
0
    def post(self, board_id, permission):
        """Add a new permission to the board.

        :param board_id: The ID of the board.
        :param permission: The dict to use to create the permission.

        """
        if boards_api.editable(boards_api.get(board_id),
                               request.current_user_id):
            return boards_api.create_permission(board_id)
        else:
            raise exc.NotFound(_("Board %s not found") % board_id)
Beispiel #21
0
def get_all(title=None,
            creator_id=None,
            project_id=None,
            board_id=None,
            user_id=None,
            story_id=None,
            task_id=None,
            subscriber_id=None,
            sort_field=None,
            sort_dir=None,
            session=None,
            offset=None,
            limit=None,
            archived=False,
            current_user=None,
            hide_lanes=True,
            item_type=None,
            **kwargs):
    if sort_field is None:
        sort_field = 'id'
    if sort_dir is None:
        sort_dir = 'asc'

    if board_id is not None:
        board = boards.get(board_id)
        if board is None:
            return []
        return [
            lane.worklist for lane in board.lanes
            if visible(lane.worklist, current_user)
        ]

    query = _build_worklist_query(title=title,
                                  creator_id=creator_id,
                                  project_id=project_id,
                                  user_id=user_id,
                                  subscriber_id=subscriber_id,
                                  archived=archived,
                                  session=session,
                                  current_user=current_user,
                                  hide_lanes=hide_lanes,
                                  item_type=item_type,
                                  story_id=story_id,
                                  task_id=task_id)

    query = api_base.paginate_query(query=query,
                                    model=models.Worklist,
                                    limit=limit,
                                    offset=offset,
                                    sort_key=sort_field,
                                    sort_dir=sort_dir)
    return query.all()
Beispiel #22
0
    def post(self, due_date):
        """Create a new due date.

        :param due_date: A due date within the request body.

        """
        due_date_dict = due_date.as_dict()
        user_id = request.current_user_id

        if due_date.creator_id and due_date.creator_id != user_id:
            abort(400, _("You can't select the creator of a due date."))
        due_date_dict.update({"creator_id": user_id})

        board_id = due_date_dict.pop("board_id")
        worklist_id = due_date_dict.pop("worklist_id")
        if "stories" in due_date_dict:
            del due_date_dict["stories"]
        if "tasks" in due_date_dict:
            del due_date_dict["tasks"]
        owners = due_date_dict.pop("owners")
        users = due_date_dict.pop("users")
        if not owners:
            owners = [user_id]
        if not users:
            users = []

        created_due_date = due_dates_api.create(due_date_dict)

        if board_id is not None:
            date = due_dates_api.get(created_due_date.id)
            date.boards.append(boards_api.get(board_id))

        if worklist_id is not None:
            date = due_dates_api.get(created_due_date.id)
            date.worklists.append(worklists_api.get(worklist_id))

        edit_permission = {"name": "edit_due_date_%d" % created_due_date.id, "codename": "edit_date", "users": owners}
        assign_permission = {
            "name": "assign_due_date_%d" % created_due_date.id,
            "codename": "assign_date",
            "users": users,
        }
        due_dates_api.create_permission(created_due_date.id, edit_permission)
        due_dates_api.create_permission(created_due_date.id, assign_permission)

        created_due_date = due_dates_api.get(created_due_date.id)
        due_date_model = wmodels.DueDate.from_db_model(created_due_date)
        due_date_model.resolve_items(created_due_date)
        due_date_model.resolve_permissions(created_due_date, request.current_user_id)
        return due_date_model
Beispiel #23
0
    def delete(self, id):
        """Archive this board.

        :param id: The ID of the board to be archived.

        """
        board = boards_api.get(id)
        user_id = request.current_user_id
        if not boards_api.editable(board, user_id):
            raise exc.NotFound(_("Board %s not found") % id)

        boards_api.update(id, {"archived": True})

        for lane in board.lanes:
            worklists_api.update(lane.worklist.id, {"archived": True})
Beispiel #24
0
    def delete(self, id):
        """Archive this board.

        :param id: The ID of the board to be archived.

        """
        board = boards_api.get(id)
        user_id = request.current_user_id
        if not boards_api.editable(board, user_id):
            raise exc.NotFound(_("Board %s not found") % id)

        boards_api.update(id, {"archived": True})

        for lane in board.lanes:
            worklists_api.update(lane.worklist.id, {"archived": True})
Beispiel #25
0
    def get_one(self, id):
        """Retrieve details about one board.

        :param id: The ID of the board.

        """
        board = boards_api.get(id)

        user_id = request.current_user_id
        if boards_api.visible(board, user_id):
            board_model = wmodels.Board.from_db_model(board)
            board_model.resolve_lanes(board)
            board_model.resolve_due_dates(board)
            board_model.resolve_permissions(board)
            return board_model
        else:
            raise exc.NotFound(_("Board %s not found") % id)
Beispiel #26
0
    def get_one(self, id):
        """Retrieve details about one board.

        :param id: The ID of the board.

        """
        board = boards_api.get(id)

        user_id = request.current_user_id
        if boards_api.visible(board, user_id):
            board_model = wmodels.Board.from_db_model(board)
            board_model.resolve_lanes(board)
            board_model.resolve_due_dates(board)
            board_model.resolve_permissions(board)
            return board_model
        else:
            raise exc.NotFound(_("Board %s not found") % id)
Beispiel #27
0
    def put(self, id, board):
        """Modify this board.

        :param id: The ID of the board.
        :param board: The new board within the request body.

        """
        user_id = request.current_user_id
        original = boards_api.get(id)
        if not boards_api.editable(original, user_id):
            raise exc.NotFound(_("Board %s not found") % id)

        story_cache = {
            story.id: story
            for story in stories_api.story_get_all(board_id=id,
                                                   current_user=user_id)
        }
        task_cache = {
            task.id: task
            for task in tasks_api.task_get_all(board_id=id,
                                               current_user=user_id)
        }

        # We use copy here because we only need to check changes
        # to the related objects, just the board's own attributes.
        # Also, deepcopy trips up on the lanes' backrefs.
        original = copy.copy(original)

        board_dict = board.as_dict(omit_unset=True)
        update_lanes(board_dict, id)

        # This is not how we add due dates.
        if 'due_dates' in board_dict:
            del board_dict['due_dates']

        updated_board = boards_api.update(id, board_dict)

        post_timeline_events(original, updated_board)

        if boards_api.visible(updated_board, user_id):
            board_model = wmodels.Board.from_db_model(updated_board)
            board_model.resolve_lanes(updated_board, story_cache, task_cache)
            board_model.resolve_permissions(updated_board)
            return board_model
        else:
            raise exc.NotFound(_("Board %s not found") % id)
Beispiel #28
0
    def post(self, board_id, permission):
        """Add a new permission to the board.

        :param board_id: The ID of the board.
        :param permission: The dict to use to create the permission.

        """
        user_id = request.current_user_id
        if boards_api.editable(boards_api.get(board_id), user_id):
            created = boards_api.create_permission(board_id, permission)

            users = [{user.id: user.full_name} for user in created.users]
            events_api.board_permission_created_event(board_id, user_id,
                                                      created.id,
                                                      created.codename, users)

            return created
        else:
            raise exc.NotFound(_("Board %s not found") % board_id)
Beispiel #29
0
    def post(self, board_id, permission):
        """Add a new permission to the board.

        :param board_id: The ID of the board.
        :param permission: The dict to use to create the permission.

        """
        user_id = request.current_user_id
        if boards_api.editable(boards_api.get(board_id), user_id):
            created = boards_api.create_permission(board_id, permission)

            users = [{user.id: user.full_name} for user in created.users]
            events_api.board_permission_created_event(board_id,
                                                      user_id,
                                                      created.id,
                                                      created.codename,
                                                      users)

            return created
        else:
            raise exc.NotFound(_("Board %s not found") % board_id)
Beispiel #30
0
    def get_one(self, id):
        """Retrieve details about one board.

        :param id: The ID of the board.

        """
        board = boards_api.get(id)

        user_id = request.current_user_id
        story_cache = {story.id: story for story in stories_api.story_get_all(
                       board_id=id, current_user=user_id)}
        task_cache = {task.id: task for task in tasks_api.task_get_all(
                      board_id=id, current_user=user_id)}
        if boards_api.visible(board, user_id):
            board_model = wmodels.Board.from_db_model(board)
            board_model.resolve_lanes(board, story_cache, task_cache)
            board_model.resolve_due_dates(board)
            board_model.resolve_permissions(board)
            return board_model
        else:
            raise exc.NotFound(_("Board %s not found") % id)
Beispiel #31
0
    def put(self, id, board):
        """Modify this board.

        :param id: The ID of the board.
        :param board: The new board within the request body.

        """
        user_id = request.current_user_id
        original = boards_api.get(id)
        if not boards_api.editable(original, user_id):
            raise exc.NotFound(_("Board %s not found") % id)

        story_cache = {story.id: story for story in stories_api.story_get_all(
                       board_id=id, current_user=user_id)}
        task_cache = {task.id: task for task in tasks_api.task_get_all(
                      board_id=id, current_user=user_id)}

        # We use copy here because we only need to check changes
        # to the related objects, just the board's own attributes.
        # Also, deepcopy trips up on the lanes' backrefs.
        original = copy.copy(original)

        board_dict = board.as_dict(omit_unset=True)
        update_lanes(board_dict, id)

        # This is not how we add due dates.
        if 'due_dates' in board_dict:
            del board_dict['due_dates']

        updated_board = boards_api.update(id, board_dict)

        post_timeline_events(original, updated_board)

        if boards_api.visible(updated_board, user_id):
            board_model = wmodels.Board.from_db_model(updated_board)
            board_model.resolve_lanes(updated_board, story_cache, task_cache)
            board_model.resolve_permissions(updated_board)
            return board_model
        else:
            raise exc.NotFound(_("Board %s not found") % id)
Beispiel #32
0
    def put(self, board_id, permission):
        """Update a permission of the board.

        :param board_id: The ID of the board.
        :param permission: The new contents of the permission.

        """
        user_id = request.current_user_id
        board = boards_api.get(board_id)

        old = None
        for perm in board.permissions:
            if perm.codename == permission['codename']:
                old = perm

        if old is None:
            raise exc.NotFound(_("Permission with codename %s not found")
                               % permission['codename'])

        old_users = {user.id: user.full_name for user in old.users}

        if boards_api.editable(board, user_id):
            updated = boards_api.update_permission(board_id, permission)
            new_users = {user.id: user.full_name for user in updated.users}

            added = [{id: name} for id, name in six.iteritems(new_users)
                     if id not in old_users]
            removed = [{id: name} for id, name in six.iteritems(old_users)
                       if id not in new_users]

            if added or removed:
                events_api.board_permissions_changed_event(board.id,
                                                           user_id,
                                                           updated.id,
                                                           updated.codename,
                                                           added,
                                                           removed)
        else:
            raise exc.NotFound(_("Board %s not found") % board_id)
Beispiel #33
0
    def put(self, board_id, permission):
        """Update a permission of the board.

        :param board_id: The ID of the board.
        :param permission: The new contents of the permission.

        """
        user_id = request.current_user_id
        board = boards_api.get(board_id)

        old = None
        for perm in board.permissions:
            if perm.codename == permission['codename']:
                old = perm

        if old is None:
            raise exc.NotFound(
                _("Permission with codename %s not found") %
                permission['codename'])

        old_users = {user.id: user.full_name for user in old.users}

        if boards_api.editable(board, user_id):
            updated = boards_api.update_permission(board_id, permission)
            new_users = {user.id: user.full_name for user in updated.users}

            added = [{
                id: name
            } for id, name in six.iteritems(new_users) if id not in old_users]
            removed = [{
                id: name
            } for id, name in six.iteritems(old_users) if id not in new_users]

            if added or removed:
                events_api.board_permissions_changed_event(
                    board.id, user_id, updated.id, updated.codename, added,
                    removed)
        else:
            raise exc.NotFound(_("Board %s not found") % board_id)
Beispiel #34
0
    def delete(self, id, board_id):
        """Stop associating a due date with a board.

        Note: We don't allow actual deletion of due dates.

        :param id: The ID of the due date.
        :param board_id: The ID of the board.

        """
        due_date = due_dates_api.get(id)
        if not due_dates_api.editable(due_date, request.current_user_id):
            raise exc.NotFound(_("Due date %s not found") % id)

        board = boards_api.get(board_id)
        if not boards_api.editable(board, request.current_user_id):
            raise exc.NotFound(_("Board %s not found") % board_id)

        if board in due_date.boards:
            due_date.boards.remove(board)
            for lane in board.lanes:
                for card in lane.worklist.items:
                    if card.display_due_date == due_date.id:
                        update = {'display_due_date': None}
                        worklists_api.update_item(card.id, update)
Beispiel #35
0
    def delete(self, id, board_id):
        """Stop associating a due date with a board.

        Note: We don't allow actual deletion of due dates.

        :param id: The ID of the due date.
        :param board_id: The ID of the board.

        """
        due_date = due_dates_api.get(id)
        if not due_dates_api.editable(due_date, request.current_user_id):
            raise exc.NotFound(_("Due date %s not found") % id)

        board = boards_api.get(board_id)
        if not boards_api.editable(board, request.current_user_id):
            raise exc.NotFound(_("Board %s not found") % board_id)

        if board in due_date.boards:
            due_date.boards.remove(board)
            for lane in board.lanes:
                for card in lane.worklist.items:
                    if card.display_due_date == due_date.id:
                        update = {'display_due_date': None}
                        worklists_api.update_item(card.id, update)
Beispiel #36
0
def get_all(title=None, creator_id=None, project_id=None, board_id=None,
            user_id=None, story_id=None, task_id=None, sort_field=None,
            sort_dir=None, session=None, offset=None, limit=None,
            archived=False, current_user=None, hide_lanes=True,
            item_type=None, **kwargs):
    if sort_field is None:
        sort_field = 'id'
    if sort_dir is None:
        sort_dir = 'asc'

    if board_id is not None:
        board = boards.get(board_id)
        if board is None:
            return []
        return [lane.worklist for lane in board.lanes
                if visible(lane.worklist, current_user)]

    query = _build_worklist_query(title=title,
                                  creator_id=creator_id,
                                  project_id=project_id,
                                  user_id=user_id,
                                  archived=archived,
                                  session=session,
                                  current_user=current_user,
                                  hide_lanes=hide_lanes,
                                  item_type=item_type,
                                  story_id=story_id,
                                  task_id=task_id)

    query = api_base.paginate_query(query=query,
                                    model=models.Worklist,
                                    limit=limit,
                                    offset=offset,
                                    sort_key=sort_field,
                                    sort_dir=sort_dir)
    return query.all()
Beispiel #37
0
def get_count(title=None, creator_id=None, project_id=None, board_id=None,
              user_id=None, story_id=None, task_id=None, session=None,
              archived=False, current_user=None, hide_lanes=True,
              item_type=None, **kwargs):
    if board_id is not None:
        board = boards.get(board_id)
        if board is None:
            return 0
        lists = [lane.worklist for lane in board.lanes
                 if visible(lane.worklist, current_user)]
        return len(lists)

    query = _build_worklist_query(title=title,
                                  creator_id=creator_id,
                                  project_id=project_id,
                                  user_id=user_id,
                                  archived=archived,
                                  session=session,
                                  current_user=current_user,
                                  hide_lanes=hide_lanes,
                                  story_id=story_id,
                                  task_id=task_id,
                                  item_type=item_type)
    return query.count()
Beispiel #38
0
    def put(self, id, due_date):
        """Modify a due date.

        :param id: The ID of the due date to edit.
        :param due_date: The new due date within the request body.

        """
        if not due_dates_api.assignable(due_dates_api.get(id),
                                        request.current_user_id):
            raise exc.NotFound(_("Due date %s not found") % id)

        original_due_date = due_dates_api.get(id)

        due_date_dict = due_date.as_dict(omit_unset=True)
        editing = any(prop in due_date_dict
                      for prop in ('name', 'date', 'private'))
        if editing and not due_dates_api.editable(original_due_date,
                                                  request.current_user_id):
            raise exc.NotFound(_("Due date %s not found") % id)

        if due_date.creator_id \
                and due_date.creator_id != original_due_date.creator_id:
            abort(400, _("You can't select the creator of a due date."))

        if 'tasks' in due_date_dict:
            tasks = due_date_dict.pop('tasks')
            db_tasks = []
            for task in tasks:
                db_tasks.append(tasks_api.task_get(
                    task.id, current_user=request.current_user_id))
            due_date_dict['tasks'] = db_tasks

        if 'stories' in due_date_dict:
            stories = due_date_dict.pop('stories')
            db_stories = []
            for story in stories:
                db_stories.append(stories_api.story_get_simple(
                    story.id, current_user=request.current_user_id))
            due_date_dict['stories'] = db_stories

        board = None
        worklist = None
        if 'board_id' in due_date_dict:
            board = boards_api.get(due_date_dict['board_id'])

        if 'worklist_id' in due_date_dict:
            worklist = worklists_api.get(due_date_dict['worklist_id'])

        updated_due_date = due_dates_api.update(id, due_date_dict)

        if board:
            updated_due_date.boards.append(board)

        if worklist:
            updated_due_date.worklists.append(worklist)

        if due_dates_api.visible(updated_due_date, request.current_user_id):
            due_date_model = wmodels.DueDate.from_db_model(updated_due_date)
            due_date_model.resolve_items(updated_due_date)
            due_date_model.resolve_permissions(updated_due_date,
                                               request.current_user_id)
            return due_date_model
        else:
            raise exc.NotFound(_("Due date %s not found") % id)