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']
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']
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)
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()
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()
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)
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)
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)
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
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)
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']
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']
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)
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)
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()
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
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})
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)
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)
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)
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)
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)
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)
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)
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)
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()
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()
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)