Exemple #1
0
def get_task_types_schedule_items(project_id):
    """
    Return all schedule items for given project. If no schedule item exists
    for a given task type, it creates one.
    """
    task_types = tasks_service.get_task_types_for_project(project_id)
    task_type_map = base_service.get_model_map_from_array(task_types)
    schedule_items = set(
        ScheduleItem.query.filter_by(project_id=project_id).filter(
            ScheduleItem.object_id == None).all())
    schedule_item_map = {
        str(schedule_item.task_type_id): schedule_item
        for schedule_item in schedule_items
    }

    new_schedule_items = set()
    schedule_item_to_remove = set()
    for schedule_item in schedule_items:
        if schedule_item.task_type_id is not None:
            if str(schedule_item.task_type_id) not in task_type_map:
                schedule_item_to_remove.add(schedule_item)

    for task_type in task_types:
        if task_type["id"] not in schedule_item_map:
            new_schedule_item = ScheduleItem.create(
                project_id=project_id,
                start_date=date.today(),
                end_date=date.today() + timedelta(days=1),
                task_type_id=task_type["id"],
            )
            new_schedule_items.add(new_schedule_item)
            events.emit("schedule-item:new",
                        {"schedule_item_id": str(new_schedule_item.id)},
                        project_id=project_id)

    schedule_items = (schedule_items.union(new_schedule_items) -
                      schedule_item_to_remove)
    return sorted(
        [schedule_item.present() for schedule_item in schedule_items],
        key=lambda x: x["start_date"],
    )
def create_notifications_for_task_and_comment(task, comment, change=False):
    """
    For given task and comment, create a notification for every assignee
    to the task and to every person participating to this task.
    """
    task = tasks_service.get_task(task["id"])
    recipient_ids = get_notification_recipients(task)
    recipient_ids.remove(comment["person_id"])

    for recipient_id in recipient_ids:
        try:
            notification = create_notification(
                recipient_id,
                comment_id=comment["id"],
                author_id=comment["person_id"],
                task_id=comment["object_id"],
                read=False,
                change=change,
                type="comment"
            )
            events.emit("notification:new", {
                "notification_id": notification["id"],
                "person_id": recipient_id
            }, persist=False)
        except PersonNotFoundException:
            pass

    for recipient_id in comment["mentions"]:
        notification = create_notification(
            recipient_id,
            comment_id=comment["id"],
            author_id=comment["person_id"],
            task_id=comment["object_id"],
            type="mention"
        )
        events.emit("notification:new", {
            "notification_id": notification["id"],
            "person_id": recipient_id
        }, persist=False)

    return recipient_ids
def remove_task(task_id, force=False):
    """
    Remove given task. Force deletion if the task has some comments and files
    related. This will lead to the deletion of all of them.
    """
    task = Task.get(task_id)
    entity = Entity.get(task.entity_id)

    if force:
        working_files = WorkingFile.query.filter_by(task_id=task_id)
        for working_file in working_files:
            output_files = OutputFile.query.filter_by(
                source_file_id=working_file.id)
            for output_file in output_files:
                output_file.delete()
            working_file.delete()

        comments = Comment.query.filter_by(object_id=task_id)
        for comment in comments:
            notifications = Notification.query.filter_by(comment_id=comment.id)
            for notification in notifications:
                notification.delete()
            comment.delete()

        subscriptions = Subscription.query.filter_by(task_id=task_id)
        for subscription in subscriptions:
            subscription.delete()

        preview_files = PreviewFile.query.filter_by(task_id=task_id)
        for preview_file in preview_files:
            if entity.preview_file_id == preview_file.id:
                entity.update({"preview_file_id": None})
            remove_preview_file(preview_file)

        time_spents = TimeSpent.query.filter_by(task_id=task_id)
        for time_spent in time_spents:
            time_spent.delete()

    task.delete()
    events.emit("task:delete", {"task_id": task_id})
    return task.serialize()
Exemple #4
0
def remove_person(person_id, force=True):
    person = Person.get(person_id)
    if force:
        for comment in Comment.get_all_by(person_id=person_id):
            remove_comment(comment.id)
        ApiEvent.delete_all_by(user_id=person_id)
        Notification.delete_all_by(person_id=person_id)
        SearchFilter.delete_all_by(person_id=person_id)
        DesktopLoginLog.delete_all_by(person_id=person_id)
        LoginLog.delete_all_by(person_id=person_id)
        Subscription.delete_all_by(person_id=person_id)
        TimeSpent.delete_all_by(person_id=person_id)
        for project in Project.query.filter(Project.team.contains(person)):
            project.team = [
                member for member in project.team
                if str(member.id) != person_id
            ]
            project.save()
        for task in Task.query.filter(Task.assignees.contains(person)):
            task.assignees = [
                assignee for assignee in task.assignees
                if str(assignee.id) != person_id
            ]
            task.save()
        for task in Task.get_all_by(assigner_id=person_id):
            task.update({"assigner_id": None})
        for output_file in OutputFile.get_all_by(person_id=person_id):
            output_file.update({"person_id": None})
        for working_file in WorkingFile.get_all_by(person_id=person_id):
            output_file.update({"person_id": None})
        for task in WorkingFile.get_all_by(person_id=person_id):
            output_file.update({"person_id": None})

    try:
        person.delete()
        events.emit("person:delete", {"person_id": person.id})
    except IntegrityError:
        raise ModelWithRelationsDeletionException(
            "Some data are still linked to given person.")

    return person.serialize_safe()
Exemple #5
0
def remove_metadata_descriptor(metadata_descriptor_id):
    """
    Delete metadata descriptor and related informations.
    """
    descriptor = get_metadata_descriptor_raw(metadata_descriptor_id)
    entities = Entity.get_all_by(project_id=descriptor.project_id)
    for entity in entities:
        metadata = fields.serialize_value(entity.data)
        if metadata is not None:
            metadata.pop(descriptor.field_name, None)
            entity.update({"data": metadata})
    try:
        descriptor.delete()
    except ObjectDeletedError:
        pass
    events.emit(
        "metadata-descriptor:delete",
        {"metadata_descriptor_id": str(descriptor.id)},
    )
    clear_project_cache(str(descriptor.project_id))
    return descriptor.serialize()
Exemple #6
0
def create_shot(project_id, sequence_id, name, data={}):
    """
    Create shot for given project and sequence.
    """
    shot_type = get_shot_type()

    if sequence_id is not None:
        get_sequence(sequence_id)  # raises SequenceNotFound if it fails.

    shot = Entity.get_by(entity_type_id=shot_type["id"],
                         parent_id=sequence_id,
                         project_id=project_id,
                         name=name)
    if shot is None:
        shot = Entity.create(entity_type_id=shot_type["id"],
                             project_id=project_id,
                             parent_id=sequence_id,
                             name=name,
                             data=data)
    events.emit("shot:new", {"shot_id": shot.id})
    return shot.serialize(obj_type="Shot")
Exemple #7
0
 def emit_app_preview_event(self, preview_file_id):
     """
     Emit an event, each time a preview is added.
     """
     preview_file = files_service.get_preview_file(preview_file_id)
     comment = tasks_service.get_comment_by_preview_file_id(preview_file_id)
     task = tasks_service.get_task(preview_file["task_id"])
     comment_id = None
     if comment is not None:
         comment_id = comment["id"]
         events.emit("comment:update", {"comment_id": comment_id},
                     project_id=task["project_id"])
         events.emit("preview-file:add-file", {
             "comment_id": comment_id,
             "task_id": preview_file["task_id"],
             "preview_file_id": preview_file["id"],
             "revision": preview_file["revision"],
             "extension": preview_file["extension"],
             "status": preview_file["status"],
         },
                     project_id=task["project_id"])
Exemple #8
0
def assign_task(task_id, person_id):
    """
    Assign given person to given task. Emit a *task:assign* event.
    """
    task = get_task_raw(task_id)
    project_id = str(task.project_id)
    person = persons_service.get_person_raw(person_id)
    task.assignees.append(person)
    task.save()
    task_dict = task.serialize()
    events.emit(
        "task:assign",
        {
            "task_id": task.id,
            "person_id": person.id
        },
        project_id=project_id,
    )
    clear_task_cache(task_id)
    events.emit("task:update", {"task_id": task_id}, project_id=project_id)
    return task_dict
Exemple #9
0
def update_metadata_descriptor(metadata_descriptor_id, changes):
    """
    Update metadata descriptor information for given id.
    """
    descriptor = get_metadata_descriptor_raw(metadata_descriptor_id)
    entities = Entity.get_all_by(project_id=descriptor.project_id)
    if "name" in changes and len(changes["name"]) > 0:
        changes["field_name"] = slugify.slugify(changes["name"])
        for entity in entities:
            metadata = fields.serialize_value(entity.data) or {}
            value = metadata.pop(descriptor.field_name, None)
            if value is not None:
                metadata[changes["field_name"]] = value
                entity.update({"data": metadata})
    descriptor.update(changes)
    events.emit(
        "metadata-descriptor:update",
        {"metadata_descriptor_id": str(descriptor.id)},
    )
    clear_project_cache(str(descriptor.project_id))
    return descriptor.serialize()
Exemple #10
0
def _finalize_task_creation(task_type, task_status, task):
    task_dict = task.serialize()
    task_dict["assignees"] = []
    task_dict.update(
        {
            "task_status_id": task_status["id"],
            "task_status_name": task_status["name"],
            "task_status_short_name": task_status["short_name"],
            "task_status_color": task_status["color"],
            "task_type_id": task_type["id"],
            "task_type_name": task_type["name"],
            "task_type_color": task_type["color"],
            "task_type_priority": task_type["priority"],
        }
    )
    events.emit(
        "task:new",
        {"task_id": task.id},
        project_id=task_dict["project_id"]
    )
    return task_dict
Exemple #11
0
def get_or_create_status(name,
                         short_name="",
                         color="#f5f5f5",
                         is_reviewable=False,
                         is_done=False):
    """
    Create a new task status if it doesn't exist. If it exists, it returns the
    status from database.
    """
    task_status = TaskStatus.get_by(name=name)
    if task_status is None and len(short_name) > 0:
        task_status = TaskStatus.get_by(short_name=short_name)

    if task_status is None:
        task_status = TaskStatus.create(name=name,
                                        short_name=short_name or name.lower(),
                                        color=color,
                                        is_reviewable=is_reviewable,
                                        is_done=is_done)
        events.emit("task_status:new", {"task_status_id": task_status.id})
    return task_status.serialize()
Exemple #12
0
def clear_assignation(task_id):
    """
    Clear task assignation and emit a *task:unassign* event.
    """
    task = get_task_raw(task_id)
    project_id = str(task.project_id)
    assignees = [person.serialize() for person in task.assignees]
    task.update({"assignees": []})
    clear_task_cache(task_id)
    task_dict = task.serialize()
    for assignee in assignees:
        events.emit(
            "task:unassign",
            {
                "person_id": assignee["id"],
                "task_id": task_id
            },
            project_id=project_id,
        )
    events.emit("task:update", {"task_id": task_id}, project_id=project_id)
    return task_dict
Exemple #13
0
def remove_asset_link(asset_in_id, asset_out_id):
    """
    Remove link asset together, unmark asset_in as asset out dependency.
    """
    asset_in = get_asset_raw(asset_in_id)
    asset_out = get_asset_raw(asset_out_id)

    if asset_out in asset_in.entities_out:
        asset_in.entities_out = [
            x for x in asset_in.entities_out if x.id != asset_out_id
        ]
        asset_in.save()
        events.emit(
            "asset:remove-link",
            {
                "asset_in": asset_in.id,
                "asset_out": asset_out.id
            },
            project_id=str(asset_in.project_id),
        )
    return asset_in.serialize(obj_type="Asset")
Exemple #14
0
def update_casting(entity_id, casting):
    """
    Update casting for given entity. Casting is an array of dictionaries made of
    two fields: `asset_id` and `nb_occurences`.
    """
    entity = entities_service.get_entity_raw(entity_id)
    entity.update({"entities_out": []})
    for cast in casting:
        if "asset_id" in cast and "nb_occurences" in cast:
            create_casting_link(
                entity.id,
                cast["asset_id"],
                nb_occurences=cast["nb_occurences"],
                label=cast.get("label", ""),
            )
    entity_id = str(entity.id)
    if shots_service.is_shot(entity.serialize()):
        events.emit("shot:casting-update", {"shot_id": entity_id})
    else:
        events.emit("asset:casting-update", {"asset_id": entity_id})
    return casting
Exemple #15
0
    def delete(self, instance_id):
        parser = reqparse.RequestParser()
        parser.add_argument("force", default=False, type=bool)
        args = parser.parse_args()

        project = self.get_model_or_404(instance_id)
        project_dict = project.serialize()
        if projects_service.is_open(project_dict):
            return {
                "error": True,
                "message": "Only closed projects can be deleted",
            }, 400
        else:
            self.check_delete_permissions(project_dict)
            if args["force"] is True:
                deletion_service.remove_project(instance_id)
            else:
                project.delete()
                events.emit("project:delete", {"project_id": project.id})
            self.post_delete(project_dict)
            return "", 204
Exemple #16
0
def remove_build_job(playlist, build_job_id):
    """
    Remove build job from database and remove related temporary file from
    hard drive.
    """
    job = BuildJob.get(build_job_id)
    movie_file_path = get_playlist_movie_file_path(playlist, job.serialize())
    if os.path.exists(movie_file_path):
        os.remove(movie_file_path)
    try:
        file_store.remove_movie("playlists", build_job_id)
    except:
        current_app.logger.error("Playlist file can't be deleted: %s" %
                                 build_job_id)
    job.delete()
    events.emit("build-job:delete", {
        "build_job_id": build_job_id,
        "playlist_id": playlist["id"]
    },
                project_id=playlist["project_id"])
    return movie_file_path
Exemple #17
0
def delete_reply(comment_id, reply_id):
    comment = tasks_service.get_comment_raw(comment_id)
    task = tasks_service.get_task(comment.object_id)
    if comment.replies is None:
        comment.replies = []
    comment.replies = [
        reply for reply in comment.replies if reply["id"] != reply_id
    ]
    comment.save()
    Notification.delete_all_by(reply_id=reply_id)
    events.emit(
        "comment:delete-reply",
        {
            "task_id": task["id"],
            "comment_id": str(comment.id),
            "reply_id": reply_id,
        },
        project_id=task["project_id"],
        persist=False,
    )
    return comment.serialize()
Exemple #18
0
    def put(self, instance_id):
        """
        Update a model with data given in the request body. JSON format is
        expected. Model performs the validation automatically when fields are
        modified.
        """
        try:
            data = self.get_arguments()
            instance = self.get_model_or_404(instance_id)
            self.check_update_permissions(instance.serialize(), data)
            data = self.update_data(data, instance_id)
            instance.update(data)
            events.emit(
                "%s:update" % self.model.__tablename__,
                {"%s_id" % self.model.__tablename__: instance.id}
            )

            instance_dict = instance.serialize()
            self.post_update(instance_dict)
            return instance_dict, 200

        except StatementError as exception:
            current_app.logger.error(str(exception))
            return {"message": "Wrong id format"}, 400

        except TypeError as exception:
            current_app.logger.error(str(exception))
            return {"message": str(exception)}, 400

        except IntegrityError as exception:
            current_app.logger.error(str(exception))
            return {"message": str(exception)}, 400

        except StatementError as exception:
            current_app.logger.error(str(exception))
            return {"message": str(exception)}, 400

        except ArgumentsException as exception:
            current_app.logger.error(str(exception))
            return {"message": str(exception)}, 400
Exemple #19
0
def create_task(task_type, entity, name="main"):
    """
    Create a new task for given task type and entity.
    """
    task_status = get_todo_status()
    try:
        try:
            current_user_id = persons_service.get_current_user()["id"]
        except RuntimeError:
            current_user_id = None
        task = Task.create(name=name,
                           duration=0,
                           estimation=0,
                           completion_rate=0,
                           start_date=None,
                           end_date=None,
                           due_date=None,
                           real_start_date=None,
                           project_id=entity["project_id"],
                           task_type_id=task_type["id"],
                           task_status_id=task_status["id"],
                           entity_id=entity["id"],
                           assigner_id=current_user_id,
                           assignees=[])
        task_dict = task.serialize()
        task_dict.update({
            "task_status_id": task_status["id"],
            "task_status_name": task_status["name"],
            "task_status_short_name": task_status["short_name"],
            "task_status_color": task_status["color"],
            "task_type_id": task_type["id"],
            "task_type_name": task_type["name"],
            "task_type_color": task_type["color"],
            "task_type_priority": task_type["priority"]
        })
        events.emit("task:new", {"task_id": task.id})
        return task_dict

    except IntegrityError:
        pass  # Tasks already exists, no need to create it.
Exemple #20
0
def create_shot(project_id,
                sequence_id,
                name,
                data={},
                nb_frames=0,
                description=None):
    """
    Create shot for given project and sequence.
    """
    shot_type = get_shot_type()

    if sequence_id is not None:
        # raises SequenceNotFound if it fails.
        sequence = get_sequence(sequence_id)

    shot = Entity.get_by(
        entity_type_id=shot_type["id"],
        parent_id=sequence_id,
        project_id=project_id,
        name=name,
    )
    if shot is None:
        shot = Entity.create(
            entity_type_id=shot_type["id"],
            project_id=project_id,
            parent_id=sequence_id,
            name=name,
            data=data,
            nb_frames=nb_frames,
            description=description,
        )
    events.emit(
        "shot:new",
        {
            "shot_id": shot.id,
            "episode_id": sequence["parent_id"],
        },
        project_id=project_id,
    )
    return shot.serialize(obj_type="Shot")
Exemple #21
0
 def test_register_all(self):
     event_map = {
         "task:start": self,
         "task:new": self
     }
     events.register_all(event_map)
     events.emit("task:start")
     self.assertEqual(self.counter, 2)
     events.emit("task:stop")
     self.assertEqual(self.counter, 2)
     events.emit("task:start")
     self.assertEqual(self.counter, 3)
     events.emit("task:new")
     self.assertEqual(self.counter, 4)
Exemple #22
0
def get_entity_schedule_items(project_id, task_type_id, to_create,
                              to_create_map, existing_schedule_items):
    schedule_item_map = {
        str(schedule_item.object_id): schedule_item
        for schedule_item in existing_schedule_items
    }

    new_schedule_items = set()
    schedule_item_to_remove = set()
    for schedule_item in existing_schedule_items:
        if schedule_item.object_id is not None:
            if str(schedule_item.object_id) not in to_create_map:
                schedule_item_to_remove.add(schedule_item)

    for entity in to_create:
        if entity["id"] not in schedule_item_map:
            new_schedule_item = ScheduleItem.create(
                project_id=project_id,
                start_date=date.today(),
                end_date=date.today() + timedelta(days=1),
                object_id=entity["id"],
                task_type_id=task_type_id,
            )
            events.emit(
                "schedule-item:new",
                {"schedule_item_id": str(new_schedule_item.id)},
                project_id=project_id,
            )
            new_schedule_items.add(new_schedule_item)

    schedule_items = (existing_schedule_items.union(new_schedule_items) -
                      schedule_item_to_remove)

    results = []
    for schedule_item in schedule_items:
        result = schedule_item.present()
        result["name"] = to_create_map[result["object_id"]]["name"]
        results.append(result)

    return sorted(results, key=lambda x: x["name"])
Exemple #23
0
    def test_register(self):
        events.register("task:start", "inc_counter", self)
        events.emit("task:start")
        self.assertEqual(self.counter, 2)
        events.emit("task:stop")
        self.assertEqual(self.counter, 2)
        events.emit("task:start")
        self.assertEqual(self.counter, 3)

        event_models = events_service.get_last_events()
        self.assertEquals(len(event_models), 3)
        events.emit("task:start", persist=False)
        event_models = events_service.get_last_events()
        self.assertEquals(len(event_models), 3)
Exemple #24
0
def create_person(
    email,
    password,
    first_name,
    last_name,
    phone="",
    role="user",
    desktop_login="",
    departments=[],
):
    """
    Create a new person entry in the database. No operation are performed on
    password, so encrypted password is expected.
    """
    if email is not None:
        email = email.strip()
    if not departments:
        departments = []

    try:
        departments_objects = [
            Department.get(department_id) for department_id in departments
            if department_id is not None
        ]
    except StatementError:
        raise DepartmentNotFoundException()

    person = Person.create(
        email=email,
        password=password,
        first_name=first_name,
        last_name=last_name,
        phone=phone,
        role=role,
        desktop_login=desktop_login,
        departments=departments_objects,
    )
    events.emit("person:new", {"person_id": person.id})
    clear_person_cache()
    return person.serialize(relations=True)
def create_notifications_for_task_and_comment(task, comment, change=False):
    """
    For given task and comment, create a notification for every assignee
    to the task and to every person participating to this task.
    """
    task = tasks_service.get_task(task["id"])
    recipient_ids = get_notification_recipients(task)
    recipient_ids.remove(comment["person_id"])

    for recipient_id in recipient_ids:
        try:
            person = persons_service.get_person(recipient_id)
            notification = create_notification(
                person, comment, read=False, change=change
            )
            events.emit("notifications:new", {
                "id": notification["id"],
                "person_id": recipient_id
            })
        except PersonNotFoundException:
            pass
    return recipient_ids
Exemple #26
0
def remove_project(project_id):
    from zou.app.services import playlists_service

    tasks = Task.query.filter_by(project_id=project_id)
    for task in tasks:
        remove_task(task.id, force=True)

    query = EntityLink.query.join(Entity,
                                  EntityLink.entity_in_id == Entity.id).filter(
                                      Entity.project_id == project_id)
    for link in query:
        link.delete_no_commit()
    EntityLink.commit()

    query = EntityVersion.query.join(
        Entity, EntityVersion.entity_id == Entity.id).filter(
            Entity.project_id == project_id)
    for version in query:
        version.delete_no_commit()
    EntityLink.commit()

    playlists = Playlist.query.filter_by(project_id=project_id)
    for playlist in playlists:
        playlists_service.remove_playlist(playlist.id)

    ApiEvent.delete_all_by(project_id=project_id)
    Entity.delete_all_by(project_id=project_id)
    MetadataDescriptor.delete_all_by(project_id=project_id)
    Milestone.delete_all_by(project_id=project_id)
    ScheduleItem.delete_all_by(project_id=project_id)
    SearchFilter.delete_all_by(project_id=project_id)

    for news in News.query.join(Task).filter_by(project_id=project_id).all():
        news.delete_no_commit()
    News.commit()
    project = Project.get(project_id)
    project.delete()
    events.emit("project:delete", {"project_id": project.id})
    return project_id
Exemple #27
0
def new_comment(task_id,
                task_status_id,
                person_id,
                text,
                object_type="Task",
                files={},
                checklist=[],
                created_at=""):
    """
    Create a new comment for given object (by default, it considers this object
    as a Task).
    """
    created_at_date = None
    task = tasks_service.get_task(task_id)
    if created_at is not None and len(created_at) > 0:
        try:
            created_at_date = fields.get_date_object(
                created_at, date_format="%Y-%m-%d %H:%M:%S")
        except ValueError:
            pass

    comment = Comment.create(object_id=task_id,
                             object_type=object_type,
                             task_status_id=task_status_id,
                             person_id=person_id,
                             mentions=get_comment_mentions(task_id, text),
                             checklist=checklist,
                             text=text,
                             created_at=created_at_date)

    comment = comment.serialize(relations=True)
    comment["attachment_files"] = []
    for uploaded_file in files.values():
        attachment_file = create_attachment(comment, uploaded_file)
        comment["attachment_files"].append(attachment_file)

    events.emit("comment:new", {"comment_id": comment["id"]},
                project_id=task["project_id"])
    return comment
Exemple #28
0
def start_task(task):
    wip_status = get_wip_status()
    task_is_not_already_wip = \
        task.task_status_id is None \
        or task.task_status_id != wip_status.id

    if task_is_not_already_wip:
        task_dict_before = task.serialize()

        new_data = {"task_status_id": wip_status.id}
        if task.real_start_date is None:
            new_data["real_start_date"] = datetime.datetime.now()

        task.update(new_data)

        task_dict_after = task.serialize()
        events.emit("task:start", {
            "task_before": task_dict_before,
            "task_after": task_dict_after
        })

    return task
Exemple #29
0
def add_preview_file_to_comment(comment_id, person_id, task_id, revision=0):
    """
    Add a preview to comment preview list. Auto set the revision field
    (add 1 if it's a new preview, keep the preview revision in other cases).
    """
    comment = get_comment_raw(comment_id)
    news = News.get_by(comment_id=comment_id)
    if revision == 0 and len(comment.previews) == 0:
        revision = get_next_preview_revision(task_id)
    elif revision == 0:
        revision = comment.previews[0].revision

    preview_file = files_service.create_preview_file_raw(
        str(uuid.uuid4())[:13], revision, task_id, person_id
    )
    events.emit("preview-file:create", {"preview_file_id": preview_file.id})
    comment.previews.append(preview_file)
    comment.save()
    if news is not None:
        news.update({"preview_file_id": preview_file.id})
    events.emit("comment:update", {"comment_id": comment.id})
    return preview_file.serialize()
Exemple #30
0
def create_comment(
    object_id,
    task_status_id,
    person_id,
    text,
    object_type="Task"
):
    """
    Create a new comment for given object (by default, it considers this object
    as a Task).
    """
    comment = Comment.create(
        object_id=object_id,
        object_type=object_type,
        task_status_id=task_status_id,
        person_id=person_id,
        text=text
    )
    events.emit("comment:new", {
        "comment_id": comment.id,
    })
    return comment.serialize()