コード例 #1
0
 def test_create_tasks(self):
     shot = self.shot.serialize()
     shot_2 = self.generate_fixture_shot("S02").serialize()
     task_type = self.task_type.serialize()
     status = tasks_service.get_todo_status()
     tasks = tasks_service.create_tasks(task_type, [shot, shot_2])
     self.assertEqual(len(tasks), 2)
     task = tasks[0]
     task = tasks_service.get_task(task["id"])
     self.assertEqual(task["entity_id"], shot["id"])
     self.assertEqual(task["task_type_id"], task_type["id"])
     self.assertEqual(task["project_id"], shot["project_id"])
     self.assertEqual(task["task_status_id"], status["id"])
コード例 #2
0
ファイル: resources.py プロジェクト: NeroSouza/zou
    def get(self, file_id):
        try:
            file_dict = files_service.get_working_file(file_id)
            task = tasks_service.get_task(file_dict["task_id"])
            project_id = task["project_id"]
        except WorkingFileNotFoundException:
            file_dict = files_service.get_output_file(file_id)
            entity = entities_service.get_entity(file_dict["entity_id"])
            project_id = entity["project_id"]

        if not permissions.has_manager_permissions():
            user_service.check_has_task_related(project_id)
        return file_dict
コード例 #3
0
ファイル: resources.py プロジェクト: ricekab/zou
 def delete(self, task_id, comment_id):
     """
     Delete a comment corresponding at given ID.
     """
     comment = tasks_service.get_comment(comment_id)
     task = tasks_service.get_task(comment["object_id"])
     user_service.check_manager_project_access(task["project_id"])
     self.pre_delete(comment)
     deletion_service.remove_comment(comment_id)
     tasks_service.reset_task_data(comment["object_id"])
     tasks_service.clear_comment_cache(comment_id)
     self.post_delete(comment)
     return "", 204
コード例 #4
0
    def post(self, task_id, comment_id, preview_file_id):
        task = tasks_service.get_task(task_id)
        user_service.check_project_access(task["project_id"])
        user_service.check_entity_access(task["entity_id"])
        tasks_service.get_comment(comment_id)

        person = persons_service.get_current_user()
        related_preview_file = files_service.get_preview_file(preview_file_id)

        preview_file = tasks_service.add_preview_file_to_comment(
            comment_id, person["id"], task_id,
            related_preview_file["revision"])
        return preview_file, 201
コード例 #5
0
ファイル: news_service.py プロジェクト: flavienliger/zou
def delete_news_for_comment(comment_id):
    """
    Delete all news related to comment. It's mandatory to be able to delete the
    comment afterwards.
    """
    news_list = News.get_all_by(comment_id=comment_id)
    if len(news_list) > 0:
        task = tasks_service.get_task(news_list[0].task_id)
        for news in news_list:
            news.delete()
            events.emit("news:delete", {"news_id": news.id},
                        project_id=task["project_id"])
    return fields.serialize_list(news_list)
コード例 #6
0
    def put(self):
        (task_ids) = self.get_arguments()

        if len(task_ids) > 0:
            task = tasks_service.get_task(task_ids[0])
            user_service.check_manager_project_access(task["project_id"])

        for task_id in task_ids:
            try:
                tasks_service.clear_assignation(task_id)
            except TaskNotFoundException:
                pass
        return task_ids
コード例 #7
0
ファイル: resources.py プロジェクト: Arubinu/zou
    def post(self, task_id):
        (task_status_id, comment, person_id) = self.get_arguments()

        task = tasks_service.get_task(task_id)
        user_service.check_project_access(task["project_id"])

        task_status = tasks_service.get_task_status(task_status_id)

        if person_id:
            person = persons_service.get_person(person_id)
        else:
            person = persons_service.get_current_user()

        comment = tasks_service.create_comment(object_id=task_id,
                                               object_type="Task",
                                               task_status_id=task_status_id,
                                               person_id=person["id"],
                                               text=comment)

        status_changed = task_status_id != task["task_status_id"]
        new_data = {
            "task_status_id": task_status_id,
            "last_comment_date": comment["created_at"]
        }
        if status_changed:
            if task_status["is_retake"]:
                retake_count = task["retake_count"]
                if retake_count is None or retake_count == 'NoneType':
                    retake_count = 0
                new_data["retake_count"] = retake_count + 1

            if task_status["is_done"]:
                new_data["end_date"] = datetime.datetime.now()
            else:
                new_data["end_date"] = None

            if task_status["short_name"] == "wip" \
               and task["real_start_date"] is None:
                new_data["real_start_date"] = datetime.datetime.now()

        tasks_service.update_task(task_id, new_data)

        notifications_service.create_notifications_for_task_and_comment(
            task, comment, change=status_changed)
        news_service.create_news_for_task_and_comment(task,
                                                      comment,
                                                      change=status_changed)

        comment["task_status"] = task_status
        comment["person"] = person
        return comment, 201
コード例 #8
0
ファイル: test_preview_file.py プロジェクト: mathbou/zou
    def test_get_preview_files_for_artist(self):
        """
        Test route data/preview-files for artist.
        Artists can only access previews linked to projects he works on.
        """
        route = "data/preview-files"
        project1_id = str(self.project1.id)

        self.log_in_cg_artist()
        preview_files_artist = self.get(route)
        for preview_file in preview_files_artist:
            task = tasks_service.get_task(preview_file["task_id"])
            self.assertEqual(task["project_id"], project1_id)
        self.assertEqual(len(preview_files_artist), 2)
コード例 #9
0
ファイル: resources.py プロジェクト: unit-image/zou
    def get(self, task_id):
        result = {}

        task = tasks_service.get_task(task_id)
        user_service.check_project_access(task["project_id"])

        options = request.args
        relations = options.get("relations", "false").lower() == "true"

        result = files_service.get_working_files_for_task(
            task["id"],
            relations=relations)

        return result
コード例 #10
0
ファイル: test_permission.py プロジェクト: tokejepsen/zou
    def test_has_task_related_team(self):
        self.log_in_cg_artist()
        self.generate_fixture_asset_type()
        self.generate_fixture_asset()
        self.generate_assigned_task()
        task_id = self.task.id
        project_id = self.project.id
        self.get("data/assets/%s" % self.asset.id, 403)

        self.task = tasks_service.get_task(task_id)
        projects_service.update_project(project_id,
                                        {"team": [self.user_cg_artist]})
        self.project.save()
        self.get("data/assets/%s" % self.asset.id, 200)
コード例 #11
0
ファイル: resources.py プロジェクト: NeroSouza/zou
    def post(self, task_id):
        (task_status_id, comment, person_id) = self.get_arguments()

        tasks_service.get_task(task_id)
        if not permissions.has_manager_permissions():
            user_service.check_assigned(task_id)
        task_status = tasks_service.get_task_status(task_status_id)
        if person_id:
            person = persons_service.get_person(person_id)
        else:
            person = persons_service.get_current_user()
        comment = tasks_service.create_comment(object_id=task_id,
                                               object_type="Task",
                                               task_status_id=task_status_id,
                                               person_id=person["id"],
                                               text=comment)

        tasks_service.update_task(task_id, {"task_status_id": task_status_id})

        comment["task_status"] = task_status
        comment["person"] = person
        events.emit("comment:new", {"id": comment["id"]})
        return comment, 201
コード例 #12
0
ファイル: resources.py プロジェクト: LarsCawley/zou
 def post_delete(self, comment):
     task = tasks_service.get_task(comment["object_id"])
     self.new_task_status_id = task["task_status_id"]
     if self.previous_task_status_id != self.new_task_status_id:
         events.emit(
             "task:status-changed",
             {
                 "task_id": task["id"],
                 "new_task_status_id": self.new_task_status_id,
                 "previous_task_status_id": self.previous_task_status_id
             },
             project_id=task["project_id"]
         )
     return comment
コード例 #13
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"],
            "task_id": task_id
        },
        project_id=task["project_id"],
    )
    return comment
コード例 #14
0
def check_comment_access(comment_id):
    """
    Return true if current user can have access to a comment.
    """
    if permissions.has_admin_permissions():
        return True
    else:
        comment = tasks_service.get_comment(comment_id)
        person_id = comment["person_id"]
        task_id = comment["object_id"]
        task = tasks_service.get_task(task_id)
        if task is None:
            tasks_service.clear_task_cache(task_id)
            task = tasks_service.get_task(task_id)
        check_project_access(task["project_id"])
        check_entity_access(task["entity_id"])

        if (
            permissions.has_supervisor_permissions()
            or permissions.has_manager_permissions()
        ):
            return True
        elif permissions.has_client_permissions():
            current_user = persons_service.get_current_user()
            project = projects_service.get_project(task["project_id"])
            if project.get("is_clients_isolated", False):
                if not comment["person_id"] == current_user["id"]:
                    raise permissions.PermissionDenied
            if persons_service.get_person(person_id)["role"] == "client":
                return True
            else:
                raise permissions.PermissionDenied
        elif persons_service.get_person(person_id)["role"] == "client":
            raise permissions.PermissionDenied

        return True
コード例 #15
0
ファイル: resources.py プロジェクト: dsparrow27/zou
    def put(self, task_id):
        (person_id) = self.get_arguments()

        try:
            task = tasks_service.get_task(task_id)
            user_service.check_manager_project_access(task["project_id"])

            self.assign_task(task_id, person_id)
            notifications_service.create_assignation_notification(
                task_id, person_id)
            projects_service.add_team_member(task["project_id"], person_id)
        except PersonNotFoundException:
            return {"error": "Assignee doesn't exist in database."}, 400

        return task
コード例 #16
0
    def post(self, task_id, date, person_id):
        args = self.get_arguments()

        try:
            task = tasks_service.get_task(task_id)
            user_service.check_project_access(task["project_id"])

            persons_service.get_person(person_id)
            time_spent = tasks_service.create_or_update_time_spent(
                task_id, person_id, date, args["duration"], add=True)
            return time_spent, 201
        except ValueError:
            abort(404)
        except WrongDateFormatException:
            abort(404)
コード例 #17
0
ファイル: test_preview_file.py プロジェクト: mathbou/zou
    def test_get_preview_file_for_artist(self):
        """
        Test route data/preview-files/<preview_file_id> for artist.
        Artists can only access previews linked to projects he works on.
        """
        route1_1 = "data/preview-files/%s" % str(self.preview_file1_1.id)
        route2_1 = "data/preview-files/%s" % str(self.preview_file2_1.id)
        project1_id = str(self.project1.id)

        self.log_in_cg_artist()
        preview_file_artist1_1 = self.get(route1_1)
        task_related = tasks_service.get_task(
            preview_file_artist1_1["task_id"])
        self.assertEqual(task_related["project_id"], project1_id)
        self.get(route2_1, code=403)
コード例 #18
0
def get_preview_file_name(preview_file_id):
    """
    Build unique and human readable file name for preview downloads. The
    convention followed is:
    [project_name]_[entity_name]_[task_type_name]_v[revivision].[extension].
    """
    preview_file = files_service.get_preview_file(preview_file_id)
    task = tasks_service.get_task(preview_file["task_id"])
    task_type = tasks_service.get_task_type(task["task_type_id"])
    project = projects_service.get_project(task["project_id"])
    (entity_name, _) = get_full_entity_name(task["entity_id"])
    name = "%s_%s_%s_v%s" % (project["name"], entity_name, task_type["name"],
                             preview_file["revision"])
    return "%s.%s" % (slugify.slugify(
        name, separator="_"), preview_file["extension"])
コード例 #19
0
ファイル: resources.py プロジェクト: LarsCawley/zou
 def delete(self, task_id, comment_id):
     """
     Delete a comment corresponding at given ID.
     """
     comment = tasks_service.get_comment(comment_id)
     task = tasks_service.get_task(comment["object_id"])
     if permissions.has_manager_permissions():
         user_service.check_project_access(task["project_id"])
     else:
         user_service.check_working_on_entity(task["entity_id"])
     self.pre_delete(comment)
     deletion_service.remove_comment(comment_id)
     tasks_service.reset_task_data(comment["object_id"])
     tasks_service.clear_comment_cache(comment_id)
     self.post_delete(comment)
     return "", 204
コード例 #20
0
    def post(self, task_id):
        (task_status_id, comment, person_id, created_at,
         checklist) = self.get_arguments()

        task = tasks_service.get_task(task_id)
        user_service.check_project_access(task["project_id"])
        user_service.check_entity_access(task["entity_id"])
        files = request.files

        if not permissions.has_manager_permissions():
            person_id = None
            created_at = None
        comment = comments_service.create_comment(person_id, task_id,
                                                  task_status_id, comment,
                                                  checklist, files, created_at)
        return comment, 201
コード例 #21
0
ファイル: test_tasks_service.py プロジェクト: withgame/zou
    def test_get_task(self):
        self.assertRaises(
            TaskNotFoundException,
            tasks_service.get_task,
            "wrong-id"
        )
        task = tasks_service.get_task(self.task_id)
        self.assertEqual(str(self.task_id), task["id"])
        self.output_file.delete()
        self.working_file.delete()
        deletion_service.remove_task(task["id"])

        self.assertRaises(
            TaskNotFoundException,
            tasks_service.get_task,
            str(self.task_id)
        )
コード例 #22
0
ファイル: comments_service.py プロジェクト: ddesmond/zou
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()
    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()
コード例 #23
0
def check_project_departement_access(task_id, person_id):
    """
    Return true if current user is admin or is manager and is in team
    or is artist in the task department.
    """
    user = persons_service.get_current_user(relations=True)
    task = tasks_service.get_task(task_id)
    task_type = tasks_service.get_task_type(task["task_type_id"])
    is_allowed = (permissions.has_admin_permissions()
                  or (permissions.has_manager_permissions()
                      and check_belong_to_project(task["project_id"]))
                  or (check_belong_to_project(task["project_id"])
                      and task_type["department_id"] in user["departments"]
                      and person_id == user["id"]))
    if not is_allowed:
        raise permissions.PermissionDenied
    return is_allowed
コード例 #24
0
 def get(self, attachment_file_id):
     attachment_file = comments_service.get_attachment_file(
         attachment_file_id)
     comment = tasks_service.get_comment(attachment_file["comment_id"])
     task = tasks_service.get_task(comment["object_id"])
     user_service.check_project_access(task["project_id"])
     file_path = comments_service.get_attachment_file_path(attachment_file)
     try:
         return flask_send_file(
             file_path,
             conditional=True,
             mimetype=attachment_file["mimetype"],
             as_attachment=False,
             attachment_filename=attachment_file["name"],
         )
     except:
         abort(404)
コード例 #25
0
ファイル: resources.py プロジェクト: mathbou/zou
    def post(self, task_id):
        (
            name,
            mode,
            software_id,
            comment,
            revision,
            separator,
        ) = self.get_arguments()

        try:
            task = tasks_service.get_task(task_id)
            user_service.check_project_access(task["project_id"])
            user_service.check_entity_access(task["entity_id"])

            software = files_service.get_software(software_id)
            is_revision_set_by_user = revision != 0
            if not is_revision_set_by_user:
                revision = files_service.get_next_working_file_revision(
                    task_id, name)
            file_path = file_tree_service.get_working_folder_path(
                task,
                mode=mode,
                software=software,
                name=name,
                sep=separator,
                revision=revision,
            )
            file_name = file_tree_service.get_working_file_name(
                task,
                mode=mode,
                revision=revision,
                software=software,
                name=name,
            )
        except MalformedFileTreeException as exception:
            return (
                {
                    "message": str(exception),
                    "received_data": request.json
                },
                400,
            )

        return {"path": file_path, "name": file_name}, 200
コード例 #26
0
ファイル: notifications_service.py プロジェクト: Arubinu/zou
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"])
    author_id = comment["person_id"]

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

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

    return recipient_ids
コード例 #27
0
def generate_playlisted_shot_from_task(task_id):
    previews = {}
    task = tasks_service.get_task(task_id)
    shot = shots_service.get_shot(task["entity_id"])
    sequence = shots_service.get_sequence(shot["parent_id"])
    preview_files = get_preview_files_for_task(task_id)
    task_type_id = task["task_type_id"]
    shot["preview_file_task_id"] = task_id
    shot["sequence_id"] = sequence["id"]
    shot["sequence_name"] = sequence["name"]
    if len(preview_files) > 0:
        previews[task_type_id] = get_playlist_preview_file_list(preview_files)
        shot["preview_file_id"] = previews[task_type_id][0]["id"]
        shot["preview_file_extension"] = previews[task_type_id][0]["extension"]
        shot["preview_file_annotations"] = previews[task_type_id][0][
            "annotations"]
    shot["preview_files"] = previews
    return shot
コード例 #28
0
 def build_row(self, shot):
     name, _ = names_service.get_full_entity_name(shot["entity_id"])
     preview_file = files_service.get_preview_file(shot["preview_file_id"])
     task = tasks_service.get_task(shot["preview_file_task_id"])
     task_type = self.task_type_map[task["task_type_id"]]
     task_status = self.task_status_map[task["task_status_id"]]
     comment = self.task_comment_map.get(task["id"], {})
     author = self.get_author(comment)
     date = self.get_date(comment)
     return [
         name,
         task_type["name"],
         preview_file["revision"],
         task_status["name"],
         author,
         date,
         comment.get("text",""),
     ]
コード例 #29
0
ファイル: resources.py プロジェクト: NeroSouza/zou
    def post(self, task_id):
        (
            name,
            mode,
            software_id,
            comment,
            revision,
            separator
        ) = self.get_arguments()

        try:
            task = tasks_service.get_task(task_id)
            if not permissions.has_manager_permissions():
                user_service.check_has_task_related(task["project_id"])

            software = files_service.get_software(software_id)
            is_revision_set_by_user = revision != 0
            if not is_revision_set_by_user:
                revision = files_service.get_next_working_file_revision(
                    task_id,
                    name
                )
            file_path = file_tree_service.get_working_folder_path(
                task,
                mode=mode,
                software=software,
                name=name,
                sep=separator
            )
            file_name = file_tree_service.get_working_file_name(
                task,
                mode=mode,
                revision=revision,
                software=software,
                name=name
            )
        except MalformedFileTreeException:
            return {
                "error":
                    "Tree is not properly written, check modes and variables",
                "received_data": request.json,
            }, 400

        return {"path": file_path, "name": file_name}, 200
コード例 #30
0
    def put(self, task_id):
        """
        Assign given task list to given person.
        ---
        tags:
        - Tasks
        parameters:
          - in: path
            name: task_id
            required: True
            schema:
                type: UUID
                example: a24a6ea4-ce75-4665-a070-57453082c25
          - in: body
            name: Person
            description: Person ID
            schema:
                type: object
                required:
                  - person_id
                properties:
                    person_id:
                        type: UUID
                        example: a24a6ea4-ce75-4665-a070-57453082c25
        responses:
            200:
                description: Given task assigned to given person
            400:
                description: Assignee non-existent in database
        """
        (person_id) = self.get_arguments()

        try:
            task = tasks_service.get_task(task_id)
            user_service.check_manager_project_access(task["project_id"])

            self.assign_task(task_id, person_id)
            notifications_service.create_assignation_notification(
                task_id, person_id)
            projects_service.add_team_member(task["project_id"], person_id)
        except PersonNotFoundException:
            return {"error": "Assignee doesn't exist in database."}, 400

        return task