Esempio n. 1
0
    def test_import_asset(self):
        self.generate_fixture_asset_type()
        self.generate_fixture_project_status()
        self.generate_fixture_project()
        self.generate_fixture_sequence()
        self.generate_fixture_shot()
        self.shot.update({"shotgun_id": 3})

        self.load_fixture("projects")
        self.load_fixture("assets")
        sg_asset = {
            "code": "Cake",
            "description": "yellow cake",
            "project": {
                "type": "Project",
                "id": 1,
                "name": "Agent 327"
            },
            "sg_asset_type": "Props",
            "type": "Asset",
            "parents": [{
                "type": "Asset",
                "id": 1
            }],
            "id": 3,
        }

        api_path = "/import/shotgun/assets"
        self.assets = self.post(api_path, [sg_asset], 200)
        self.assertEqual(len(self.assets), 1)

        self.assets = self.get("data/assets/all")
        self.assertEqual(len(self.assets), 3)

        assets = sorted(self.assets, key=lambda x: x["name"])
        asset = assets[0]
        asset = assets_service.get_asset_with_relations(asset["id"])
        project = Project.get_by(shotgun_id=sg_asset["project"]["id"])
        self.assertEqual(asset["description"], sg_asset["description"])
        self.assertEqual(asset["shotgun_id"], sg_asset["id"])
        self.assertEqual(asset["project_id"], str(project.id))
        self.assertEqual(len(asset["entities_out"]), 0)

        parent = Entity.get_by(shotgun_id=1)
        self.assertEqual(str(parent.entities_out[0].id), asset["id"])
Esempio n. 2
0
def task_to_review(
    task_id,
    person,
    comment,
    preview_path={},
    change_status=True
):
    """
    Change the task status to "waiting for approval" if it is not already the
    case. It emits a *task:to-review* event.
    """
    task = get_task_raw(task_id)
    to_review_status = get_to_review_status()
    task_dict_before = task.serialize()

    if change_status:
        task.update({"task_status_id": to_review_status["id"]})
        task.save()

    project = Project.get(task.project_id)
    entity = Entity.get(task.entity_id)
    entity_type = EntityType.get(entity.entity_type_id)

    task_dict_after = task.serialize()
    task_dict_after["project"] = project.serialize()
    task_dict_after["entity"] = entity.serialize()
    task_dict_after["entity_type"] = entity_type.serialize()
    task_dict_after["person"] = person
    task_dict_after["comment"] = comment
    task_dict_after["preview_path"] = preview_path

    events.emit("task:to-review", {
        "task_id": task_id,
        "task_shotgun_id": task_dict_before["shotgun_id"],
        "entity_type_name": entity_type.name,
        "previous_task_status_id": task_dict_before["task_status_id"],
        "entity_shotgun_id": entity.shotgun_id,
        "project_shotgun_id": project.shotgun_id,
        "person_shotgun_id": person["shotgun_id"],
        "comment": comment,
        "preview_path": preview_path,
        "change_status": change_status
    })

    return task_dict_after
Esempio n. 3
0
    def test_remove_asset_with_working_files(self):
        self.load_fixture("projects")
        self.load_fixture("assets")
        sg_asset = {
            "code": "Cake",
            "description": "yellow cake",
            "project": {
                "type": "Project",
                "id": 1,
                "name": "Cosmos Landromat"
            },
            "sg_asset_type": "Props",
            "type": "Asset",
            "parents": [],
            "id": 3,
        }

        api_path = "/import/shotgun/assets"
        self.assets = self.post(api_path, [sg_asset], 200)
        asset = self.assets[0]
        self.asset = Entity.get(asset["id"])
        self.generate_fixture_project_status()
        self.generate_fixture_file_status()
        self.generate_fixture_person()
        self.generate_fixture_assigner()
        self.generate_fixture_software()
        self.generate_fixture_project()
        self.generate_fixture_department()
        self.generate_fixture_task_type()
        self.generate_fixture_task_status()

        self.generate_fixture_task()
        self.generate_fixture_working_file()

        self.assets = self.get("data/assets/all")
        self.assertEqual(len(self.assets), 3)

        api_path = "/import/shotgun/remove/asset"
        self.assets = self.post(api_path, {"id": sg_asset["id"]}, 200)

        self.assets = self.get("data/assets/all")
        self.assertEqual(len(self.assets), 3)

        asset = self.get("data/assets/%s" % asset["id"], 200)
        self.assertTrue(asset["canceled"])
Esempio n. 4
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",
                {"descriptor_id": str(descriptor.id)})
    return descriptor.serialize()
Esempio n. 5
0
File: base.py Progetto: mathbou/zou
    def generate_fixture_scene(
        self, name="SC01", project_id=None, sequence_id=None
    ):
        if project_id is None:
            project_id = self.project.id

        if sequence_id is None:
            sequence_id = self.sequence.id

        self.scene = Entity.create(
            name=name,
            description="Description Scene 01",
            data={},
            project_id=project_id,
            entity_type_id=self.scene_type.id,
            parent_id=self.sequence.id,
        )
        return self.scene
Esempio n. 6
0
def remove_metadata_descriptor(metadata_descriptor_id):
    """
    Deletee 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",
                {"descriptor_id": str(descriptor.id)})
    return descriptor.serialize()
Esempio n. 7
0
def get_entities_for_project(project_id,
                             entity_type_id,
                             obj_type="Entity",
                             only_assigned=False):
    """
    Retrieve all entities related to given project of which entity is entity
    type.
    """
    from zou.app.services import user_service
    query = (Entity.query.filter(
        Entity.entity_type_id == entity_type_id).filter(
            Entity.project_id == project_id).order_by(Entity.name))
    if only_assigned:
        query = query \
            .outerjoin(Task) \
            .filter(user_service.build_assignee_filter())
    result = query.all()
    return Entity.serialize_list(result, obj_type=obj_type)
Esempio n. 8
0
    def import_entry(self, data):
        entity = None
        parent_shotgun_ids = data["parent_shotgun_ids"]
        del data["parent_shotgun_ids"]

        try:
            entity = self.save_entity(data)
        except IntegrityError:
            current_app.logger.error("Similar asset already exists "
                                     "or project is missing: %s" % data)

        if entity is not None:
            for parent_shotgun_id in parent_shotgun_ids:
                self.parent_map.setdefault(parent_shotgun_id, [])
                self.parent_map[parent_shotgun_id].append(Entity.get(
                    entity.id))

        return entity
Esempio n. 9
0
def get_episode_raw(episode_id):
    """
    Return given episode as an active record.
    """
    episode_type = get_episode_type()
    if episode_type is None:
        episode_type = get_episode_type()

    try:
        episode = Entity.get_by(
            entity_type_id=episode_type["id"], id=episode_id
        )
    except StatementError:
        raise EpisodeNotFoundException

    if episode is None:
        raise EpisodeNotFoundException
    return episode
Esempio n. 10
0
def remove_sequence(sequence_id, force=False):
    """
    Remove a sequence and all related shots.
    """
    sequence = get_sequence_raw(sequence_id)
    if force:
        for shot in Entity.get_all_by(parent_id=sequence_id):
            remove_shot(shot.id, force=True)
        Subscription.delete_all_by(entity_id=sequence_id)
        ScheduleItem.delete_all_by(object_id=sequence_id)
    try:
        sequence.delete()
    except IntegrityError:
        raise ModelWithRelationsDeletionException(
            "Some data are still linked to this sequence."
        )
    clear_sequence_cache(sequence_id)
    return sequence.serialize(obj_type="Sequence")
Esempio n. 11
0
def get_project_sequences(project_id):
    shot_type = shots_service.get_shot_type()
    sequence_type = shots_service.get_sequence_type()

    Shot = aliased(Entity, name='shot')
    query = Entity.query \
        .join(Shot, Shot.parent_id == Entity.id) \
        .join(Task, Task.entity_id == Shot.id) \
        .join(EntityType, EntityType.id == Entity.entity_type_id) \
        .join(Project, Project.id == Entity.project_id) \
        .join(ProjectStatus) \
        .filter(Shot.entity_type_id == shot_type["id"]) \
        .filter(Entity.entity_type_id == sequence_type["id"]) \
        .filter(Project.id == project_id) \
        .filter(assignee_filter()) \
        .filter(open_project_filter())

    return Entity.serialize_list(query.all(), obj_type="Sequence")
Esempio n. 12
0
def get_or_create_sequence(project_id, episode_id, name):
    sequence_type = get_sequence_type()
    sequence = Entity.get_by(entity_type_id=sequence_type["id"],
                             parent_id=episode_id,
                             project_id=project_id,
                             name=name)
    if sequence is None:
        sequence = Entity(entity_type_id=sequence_type["id"],
                          parent_id=episode_id,
                          project_id=project_id,
                          name=name)
        sequence.save()
    return sequence.serialize()
Esempio n. 13
0
File: base.py Progetto: ricekab/zou
    def generate_fixture_sequence(
        self,
        name="S01",
        episode_id=None,
        project_id=None
    ):
        if episode_id is None and hasattr(self, "episode"):
            episode_id = self.episode.id

        if project_id is None:
            project_id = self.project.id

        self.sequence = Entity.create(
            name=name,
            project_id=project_id,
            entity_type_id=self.sequence_type.id,
            parent_id=episode_id
        )
        return self.sequence
Esempio n. 14
0
def create_asset(project_id, asset_type_id, name, description, data):
    """
    Create a new asset from given parameters.
    """
    project = projects_service.get_project_raw(project_id)
    asset_type = get_asset_type_raw(asset_type_id)

    asset = Entity.create(project_id=project_id,
                          entity_type_id=asset_type_id,
                          name=name,
                          description=description,
                          data=data)
    asset_dict = asset.serialize(obj_type="Asset")
    events.emit("asset:new", {
        "asset": asset.id,
        "asset_type": asset_type.id,
        "project_id": project.id
    })
    return asset_dict
Esempio n. 15
0
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:
            remove_preview_file(preview_file)

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

        notifications = Notification.query.filter_by(task_id=task_id)
        for notification in notifications:
            notification.delete()

    task.delete()
    events.emit("task:delete", {"task_id": task_id})
    return task.serialize()
Esempio n. 16
0
def guess_asset(project, asset_type_name, asset_name):

    asset_type_id = None
    if len(asset_type_name) > 0:
        asset_type = EntityType.get_by(name=asset_type_name)
        if asset_type is not None:
            asset_type_id = asset_type.id

    if len(asset_name) > 0:
        asset = Entity.get_by(
            name=asset_name,
            entity_type_id=asset_type_id,
            project_id=project["id"],
        )
    else:
        raise WrongPathFormatException(
            "Asset name was not found in given path.")

    return asset
Esempio n. 17
0
def update_entity_preview(entity_id, preview_file_id):
    """
    Update given entity main preview. If entity or preview is not found, it
    raises an exception.
    """
    entity = Entity.get(entity_id)
    if entity is None:
        raise EntityNotFoundException

    preview_file = PreviewFile.get(preview_file_id)
    if preview_file is None:
        raise PreviewFileNotFoundException

    entity.update({"preview_file_id": preview_file.id})
    events.emit("preview-file:set-main", {
        "entity_id": entity_id,
        "preview_file_id": preview_file_id
    })
    return entity.serialize()
Esempio n. 18
0
def get_or_create_episode(project_id, name):
    """
    Retrieve episode matching given project and name or create it.
    """
    episode_type = get_episode_type()
    episode = Entity.get_by(
        entity_type_id=episode_type["id"], project_id=project_id, name=name
    )
    if episode is None:
        episode = Entity(
            entity_type_id=episode_type["id"], project_id=project_id, name=name
        )
        episode.save()
    return episode.serialize()
    def test_import_scene(self):
        self.load_fixture("projects")
        self.load_fixture("sequences")

        api_path = "/import/shotgun/scenes"
        self.scenes = self.post(api_path, [self.sg_scene], 200)
        self.assertEqual(len(self.scenes), 1)

        self.scenes = self.get("data/scenes/all")
        self.assertEqual(len(self.scenes), 1)

        scene = self.scenes[0]
        sequence = Entity.get_by(
            shotgun_id=self.sg_scene["sequence_sg_scenes_1_sequences"][0]["id"],
            entity_type_id=shots_service.get_sequence_type()["id"]
        )
        project = Project.get_by(name=self.sg_scene["project"]["name"])
        self.assertEqual(scene["name"], self.sg_scene["code"])
        self.assertEqual(scene["parent_id"], str(sequence.id))
        self.assertEqual(scene["project_id"], str(project.id))
Esempio n. 20
0
    def save_entity(self, data):
        entity = None
        entities = asset_info.get_assets({"shotgun_id": data["shotgun_id"]})
        if len(entities) > 0:
            entity = entities[0]

        if entity is None:
            entity = Entity(**data)
            entity.save()
            current_app.logger.info("Entity created: %s" % entity)
        else:
            entity.update(data)
            current_app.logger.info("Entity updated: %s" % entity)

        return entity
Esempio n. 21
0
def remove_preview_file(preview_file):
    """
    Remove all files related to given preview file, then remove the preview file
    entry from the database.
    """
    task = Task.get(preview_file.task_id)
    entity = Entity.get(task.entity_id)
    if entity.preview_file_id == preview_file.id:
        entity.update({"preview_file_id": None})

    if preview_file.extension == "png":
        clear_picture_files(preview_file.id)
    elif preview_file.extension == "mp4":
        clear_movie_files(preview_file.id)
    else:
        clear_generic_files(preview_file.id)

    preview_file.comments = []
    preview_file.save()
    preview_file.delete()
    return preview_file.serialize()
Esempio n. 22
0
def sync_entity_thumbnails(project, model_name):
    """
    Once every preview files and entities has been imported, this function
    allows you to import project entities again to set thumbnails id (link to
    a preview file) for all entities.
    """
    results = gazu.client.fetch_all("projects/%s/%s" %
                                    (project["id"], model_name))
    total = 0
    for result in results:
        if result.get("preview_file_id") is not None:
            entity = Entity.get(result["id"])
            try:
                entity.update({
                    "preview_file_id": result["preview_file_id"],
                    "updated_at": result["updated_at"],
                })
                total += 1
            except sqlalchemy.exc.IntegrityError:
                logger.error("An error occured", exc_info=1)
    logger.info("    %s %s thumbnails synced." % (total, model_name))
Esempio n. 23
0
    def post_processing(self):
        # We handle the fact that an asset can have multiple parents by using
        # the entities out field as a children field.
        for key in self.parent_map.keys():
            try:
                asset = assets_service.get_asset_by_shotgun_id(key)

                asset = assets_service.get_full_asset(asset['id'])
                former_children = [
                    Entity.get(child_id)
                    for child_id in asset.get('entities_out', [])
                ]
                children = list(set(self.parent_map[key] + former_children))
                data = {"entities_out": children}

                assets_service.update_asset(asset["id"], data)
                assets_service.clear_asset_cache(asset["id"])
            except AssetNotFoundException:
                pass

        return self.parent_map
Esempio n. 24
0
def get_sequences_for_project(project_id):
    """
    Return all sequences for given project and for which current user has
    a task assigned to a shot.
    """
    shot_type = shots_service.get_shot_type()
    sequence_type = shots_service.get_sequence_type()

    Shot = aliased(Entity, name="shot")
    query = (Entity.query.join(Shot, Shot.parent_id == Entity.id).join(
        Task, Task.entity_id == Shot.id).join(
            EntityType, EntityType.id == Entity.entity_type_id).join(
                Project,
                Project.id == Entity.project_id).join(ProjectStatus).filter(
                    Shot.entity_type_id == shot_type["id"]).filter(
                        Entity.entity_type_id == sequence_type["id"]).filter(
                            Project.id == project_id).filter(
                                build_assignee_filter()).filter(
                                    build_open_project_filter()))

    return Entity.serialize_list(query.all(), obj_type="Sequence")
Esempio n. 25
0
def get_or_create_sequence(project_id, episode_id, name):
    """
    Retrieve sequence matching given project, episode and name or create it.
    """
    sequence_type = get_sequence_type()
    sequence = Entity.get_by(entity_type_id=sequence_type["id"],
                             parent_id=episode_id,
                             project_id=project_id,
                             name=name)
    if sequence is None:
        sequence = Entity(entity_type_id=sequence_type["id"],
                          parent_id=episode_id,
                          project_id=project_id,
                          name=name)
        sequence.save()
    return sequence.serialize()
 def setUp(self):
     super(FileTreeTestCase, self).setUp()
     self.generate_fixture_project_status()
     self.generate_fixture_project()
     self.generate_fixture_project_standard()
     self.generate_fixture_asset_type()
     self.generate_fixture_asset()
     self.generate_fixture_episode()
     self.generate_fixture_sequence()
     self.generate_fixture_shot()
     self.generate_fixture_scene()
     self.generate_fixture_sequence_standard()
     self.generate_fixture_shot_standard()
     self.generate_fixture_person()
     self.generate_fixture_department()
     self.generate_fixture_task_type()
     self.generate_fixture_task_status()
     self.generate_fixture_assigner()
     self.generate_fixture_task()
     self.generate_fixture_shot_task()
     self.generate_fixture_shot_task_standard()
     self.generate_fixture_software()
     self.asset_standard = Entity(
         name='Car',
         project_id=self.project_standard.id,
         entity_type_id=self.asset_type.id
     )
     self.asset_standard.save()
     self.sequence_standard = Entity(
         name='Seq1',
         project_id=self.project.id,
         entity_type_id=self.sequence_type.id
     )
     self.sequence_standard.save()
     self.shot_standard = Entity(
         name='P001',
         project_id=self.project_standard.id,
         entity_type_id=self.shot_type.id,
         parent_id=self.sequence_standard.id
     )
     self.shot_standard.save()
     self.output_type_materials = files_service.get_or_create_output_type(
         "Materials")
     self.output_type_cache = files_service.get_or_create_output_type(
         "Cache")
     self.output_type_image = files_service.get_or_create_output_type(
         "Images")
Esempio n. 27
0
 def test_update_metadata_descriptor(self):
     asset = self.generate_fixture_asset_type()
     asset = self.generate_fixture_asset()
     descriptor = projects_service.add_metadata_descriptor(
         self.project.id,
         "Asset",
         "Contractor",
         []
     )
     asset.update({
         "data": {
             "contractor": "contractor 1"
         }
     })
     self.assertTrue("contractor" in asset.data)
     projects_service.update_metadata_descriptor(
         descriptor["id"],
         {"name": "Team"}
     )
     descriptors = projects_service.get_metadata_descriptors(self.project.id)
     self.assertEqual(len(descriptors), 1)
     asset = Entity.get(asset.id)
     self.assertEqual(asset.data.get("team"), "contractor 1")
Esempio n. 28
0
    def test_add_delete_metadata_descriptor(self):
        asset = self.generate_fixture_asset_type()
        asset = self.generate_fixture_asset()
        descriptor = projects_service.add_metadata_descriptor(
            self.project.id,
            "Asset",
            "Contractor",
            []
        )
        asset.update({
            "data": {
                "contractor": "contractor 1"
            }
        })
        self.assertTrue("contractor" in asset.data)

        projects_service.remove_metadata_descriptor(
            descriptor["id"]
        )
        descriptors = projects_service.get_metadata_descriptors(self.project.id)
        self.assertEqual(len(descriptors), 0)
        asset = Entity.get(asset.id)
        self.assertFalse("contractor" in asset.data)
Esempio n. 29
0
    def get(self, instance_id):
        try:
            task = task_info.get_task(instance_id)
        except TaskNotFoundException:
            abort(404)

        result = task.serialize()
        task_type = TaskType.get(task.task_type_id)
        result["task_type"] = task_type.serialize()
        assigner = Person.get(task.assigner_id)
        result["assigner"] = assigner.serialize()
        project = Project.get(task.project_id)
        result["project"] = project.serialize()
        task_status = TaskStatus.get(task.task_status_id)
        result["task_status"] = task_status.serialize()
        entity = Entity.get(task.entity_id)
        result["entity"] = entity.serialize()
        assignees = []
        for assignee in task.assignees:
            assignees.append(assignee.serialize())
        result["persons"] = assignees

        return result, 200
Esempio n. 30
0
    def test_set_main_preview(self):
        path = "/pictures/preview-files/%s" % self.preview_file_id

        file_path_fixture = self.get_fixture_file_path(
            os.path.join("thumbnails", "th01.png"))
        self.upload_file(path, file_path_fixture)

        path = \
            "/actions/preview-files/%s/set-main-preview" % self.preview_file_id
        self.put(path, {})

        asset = assets_service.get_asset(self.asset_id)
        self.assertEqual(asset["preview_file_id"], str(self.preview_file_id))

        self.put(
            "/actions/entities/%s/set-main-preview/%s" %
            (self.preview_file_id, self.preview_file_id), {}, 404)

        self.put(
            "/actions/entities/%s/set-main-preview/%s" %
            (self.asset_id, self.asset_id), {}, 404)
        entity = Entity.get(self.asset_id)
        entity.preview_file_id = None
        entity.save()