Exemplo n.º 1
0
    def put(self, story_id, tags):
        """Add a list of tags to a Story.

        :param story_id: An id of a Story to which the tags should be added.
        :param tags: A list of tags to be added.
        """

        story = stories_api.story_get(
            story_id, current_user=request.current_user_id)
        if not story:
            raise exc.NotFound("Story %s not found" % story_id)

        for tag in tags:
            stories_api.story_add_tag(
                story_id, tag, current_user=request.current_user_id)
        # For some reason the story gets cached and the tags do not appear.
        stories_api.api_base.get_session().expunge(story)

        story = stories_api.story_get(
            story_id, current_user=request.current_user_id)
        events_api.tags_added_event(story_id=story_id,
                                    author_id=request.current_user_id,
                                    story_title=story.title,
                                    tags=tags)
        return wmodels.Story.from_db_model(story)
Exemplo n.º 2
0
    def put(self, story_id, tags=[], body=[]):
        """Add a list of tags to a Story.

        Example::

          curl https://my.example.org/api/v1/tags/19 -X PUT \\
          -H 'Authorization: Bearer MY_ACCESS_TOKEN' \\
          -H 'Content-Type: application/json;charset=UTF-8' \\
          --data-binary '["taga","tagb"]'

        :param story_id: An id of a Story to which the tags should be added.
        :param tags: A list of tags to be added.
        """
        tags = (tags or []) + (body or [])

        story = stories_api.story_get(
            story_id, current_user=request.current_user_id)
        if not story:
            raise exc.NotFound("Story %s not found" % story_id)

        for tag in tags:
            stories_api.story_add_tag(
                story_id, tag, current_user=request.current_user_id)
        # For some reason the story gets cached and the tags do not appear.
        stories_api.api_base.get_session().expunge(story)

        story = stories_api.story_get(
            story_id, current_user=request.current_user_id)
        events_api.tags_added_event(story_id=story_id,
                                    author_id=request.current_user_id,
                                    story_title=story.title,
                                    tags=tags)
        return wmodels.Story.from_db_model(story)
Exemplo n.º 3
0
    def put(self, story_id, tags):
        """Add a list of tags to a Story.

        :param story_id: An id of a Story to which the tags should be added.
        :param tags: A list of tags to be added.
        """

        story = stories_api.story_get(story_id,
                                      current_user=request.current_user_id)
        if not story:
            raise exc.NotFound("Story %s not found" % story_id)

        for tag in tags:
            stories_api.story_add_tag(story_id,
                                      tag,
                                      current_user=request.current_user_id)
        # For some reason the story gets cached and the tags do not appear.
        stories_api.api_base.get_session().expunge(story)

        story = stories_api.story_get(story_id,
                                      current_user=request.current_user_id)
        events_api.tags_added_event(story_id=story_id,
                                    author_id=request.current_user_id,
                                    story_title=story.title,
                                    tags=tags)
        return wmodels.Story.from_db_model(story)
Exemplo n.º 4
0
    def put(self, story_id, tags=[], body=[]):
        """Add a list of tags to a Story.

        Example::

          curl https://my.example.org/api/v1/tags/19 -X PUT \\
          -H 'Authorization: Bearer MY_ACCESS_TOKEN' \\
          -H 'Content-Type: application/json;charset=UTF-8' \\
          --data-binary '["taga","tagb"]'

        :param story_id: An id of a Story to which the tags should be added.
        :param tags: A list of tags to be added.
        """
        tags = (tags or []) + (body or [])

        story = stories_api.story_get(story_id,
                                      current_user=request.current_user_id)
        if not story:
            raise exc.NotFound("Story %s not found" % story_id)

        for tag in tags:
            stories_api.story_add_tag(story_id,
                                      tag,
                                      current_user=request.current_user_id)
        # For some reason the story gets cached and the tags do not appear.
        stories_api.api_base.get_session().expunge(story)

        story = stories_api.story_get(story_id,
                                      current_user=request.current_user_id)
        events_api.tags_added_event(story_id=story_id,
                                    author_id=request.current_user_id,
                                    story_title=story.title,
                                    tags=tags)
        return wmodels.Story.from_db_model(story)
Exemplo n.º 5
0
 def resolve_item(self, item):
     user_id = request.current_user_id
     if item.item_type == 'story':
         story = stories_api.story_get(item.item_id,
                                       current_user=request.current_user_id)
         if story is None:
             return False
         self.story = Story.from_db_model(story)
         due_dates = [
             date.id for date in story.due_dates
             if due_dates_api.visible(date, user_id)
         ]
         self.story.due_dates = due_dates
     elif item.item_type == 'task':
         task = tasks_api.task_get(item.item_id,
                                   current_user=request.current_user_id)
         if task is None or task.story is None:
             return False
         self.task = Task.from_db_model(task)
         due_dates = [
             date.id for date in task.due_dates
             if due_dates_api.visible(date, user_id)
         ]
         self.task.due_dates = due_dates
     return True
Exemplo n.º 6
0
    def post(self, id, item_id, item_type, list_position):
        """Add an item to a worklist.

        :param id: The ID of the worklist.
        :param item_id: The ID of the item.
        :param item_type: The type of the item (i.e. "story" or "task").
        :param list_position: The position in the list to add the item.

        """
        user_id = request.current_user_id
        if not worklists_api.editable_contents(worklists_api.get(id),
                                               user_id):
            raise exc.NotFound(_("Worklist %s not found") % id)
        item = None
        if item_type == 'story':
            item = stories_api.story_get(
                item_id, current_user=request.current_user_id)
        elif item_type == 'task':
            item = tasks_api.task_get(
                item_id, current_user=request.current_user_id)
        if item is None:
            raise exc.NotFound(_("Item %s refers to a non-existent task or "
                                 "story.") % item_id)

        worklists_api.add_item(
            id, item_id, item_type, list_position,
            current_user=request.current_user_id)

        return wmodels.WorklistItem.from_db_model(
            worklists_api.get_item_at_position(id, list_position))
Exemplo n.º 7
0
 def resolve_item(self, item, story_cache, task_cache, due_dates=True):
     user_id = request.current_user_id
     if item.item_type == 'story':
         story = story_cache.get(item.item_id) or stories_api.story_get(
             item.item_id, current_user=request.current_user_id)
         if story is None:
             return False
         self.story = Story.from_db_model(story)
         if due_dates:
             self.story.due_dates = [
                 date.id for date in story.due_dates
                 if due_dates_api.visible(date, user_id)
             ]
     elif item.item_type == 'task':
         task = task_cache.get(item.item_id) or tasks_api.task_get(
             item.item_id, current_user=request.current_user_id)
         if task is None or task.story is None:
             return False
         self.task = Task.from_db_model(task)
         if due_dates:
             self.task.due_dates = [
                 date.id for date in task.due_dates
                 if due_dates_api.visible(date, user_id)
             ]
     return True
Exemplo n.º 8
0
    def delete(self, story_id, tags):
        """Remove a list of tags from a Story.

        Example::

          curl https://my.example.org/api/v1/tags/19 -X DELETE \\
          -H 'Authorization: Bearer MY_ACCESS_TOKEN' \\
          -H 'Content-Type: application/json;charset=UTF-8' \\
          --data-binary '["taga","tagb"]'

        :param story_id: An id of a Story from which the tags should be
                         removed.
        :param tags: A list of tags to be removed.
        """

        story = stories_api.story_get(
            story_id, current_user=request.current_user_id)
        if not story:
            raise exc.NotFound("Story %s not found" % story_id)

        for tag in tags:
            stories_api.story_remove_tag(
                story_id, tag, current_user=request.current_user_id)

        events_api.tags_deleted_event(story_id=story_id,
                                      author_id=request.current_user_id,
                                      story_title=story.title,
                                      tags=tags)
Exemplo n.º 9
0
    def get_all(self,
                story_id=None,
                name=None,
                marker=None,
                limit=None,
                offset=None):
        """Retrieve all tags.

        Example::

          curl https://my.example.org/api/v1/tags

        :param story_id: Filter tags by story ID.
        :param name: Filter tags by name.
        :param marker: ID of the tag to start results from.
        :param limit: Maximum number of results per page.
        :param offset: Number of results to offset page by.
        """

        if not story_id:
            marker_tag = tags_api.tag_get_by_id(marker)
            tags = tags_api.tag_get_all(name=name,
                                        marker=marker_tag,
                                        limit=limit,
                                        offset=offset)

            return [wmodels.Tag.from_db_model(t) for t in tags]

        story = stories_api.story_get(story_id,
                                      current_user=request.current_user_id)
        if not story:
            raise exc.NotFound("Story %s not found" % story_id)

        return [wmodels.Tag.from_db_model(t) for t in story.tags]
Exemplo n.º 10
0
    def delete(self, story_id, tags):
        """Remove a list of tags from a Story.

        Example::

          curl https://my.example.org/api/v1/tags/19 -X DELETE \\
          -H 'Authorization: Bearer MY_ACCESS_TOKEN' \\
          -H 'Content-Type: application/json;charset=UTF-8' \\
          --data-binary '["taga","tagb"]'

        :param story_id: An id of a Story from which the tags should be
                         removed.
        :param tags: A list of tags to be removed.
        """

        story = stories_api.story_get(story_id,
                                      current_user=request.current_user_id)
        if not story:
            raise exc.NotFound("Story %s not found" % story_id)

        for tag in tags:
            stories_api.story_remove_tag(story_id,
                                         tag,
                                         current_user=request.current_user_id)

        events_api.tags_deleted_event(story_id=story_id,
                                      author_id=request.current_user_id,
                                      story_title=story.title,
                                      tags=tags)
Exemplo n.º 11
0
def add_item(worklist_id, item_id, item_type, list_position,
             current_user=None):
    worklist = _worklist_get(worklist_id)
    if worklist is None:
        raise exc.NotFound(_("Worklist %s not found") % worklist_id)

    # Check if this item has an archived card in this worklist to restore
    archived = get_item_by_item_id(
        worklist, item_type, item_id, archived=True)
    if archived:
        update = {
            'archived': False,
            'list_position': list_position
        }
        api_base.entity_update(models.WorklistItem, archived.id, update)
        return worklist

    # If this worklist is a lane, check if the item has an archived card
    # somewhere in the board to restore
    if is_lane(worklist):
        board = boards.get_from_lane(worklist)
        archived = boards.get_card(board, item_type, item_id, archived=True)
        if archived:
            update = {
                'archived': False,
                'list_id': worklist_id,
                'list_position': list_position
            }
            api_base.entity_update(models.WorklistItem, archived.id, update)
            return worklist

    # Create a new card
    if item_type == 'story':
        item = stories_api.story_get(item_id, current_user=current_user)
    elif item_type == 'task':
        item = tasks_api.task_get(item_id, current_user=current_user)
    else:
        raise ClientSideError(_("An item in a worklist must be either a "
                                "story or a task"))

    if item is None:
        raise exc.NotFound(_("%(type)s %(id)s not found") %
                           {'type': item_type, 'id': item_id})

    item_dict = {
        'list_id': worklist_id,
        'item_id': item_id,
        'item_type': item_type,
        'list_position': list_position
    }
    worklist_item = api_base.entity_create(models.WorklistItem, item_dict)

    if worklist.items is None:
        worklist.items = [worklist_item]
    else:
        worklist.items.append(worklist_item)

    return worklist
Exemplo n.º 12
0
def add_item(worklist_id, item_id, item_type, list_position,
             current_user=None):
    worklist = _worklist_get(worklist_id)
    if worklist is None:
        raise exc.NotFound(_("Worklist %s not found") % worklist_id)

    # Check if this item has an archived card in this worklist to restore
    archived = get_item_by_item_id(
        worklist, item_type, item_id, archived=True)
    if archived:
        update = {
            'archived': False,
            'list_position': list_position
        }
        api_base.entity_update(models.WorklistItem, archived.id, update)
        return worklist

    # If this worklist is a lane, check if the item has an archived card
    # somewhere in the board to restore
    if is_lane(worklist):
        board = boards.get_from_lane(worklist)
        archived = boards.get_card(board, item_type, item_id, archived=True)
        if archived:
            update = {
                'archived': False,
                'list_id': worklist_id,
                'list_position': list_position
            }
            api_base.entity_update(models.WorklistItem, archived.id, update)
            return worklist

    # Create a new card
    if item_type == 'story':
        item = stories_api.story_get(item_id, current_user=current_user)
    elif item_type == 'task':
        item = tasks_api.task_get(item_id, current_user=current_user)
    else:
        raise ClientSideError(_("An item in a worklist must be either a "
                                "story or a task"))

    if item is None:
        raise exc.NotFound(_("%(type)s %(id)s not found") %
                           {'type': item_type, 'id': item_id})

    item_dict = {
        'list_id': worklist_id,
        'item_id': item_id,
        'item_type': item_type,
        'list_position': list_position
    }
    worklist_item = api_base.entity_create(models.WorklistItem, item_dict)

    if worklist.items is None:
        worklist.items = [worklist_item]
    else:
        worklist.items.append(worklist_item)

    return worklist
Exemplo n.º 13
0
    def get_all(self, title=None, description=None, status=None,
                assignee_id=None, project_group_id=None, project_id=None,
                tags=None, marker=None, limit=None, tags_filter_type='all',
                sort_field='id', sort_dir='asc'):
        """Retrieve definitions of all of the stories.

        :param title: A string to filter the title by.
        :param description: A string to filter the description by.
        :param status: Only show stories with this particular status.
        :param assignee_id: Filter stories by who they are assigned to.
        :param project_group_id: Filter stories by project group.
        :param project_id: Filter stories by project ID.
        :param tags: A list of tags to filter by.
        :param marker: The resource id where the page should begin.
        :param limit: The number of stories to retrieve.
        :param tags_filter_type: Type of tags filter.
        :param sort_field: The name of the field to sort on.
        :param sort_dir: Sort direction for results (asc, desc).
        """

        # Boundary check on limit.
        if limit is not None:
            limit = max(0, limit)

        # Resolve the marker record.
        marker_story = stories_api.story_get(marker)

        stories = stories_api \
            .story_get_all(title=title,
                           description=description,
                           status=status,
                           assignee_id=assignee_id,
                           project_group_id=project_group_id,
                           project_id=project_id,
                           tags=tags,
                           marker=marker_story,
                           tags_filter_type=tags_filter_type,
                           limit=limit, sort_field=sort_field,
                           sort_dir=sort_dir)
        story_count = stories_api \
            .story_get_count(title=title,
                             description=description,
                             status=status,
                             assignee_id=assignee_id,
                             project_group_id=project_group_id,
                             project_id=project_id,
                             tags=tags,
                             tags_filter_type=tags_filter_type)

        # Apply the query response headers.
        if limit:
            response.headers['X-Limit'] = str(limit)
        response.headers['X-Total'] = str(story_count)
        if marker_story:
            response.headers['X-Marker'] = str(marker_story.id)

        return [wmodels.Story.from_db_model(s) for s in stories]
Exemplo n.º 14
0
def subscription_get_resource(target_type, target_id, current_user=None):
    if target_type not in SUPPORTED_TYPES:
        return None
    if target_type == 'story':
        return stories_api.story_get(target_id, current_user=current_user)
    elif target_type == 'task':
        return tasks_api.task_get(target_id, current_user=current_user)

    return api_base.entity_get(SUPPORTED_TYPES[target_type], target_id)
Exemplo n.º 15
0
def subscription_get_resource(target_type, target_id, current_user=None):
    if target_type not in SUPPORTED_TYPES:
        return None
    if target_type == 'story':
        return stories_api.story_get(target_id, current_user=current_user)
    elif target_type == 'task':
        return tasks_api.task_get(target_id, current_user=current_user)

    return api_base.entity_get(SUPPORTED_TYPES[target_type], target_id)
Exemplo n.º 16
0
    def get_one(self, story_id):
        """Retrieve details about one story.

        :param story_id: An ID of the story.
        """
        story = stories_api.story_get(story_id)

        if story:
            return create_story_wmodel(story)
        else:
            raise exc.NotFound(_("Story %s not found") % story_id)
Exemplo n.º 17
0
    def get_one(self, story_id):
        """Retrieve details about one story.

        :param story_id: An ID of the story.
        """
        story = stories_api.story_get(story_id,
                                      current_user=request.current_user_id)

        if story:
            return create_story_wmodel(story)
        else:
            raise exc.NotFound(_("Story %s not found") % story_id)
Exemplo n.º 18
0
def subscription_get_resource(target_type, target_id, current_user=None):
    if target_type not in SUPPORTED_TYPES:
        return None
    if target_type == 'story':
        return stories_api.story_get(target_id, current_user=current_user)
    elif target_type == 'task':
        return tasks_api.task_get(target_id, current_user=current_user)
    elif target_type == 'worklist':
        worklist = worklists_api.get(target_id)
        if worklists_api.visible(worklist, current_user):
            return worklist
        return None

    return api_base.entity_get(SUPPORTED_TYPES[target_type], target_id)
Exemplo n.º 19
0
def subscription_get_resource(target_type, target_id, current_user=None):
    if target_type not in SUPPORTED_TYPES:
        return None
    if target_type == 'story':
        return stories_api.story_get(target_id, current_user=current_user)
    elif target_type == 'task':
        return tasks_api.task_get(target_id, current_user=current_user)
    elif target_type == 'worklist':
        worklist = worklists_api.get(target_id)
        if worklists_api.visible(worklist, current_user):
            return worklist
        return None

    return api_base.entity_get(SUPPORTED_TYPES[target_type], target_id)
Exemplo n.º 20
0
def story_is_valid(task, branch):
    """Check that branch is restricted if story type is restricted.
    """

    story = stories_api.story_get(task.story_id)

    if not story:
        raise exc.NotFound("Story %s not found." % task.story_id)

    story_type = story_types_api.story_type_get(story.story_type_id)

    if story_type.restricted:
        if not branch.restricted:
            abort(400, _("Branch %s must be restricted.") % branch.id)
Exemplo n.º 21
0
def story_is_valid(task, branch):
    """Check that branch is restricted if story type is restricted.
    """

    story = stories_api.story_get(
        task.story_id, current_user=request.current_user_id)

    if not story:
        raise exc.NotFound("Story %s not found." % task.story_id)

    story_type = story_types_api.story_type_get(story.story_type_id)

    if story_type.restricted:
        if not branch.restricted:
            abort(400, _("Branch %s must be restricted.") % branch.id)
Exemplo n.º 22
0
    def get_one(self, story_id):
        """Retrieve details about one story.

        Example::

          curl https://my.example.org/api/v1/stories/11

        :param story_id: An ID of the story.
        """
        story = stories_api.story_get(
            story_id, current_user=request.current_user_id)

        if story:
            return create_story_wmodel(story)
        else:
            raise exc.NotFound(_("Story %s not found") % story_id)
Exemplo n.º 23
0
    def put(self, id, item_id, list_position, list_id=None,
            display_due_date=None):
        """Update a WorklistItem.

        This method also updates the positions of other items in affected
        worklists, if necessary.

        :param id: The ID of the worklist.
        :param item_id: The ID of the worklist_item to be moved.
        :param display_due_date: The ID of the due date displayed on the item.

        """
        user_id = request.current_user_id
        if not worklists_api.editable_contents(worklists_api.get(id),
                                               user_id):
            raise exc.NotFound(_("Worklist %s not found") % id)
        card = worklists_api.get_item_by_id(item_id)
        if card is None:
            raise exc.NotFound(_("Item %s seems to have been deleted, "
                                 "try refreshing your page.") % item_id)

        item = None
        if card.item_type == 'story':
            item = stories_api.story_get(
                card.item_id, current_user=request.current_user_id)
        elif card.item_type == 'task':
            item = tasks_api.task_get(
                card.item_id, current_user=request.current_user_id)

        if item is None:
            raise exc.NotFound(_("Item %s refers to a non-existent task or "
                                 "story.") % item_id)

        worklists_api.move_item(id, item_id, list_position, list_id)

        if display_due_date is not None:
            if display_due_date == -1:
                display_due_date = None
            update_dict = {
                'display_due_date': display_due_date
            }
            worklists_api.update_item(item_id, update_dict)

        updated = worklists_api.get_item_by_id(item_id)
        result = wmodels.WorklistItem.from_db_model(updated)
        result.resolve_due_date(updated)
        return result
Exemplo n.º 24
0
    def post(self, id, item_id, item_type, list_position):
        """Add an item to a worklist.

        Example::

          TODO

        :param id: The ID of the worklist.
        :param item_id: The ID of the item.
        :param item_type: The type of the item (i.e. "story" or "task").
        :param list_position: The position in the list to add the item.

        """
        user_id = request.current_user_id
        if not worklists_api.editable_contents(worklists_api.get(id), user_id):
            raise exc.NotFound(_("Worklist %s not found") % id)
        item = None
        if item_type == 'story':
            item = stories_api.story_get(item_id,
                                         current_user=request.current_user_id)
        elif item_type == 'task':
            item = tasks_api.task_get(item_id,
                                      current_user=request.current_user_id)
        if item is None:
            raise exc.NotFound(
                _("Item %s refers to a non-existent task or "
                  "story.") % item_id)

        card = worklists_api.add_item(id,
                                      item_id,
                                      item_type,
                                      list_position,
                                      current_user=request.current_user_id)

        added = {
            "worklist_id": id,
            "item_id": item_id,
            "item_title": item.title,
            "item_type": item_type,
            "position": card.list_position
        }

        events_api.worklist_contents_changed_event(id, user_id, added=added)

        return wmodels.WorklistItem.from_db_model(card)
Exemplo n.º 25
0
    def delete(self, story_id, tags):
        """Remove a list of tags from a Story.

        :param story_id: An id of a Story from which the tags should be
                         removed.
        :param tags: A list of tags to be removed.
        """

        story = stories_api.story_get(story_id)
        if not story:
            raise exc.NotFound("Story %s not found" % story_id)

        for tag in tags:
            stories_api.story_remove_tag(story_id, tag)

        events_api.tags_deleted_event(story_id=story_id,
                                      author_id=request.current_user_id,
                                      tags=tags)
Exemplo n.º 26
0
    def get_all(self, story_id=None, marker=None, limit=None):
        """Retrieve all tags for a given Story. If no story_id is provided
        all tags will be returned.

        :param story_id: Filter tags by story ID.
        """

        if not story_id:
            marker_tag = tags_api.tag_get_by_id(marker)
            tags = tags_api.tag_get_all(marker_tag, limit)

            return [wmodels.Tag.from_db_model(t) for t in tags]

        story = stories_api.story_get(story_id)
        if not story:
            raise exc.NotFound("Story %s not found" % story_id)

        return [wmodels.Tag.from_db_model(t) for t in story.tags]
Exemplo n.º 27
0
    def get_all(self, story_id=None, marker=None, limit=None):
        """Retrieve all tags for a given Story. If no story_id is provided
        all tags will be returned.

        :param story_id: Filter tags by story ID.
        """

        if not story_id:
            marker_tag = tags_api.tag_get_by_id(marker)
            tags = tags_api.tag_get_all(marker_tag, limit)

            return [wmodels.Tag.from_db_model(t) for t in tags]

        story = stories_api.story_get(story_id,
                                      current_user=request.current_user_id)
        if not story:
            raise exc.NotFound("Story %s not found" % story_id)

        return [wmodels.Tag.from_db_model(t) for t in story.tags]
Exemplo n.º 28
0
    def post(self, id, item_id, item_type, list_position):
        """Add an item to a worklist.

        Example::

          TODO

        :param id: The ID of the worklist.
        :param item_id: The ID of the item.
        :param item_type: The type of the item (i.e. "story" or "task").
        :param list_position: The position in the list to add the item.

        """
        user_id = request.current_user_id
        if not worklists_api.editable_contents(worklists_api.get(id),
                                               user_id):
            raise exc.NotFound(_("Worklist %s not found") % id)
        item = None
        if item_type == 'story':
            item = stories_api.story_get(
                item_id, current_user=request.current_user_id)
        elif item_type == 'task':
            item = tasks_api.task_get(
                item_id, current_user=request.current_user_id)
        if item is None:
            raise exc.NotFound(_("Item %s refers to a non-existent task or "
                                 "story.") % item_id)

        card = worklists_api.add_item(
            id, item_id, item_type, list_position,
            current_user=request.current_user_id)

        added = {
            "worklist_id": id,
            "item_id": item_id,
            "item_title": item.title,
            "item_type": item_type,
            "position": card.list_position
        }

        events_api.worklist_contents_changed_event(id, user_id, added=added)

        return wmodels.WorklistItem.from_db_model(card)
Exemplo n.º 29
0
def resolve_comments(event):
    event_info = {
        'comment_id': event.comment_id or None,
    }

    # Retrieve the content of the comment.
    comment = comments_api.comment_get(event.comment_id)
    event_info['comment_content'] = comment.content

    # Retrieve the story ID of the comment.
    timeline_events = timeline_api.events_get_all(comment_id=event.comment_id)
    if timeline_events:
        story = story_api.story_get(timeline_events[0].story_id)

        if story:
            event_info['story_id'] = story.id
            event_info['story_title'] = story.title

    return json.dumps(event_info)
Exemplo n.º 30
0
    def delete(self, id, item_id):
        """Remove an item from a worklist.

        Example::

          TODO

        :param id: The ID of the worklist.
        :param item_id: The ID of the worklist item to be removed.

        """
        user_id = request.current_user_id
        worklist = worklists_api.get(id)
        if not worklists_api.editable_contents(worklist, user_id):
            raise exc.NotFound(_("Worklist %s not found") % id)
        card = worklists_api.get_item_by_id(item_id)
        if card is None:
            raise exc.NotFound(_("Item %s seems to have already been deleted,"
                                 " try refreshing your page.") % item_id)

        worklists_api.archive_item(item_id)

        item = None
        if card.item_type == 'story':
            item = stories_api.story_get(
                card.item_id, current_user=user_id)
        elif card.item_type == 'task':
            item = tasks_api.task_get(
                card.item_id, current_user=user_id)
        if item is None:
            item.title = ''

        removed = {
            "worklist_id": id,
            "item_id": card.item_id,
            "item_type": card.item_type,
            "item_title": item.title
        }
        events_api.worklist_contents_changed_event(id,
                                                   user_id,
                                                   removed=removed)
Exemplo n.º 31
0
    def delete(self, id, item_id):
        """Remove an item from a worklist.

        Example::

          TODO

        :param id: The ID of the worklist.
        :param item_id: The ID of the worklist item to be removed.

        """
        user_id = request.current_user_id
        worklist = worklists_api.get(id)
        if not worklists_api.editable_contents(worklist, user_id):
            raise exc.NotFound(_("Worklist %s not found") % id)
        card = worklists_api.get_item_by_id(item_id)
        if card is None:
            raise exc.NotFound(
                _("Item %s seems to have already been deleted,"
                  " try refreshing your page.") % item_id)
        worklists_api.update_item(item_id, {'archived': True})
        worklists_api.normalize_positions(worklist)

        item = None
        if card.item_type == 'story':
            item = stories_api.story_get(card.item_id, current_user=user_id)
        elif card.item_type == 'task':
            item = tasks_api.task_get(card.item_id, current_user=user_id)
        if item is None:
            item.title = ''

        removed = {
            "worklist_id": id,
            "item_id": card.item_id,
            "item_type": card.item_type,
            "item_title": item.title
        }
        events_api.worklist_contents_changed_event(id,
                                                   user_id,
                                                   removed=removed)
Exemplo n.º 32
0
    def get_all(self, story_id=None, name=None, marker=None, limit=None,
                offset=None):
        """Retrieve all tags.

        Example::

          curl https://my.example.org/api/v1/tags

        :param story_id: Filter tags by story ID.
        :param name: Filter tags by name.
        :param marker: ID of the tag to start results from.
        :param limit: Maximum number of results per page.
        :param offset: Number of results to offset page by.
        """

        if not story_id:
            marker_tag = tags_api.tag_get_by_id(marker)
            tags = tags_api.tag_get_all(name=name,
                                        marker=marker_tag,
                                        limit=limit,
                                        offset=offset)

            result = []
            for t in tags:
                tag = wmodels.Tag.from_db_model(t)
                tag.set_popularity(t)
                result.append(tag)
            return result

        story = stories_api.story_get(
            story_id, current_user=request.current_user_id)
        if not story:
            raise exc.NotFound("Story %s not found" % story_id)

        result = []
        for t in story.tags:
            tag = wmodels.Tag.from_db_model(t)
            tag.set_popularity(t)
            result.append(tag)
        return result
Exemplo n.º 33
0
    def put(self, id, item_id, list_position, list_id=None, display_due_date=None):
        """Update a WorklistItem.

        This method also updates the positions of other items in affected
        worklists, if necessary.

        :param id: The ID of the worklist.
        :param item_id: The ID of the worklist_item to be moved.
        :param display_due_date: The ID of the due date displayed on the item.

        """
        user_id = request.current_user_id
        if not worklists_api.editable_contents(worklists_api.get(id), user_id):
            raise exc.NotFound(_("Worklist %s not found") % id)
        card = worklists_api.get_item_by_id(item_id)
        if card is None:
            raise exc.NotFound(_("Item %s seems to have been deleted, " "try refreshing your page.") % item_id)

        item = None
        if card.item_type == "story":
            item = stories_api.story_get(card.item_id, current_user=request.current_user_id)
        elif card.item_type == "task":
            item = tasks_api.task_get(card.item_id, current_user=request.current_user_id)

        if item is None:
            raise exc.NotFound(_("Item %s refers to a non-existent task or " "story.") % item_id)

        worklists_api.move_item(id, item_id, list_position, list_id)

        if display_due_date is not None:
            if display_due_date == -1:
                display_due_date = None
            update_dict = {"display_due_date": display_due_date}
            worklists_api.update_item(item_id, update_dict)

        updated = worklists_api.get_item_by_id(item_id)
        result = wmodels.WorklistItem.from_db_model(updated)
        result.resolve_due_date(updated)
        return result
Exemplo n.º 34
0
    def delete(self, story_id, tags):
        """Remove a list of tags from a Story.

        :param story_id: An id of a Story from which the tags should be
                         removed.
        :param tags: A list of tags to be removed.
        """

        story = stories_api.story_get(story_id,
                                      current_user=request.current_user_id)
        if not story:
            raise exc.NotFound("Story %s not found" % story_id)

        for tag in tags:
            stories_api.story_remove_tag(story_id,
                                         tag,
                                         current_user=request.current_user_id)

        events_api.tags_deleted_event(story_id=story_id,
                                      author_id=request.current_user_id,
                                      story_title=story.title,
                                      tags=tags)
Exemplo n.º 35
0
    def post(self, id, item_id, item_type, list_position):
        """Add an item to a worklist.

        :param id: The ID of the worklist.
        :param item_id: The ID of the item.
        :param item_type: The type of the item (i.e. "story" or "task").
        :param list_position: The position in the list to add the item.

        """
        user_id = request.current_user_id
        if not worklists_api.editable_contents(worklists_api.get(id), user_id):
            raise exc.NotFound(_("Worklist %s not found") % id)
        item = None
        if item_type == "story":
            item = stories_api.story_get(item_id, current_user=request.current_user_id)
        elif item_type == "task":
            item = tasks_api.task_get(item_id, current_user=request.current_user_id)
        if item is None:
            raise exc.NotFound(_("Item %s refers to a non-existent task or " "story.") % item_id)

        worklists_api.add_item(id, item_id, item_type, list_position, current_user=request.current_user_id)

        return wmodels.WorklistItem.from_db_model(worklists_api.get_item_at_position(id, list_position))
Exemplo n.º 36
0
    def get_all(self, title=None, description=None, status=None,
                assignee_id=None, creator_id=None, project_group_id=None,
                project_id=None, subscriber_id=None, tags=None,
                updated_since=None, marker=None, offset=None, limit=None,
                tags_filter_type='all', sort_field='id', sort_dir='asc'):
        """Retrieve definitions of all of the stories.

        Example::

          curl https://my.example.org/api/v1/stories

        :param title: A string to filter the title by.
        :param description: A string to filter the description by.
        :param status: Only show stories with this particular status.
        :param assignee_id: Filter stories by who they are assigned to.
        :param creator_id: Filter stories by who created them.
        :param project_group_id: Filter stories by project group.
        :param project_id: Filter stories by project ID.
        :param subscriber_id: Filter stories by subscriber ID.
        :param tags: A list of tags to filter by.
        :param updated_since: Filter stories by last updated time.
        :param marker: The resource id where the page should begin.
        :param offset: The offset to start the page at.
        :param limit: The number of stories to retrieve.
        :param tags_filter_type: Type of tags filter.
        :param sort_field: The name of the field to sort on.
        :param sort_dir: Sort direction for results (asc, desc).
        """

        # Boundary check on limit.
        if limit is not None:
            limit = max(0, limit)

        # Resolve the marker record.
        marker_story = None
        if marker:
            marker_story = stories_api.story_get(
                marker, current_user=request.current_user_id)

        stories = stories_api \
            .story_get_all(title=title,
                           description=description,
                           status=status,
                           assignee_id=assignee_id,
                           creator_id=creator_id,
                           project_group_id=project_group_id,
                           project_id=project_id,
                           subscriber_id=subscriber_id,
                           tags=tags,
                           updated_since=updated_since,
                           marker=marker_story,
                           offset=offset,
                           tags_filter_type=tags_filter_type,
                           limit=limit,
                           sort_field=sort_field,
                           sort_dir=sort_dir,
                           current_user=request.current_user_id)
        story_count = stories_api \
            .story_get_count(title=title,
                             description=description,
                             status=status,
                             assignee_id=assignee_id,
                             creator_id=creator_id,
                             project_group_id=project_group_id,
                             project_id=project_id,
                             subscriber_id=subscriber_id,
                             tags=tags,
                             updated_since=updated_since,
                             tags_filter_type=tags_filter_type,
                             current_user=request.current_user_id)

        # Apply the query response headers.
        if limit:
            response.headers['X-Limit'] = str(limit)
        response.headers['X-Total'] = str(story_count)
        if marker_story:
            response.headers['X-Marker'] = str(marker_story.id)
        if offset is not None:
            response.headers['X-Offset'] = str(offset)

        return [create_story_wmodel(s) for s in stories]
Exemplo n.º 37
0
    def get_all(self, title=None, creator_id=None, project_id=None,
                archived=False, user_id=None, story_id=None, task_id=None,
                hide_lanes=True, sort_field='id', sort_dir='asc',
                item_type=None, board_id=None, subscriber_id=None,
                offset=None, limit=None):
        """Retrieve definitions of all of the worklists.

        Example::

          curl https://my.example.org/api/v1/worklists

        :param title: A string to filter the title by.
        :param creator_id: Filter worklists by their creator.
        :param project_id: Filter worklists by project ID.
        :param archived: Filter worklists by whether they are archived or not.
        :param user_id: Filter worklists by the users with permissions.
        :param story_id: Filter worklists by whether they contain a story.
        :param task_id: Filter worklists by whether they contain a task.
        :param hide_lanes: If true, don't return worklists which are lanes in
                           a board.
        :param sort_field: The name of the field to sort on.
        :param sort_dir: Sort direction for results (asc, desc).
        :param item_type: Used when filtering by story_id. If
                          item_type is 'story' then only return
                          worklists that contain the story, if
                          item_type is 'task' then only return
                          worklists that contain tasks from the story,
                          otherwise return worklists that contain the
                          story or tasks from the story.
        :param board_id: Get all worklists in the board with this id. Other
                         filters are not applied.
        :param subscriber_id: Filter worklists by whether a user is subscribed.
        :param offset: Offset at which to begin the results.
        :param limit: Maximum number of results to return.

        """
        current_user = request.current_user_id

        # If a non existent story/task is requested, there is no point trying
        # to find worklists which contain it
        if story_id:
            story = stories_api.story_get(story_id, current_user=current_user)
            if story is None:
                response.headers['X-Total'] = '0'
                return []
        if task_id:
            task = tasks_api.task_get(task_id, current_user=current_user)
            if task is None:
                response.headers['X-Total'] = '0'
                return []

        worklists = worklists_api.get_all(title=title,
                                          creator_id=creator_id,
                                          project_id=project_id,
                                          archived=archived,
                                          board_id=board_id,
                                          user_id=user_id,
                                          story_id=story_id,
                                          task_id=task_id,
                                          subscriber_id=subscriber_id,
                                          sort_field=sort_field,
                                          sort_dir=sort_dir,
                                          offset=offset,
                                          limit=limit,
                                          current_user=current_user,
                                          hide_lanes=hide_lanes,
                                          item_type=item_type)
        count = worklists_api.get_count(title=title,
                                        creator_id=creator_id,
                                        project_id=project_id,
                                        archived=archived,
                                        board_id=board_id,
                                        user_id=user_id,
                                        story_id=story_id,
                                        task_id=task_id,
                                        subscriber_id=subscriber_id,
                                        current_user=current_user,
                                        hide_lanes=hide_lanes,
                                        item_type=item_type)

        visible_worklists = []
        for worklist in worklists:
            worklist_model = wmodels.Worklist.from_db_model(worklist)
            worklist_model.resolve_permissions(worklist)
            visible_items = worklists_api.get_visible_items(
                worklist, request.current_user_id)
            worklist_model.items = [
                wmodels.WorklistItem.from_db_model(item)
                for item in visible_items
            ]
            visible_worklists.append(worklist_model)

        # Apply the query response headers
        response.headers['X-Total'] = str(count)
        if limit is not None:
            response.headers['X-Limit'] = str(limit)
        if offset is not None:
            response.headers['X-Offset'] = str(offset)

        return visible_worklists
Exemplo n.º 38
0
def add_item(worklist_id,
             item_id,
             item_type,
             list_position,
             current_user=None):
    worklist = _worklist_get(worklist_id)
    if worklist is None:
        raise exc.NotFound(_("Worklist %s not found") % worklist_id)

    # If the target position is "outside" the list, override it
    if list_position > worklist.items.count():
        list_position = worklist.items.count()

    # Check if this item has an archived card in this worklist to restore
    archived = get_item_by_item_id(worklist, item_type, item_id, archived=True)
    if archived:
        update_item(archived.id, {'archived': False})
        # Move the newly unarchived card into position, and move other cards
        # to compensate for the move
        move_item(archived.id, list_position)
        return archived

    # If this worklist is a lane, check if the item has an archived card
    # somewhere in the board to restore
    if is_lane(worklist):
        board = boards.get_from_lane(worklist)
        archived = boards.get_card(board, item_type, item_id, archived=True)
        if archived:
            update_item(archived.id, {'archived': False})
            # Move the newly unarchived card into position, and move other
            # cards to compensate for the move
            move_item(archived.id, list_position, new_list_id=worklist_id)
            return archived

    # Create a new card
    if item_type == 'story':
        item = stories_api.story_get(item_id, current_user=current_user)
    elif item_type == 'task':
        item = tasks_api.task_get(item_id, current_user=current_user)
    else:
        raise ClientSideError(
            _("An item in a worklist must be either a "
              "story or a task"))

    if item is None:
        raise exc.NotFound(
            _("%(type)s %(id)s not found") % {
                'type': item_type,
                'id': item_id
            })

    card_dict = {
        'list_id': worklist_id,
        'item_id': item_id,
        'item_type': item_type,
        'list_position': 99999  # Initialise the card "outside" the list
    }
    card = api_base.entity_create(models.WorklistItem, card_dict)

    # Move the card into position, and move other cards to compensate
    card = move_item(card.id, list_position)

    if worklist.items is None:
        worklist.items = [card]
    else:
        worklist.items.append(card)

    return card
Exemplo n.º 39
0
    def get_all(self,
                title=None,
                creator_id=None,
                project_id=None,
                archived=False,
                user_id=None,
                story_id=None,
                task_id=None,
                hide_lanes=True,
                sort_field='id',
                sort_dir='asc',
                item_type=None,
                board_id=None,
                subscriber_id=None,
                offset=None,
                limit=None):
        """Retrieve definitions of all of the worklists.

        Example::

          curl https://my.example.org/api/v1/worklists

        :param title: A string to filter the title by.
        :param creator_id: Filter worklists by their creator.
        :param project_id: Filter worklists by project ID.
        :param archived: Filter worklists by whether they are archived or not.
        :param user_id: Filter worklists by the users with permissions.
        :param story_id: Filter worklists by whether they contain a story.
        :param task_id: Filter worklists by whether they contain a task.
        :param hide_lanes: If true, don't return worklists which are lanes in
                           a board.
        :param sort_field: The name of the field to sort on.
        :param sort_dir: Sort direction for results (asc, desc).
        :param item_type: Used when filtering by story_id. If
                          item_type is 'story' then only return
                          worklists that contain the story, if
                          item_type is 'task' then only return
                          worklists that contain tasks from the story,
                          otherwise return worklists that contain the
                          story or tasks from the story.
        :param board_id: Get all worklists in the board with this id. Other
                         filters are not applied.
        :param subscriber_id: Filter worklists by whether a user is subscribed.
        :param offset: Offset at which to begin the results.
        :param limit: Maximum number of results to return.

        """
        current_user = request.current_user_id

        # If a non existent story/task is requested, there is no point trying
        # to find worklists which contain it
        if story_id:
            story = stories_api.story_get(story_id, current_user=current_user)
            if story is None:
                response.headers['X-Total'] = '0'
                return []
        if task_id:
            task = tasks_api.task_get(task_id, current_user=current_user)
            if task is None:
                response.headers['X-Total'] = '0'
                return []

        worklists = worklists_api.get_all(title=title,
                                          creator_id=creator_id,
                                          project_id=project_id,
                                          archived=archived,
                                          board_id=board_id,
                                          user_id=user_id,
                                          story_id=story_id,
                                          task_id=task_id,
                                          subscriber_id=subscriber_id,
                                          sort_field=sort_field,
                                          sort_dir=sort_dir,
                                          offset=offset,
                                          limit=limit,
                                          current_user=current_user,
                                          hide_lanes=hide_lanes,
                                          item_type=item_type)
        count = worklists_api.get_count(title=title,
                                        creator_id=creator_id,
                                        project_id=project_id,
                                        archived=archived,
                                        board_id=board_id,
                                        user_id=user_id,
                                        story_id=story_id,
                                        task_id=task_id,
                                        subscriber_id=subscriber_id,
                                        current_user=current_user,
                                        hide_lanes=hide_lanes,
                                        item_type=item_type)

        visible_worklists = []
        for worklist in worklists:
            worklist_model = wmodels.Worklist.from_db_model(worklist)
            worklist_model.resolve_permissions(worklist)
            visible_items = worklists_api.get_visible_items(
                worklist, request.current_user_id)
            worklist_model.items = [
                wmodels.WorklistItem.from_db_model(item)
                for item in visible_items
            ]
            visible_worklists.append(worklist_model)

        # Apply the query response headers
        response.headers['X-Total'] = str(count)
        if limit is not None:
            response.headers['X-Limit'] = str(limit)
        if offset is not None:
            response.headers['X-Offset'] = str(offset)

        return visible_worklists
Exemplo n.º 40
0
    def put(self,
            id,
            item_id,
            list_position,
            list_id=None,
            display_due_date=None):
        """Update a WorklistItem.

        Example::

          TODO

        This method also updates the positions of other items in affected
        worklists, if necessary.

        :param id: The ID of the worklist.
        :param item_id: The ID of the worklist_item to be moved.
        :param display_due_date: The ID of the due date displayed on the item.

        """
        user_id = request.current_user_id
        if not worklists_api.editable_contents(worklists_api.get(id), user_id):
            raise exc.NotFound(_("Worklist %s not found") % id)
        card = worklists_api.get_item_by_id(item_id)
        if card is None:
            raise exc.NotFound(
                _("Item %s seems to have been deleted, "
                  "try refreshing your page.") % item_id)

        item = None
        if card.item_type == 'story':
            item = stories_api.story_get(card.item_id,
                                         current_user=request.current_user_id)
        elif card.item_type == 'task':
            item = tasks_api.task_get(card.item_id,
                                      current_user=request.current_user_id)

        if item is None:
            raise exc.NotFound(
                _("Item %s refers to a non-existent task or "
                  "story.") % item_id)

        old = {
            "worklist_id": card.list_id,
            "item_id": card.item_id,
            "item_title": item.title,
            "item_type": card.item_type,
            "position": card.list_position,
            "due_date_id": card.display_due_date
        }

        new = {
            "item_id": card.item_id,
            "item_title": item.title,
            "item_type": card.item_type
        }

        if list_position != card.list_position and list_position is not None:
            new['position'] = list_position
        if list_id != card.list_id and list_id is not None:
            new['worklist_id'] = list_id

        worklists_api.move_item(id, item_id, list_position, list_id)

        if display_due_date is not None:
            if display_due_date == -1:
                display_due_date = None
            update_dict = {'display_due_date': display_due_date}
            worklists_api.update_item(item_id, update_dict)
            new['due_date_id'] = display_due_date

        updated = {"old": old, "new": new}
        events_api.worklist_contents_changed_event(id,
                                                   user_id,
                                                   updated=updated)

        updated = worklists_api.get_item_by_id(item_id)
        result = wmodels.WorklistItem.from_db_model(updated)
        result.resolve_due_date(updated)
        return result
Exemplo n.º 41
0
    def get_all(self,
                title=None,
                description=None,
                status=None,
                assignee_id=None,
                creator_id=None,
                project_group_id=None,
                project_id=None,
                subscriber_id=None,
                tags=None,
                updated_since=None,
                marker=None,
                offset=None,
                limit=None,
                tags_filter_type='all',
                sort_field='id',
                sort_dir='asc'):
        """Retrieve definitions of all of the stories.

        Example::

          curl https://my.example.org/api/v1/stories

        :param title: A string to filter the title by.
        :param description: A string to filter the description by.
        :param status: Only show stories with this particular status.
        :param assignee_id: Filter stories by who they are assigned to.
        :param creator_id: Filter stories by who created them.
        :param project_group_id: Filter stories by project group.
        :param project_id: Filter stories by project ID.
        :param subscriber_id: Filter stories by subscriber ID.
        :param tags: A list of tags to filter by.
        :param updated_since: Filter stories by last updated time.
        :param marker: The resource id where the page should begin.
        :param offset: The offset to start the page at.
        :param limit: The number of stories to retrieve.
        :param tags_filter_type: Type of tags filter.
        :param sort_field: The name of the field to sort on.
        :param sort_dir: Sort direction for results (asc, desc).
        """

        # Boundary check on limit.
        if limit is not None:
            limit = max(0, limit)

        # Resolve the marker record.
        marker_story = None
        if marker:
            marker_story = stories_api.story_get(
                marker, current_user=request.current_user_id)

        stories = stories_api \
            .story_get_all(title=title,
                           description=description,
                           status=status,
                           assignee_id=assignee_id,
                           creator_id=creator_id,
                           project_group_id=project_group_id,
                           project_id=project_id,
                           subscriber_id=subscriber_id,
                           tags=tags,
                           updated_since=updated_since,
                           marker=marker_story,
                           offset=offset,
                           tags_filter_type=tags_filter_type,
                           limit=limit,
                           sort_field=sort_field,
                           sort_dir=sort_dir,
                           current_user=request.current_user_id)
        story_count = stories_api \
            .story_get_count(title=title,
                             description=description,
                             status=status,
                             assignee_id=assignee_id,
                             creator_id=creator_id,
                             project_group_id=project_group_id,
                             project_id=project_id,
                             subscriber_id=subscriber_id,
                             tags=tags,
                             updated_since=updated_since,
                             tags_filter_type=tags_filter_type,
                             current_user=request.current_user_id)

        # Apply the query response headers.
        if limit:
            response.headers['X-Limit'] = str(limit)
        response.headers['X-Total'] = str(story_count)
        if marker_story:
            response.headers['X-Marker'] = str(marker_story.id)
        if offset is not None:
            response.headers['X-Offset'] = str(offset)

        return [create_story_wmodel(s) for s in stories]
Exemplo n.º 42
0
    def put(self, id, item_id, list_position, list_id=None,
            display_due_date=None):
        """Update a WorklistItem.

        Example::

          TODO

        This method also updates the positions of other items in affected
        worklists, if necessary.

        :param id: The ID of the worklist.
        :param item_id: The ID of the worklist_item to be moved.
        :param display_due_date: The ID of the due date displayed on the item.

        """
        user_id = request.current_user_id
        if not worklists_api.editable_contents(worklists_api.get(id),
                                               user_id):
            raise exc.NotFound(_("Worklist %s not found") % id)
        card = worklists_api.get_item_by_id(item_id)
        if card is None:
            raise exc.NotFound(_("Item %s seems to have been deleted, "
                                 "try refreshing your page.") % item_id)

        item = None
        if card.item_type == 'story':
            item = stories_api.story_get(
                card.item_id, current_user=request.current_user_id)
        elif card.item_type == 'task':
            item = tasks_api.task_get(
                card.item_id, current_user=request.current_user_id)

        if item is None:
            raise exc.NotFound(_("Item %s refers to a non-existent task or "
                                 "story.") % item_id)

        old = {
            "worklist_id": card.list_id,
            "item_id": card.item_id,
            "item_title": item.title,
            "item_type": card.item_type,
            "position": card.list_position,
            "due_date_id": card.display_due_date
        }

        new = {
            "item_id": card.item_id,
            "item_title": item.title,
            "item_type": card.item_type
        }

        if list_position != card.list_position and list_position is not None:
            new['position'] = list_position
        if list_id != card.list_id and list_id is not None:
            new['worklist_id'] = list_id

        worklists_api.move_item(item_id, list_position, list_id)

        if display_due_date is not None:
            if display_due_date == -1:
                display_due_date = None
            update_dict = {
                'display_due_date': display_due_date
            }
            worklists_api.update_item(item_id, update_dict)
            new['due_date_id'] = display_due_date

        updated = {
            "old": old,
            "new": new
        }
        events_api.worklist_contents_changed_event(id,
                                                   user_id,
                                                   updated=updated)

        updated = worklists_api.get_item_by_id(item_id)
        result = wmodels.WorklistItem.from_db_model(updated)
        result.resolve_due_date(updated)
        return result