示例#1
0
def get_full_entity_name(entity_id):
    """
    Get full entity name whether it's an asset or a shot. If it's a shot
    the result is "Episode name / Sequence name / Shot name". If it's an
    asset the result is "Asset type name / Asset name".
    """
    entity = entities_service.get_entity(entity_id)
    episode_id = None
    if shots_service.is_shot(entity):
        sequence = entities_service.get_entity(entity["parent_id"])
        if sequence["parent_id"] is None:
            name = "%s / %s" % (sequence["name"], entity["name"])
        else:
            episode = entities_service.get_entity(sequence["parent_id"])
            episode_id = episode["id"]
            name = "%s / %s / %s" % (
                episode["name"],
                sequence["name"],
                entity["name"],
            )
    else:
        asset_type = entities_service.get_entity_type(entity["entity_type_id"])
        episode_id = entity["source_id"]
        name = "%s / %s" % (asset_type["name"], entity["name"])
    return (name, episode_id)
示例#2
0
def generate_playlisted_entity_from_task(task_id):
    """
    Generate the data structure of a playlisted shot for a given task. It
    doesn't persist anything.
    """
    task = tasks_service.get_task(task_id)
    entity = entities_service.get_entity(task["entity_id"])
    if shots_service.is_shot(entity):
        playlisted_entity = get_base_shot_for_playlist(entity, task_id)
    else:
        playlisted_entity = get_base_asset_for_playlist(entity, task_id)

    task_type_id = task["task_type_id"]
    preview_files = get_preview_files_for_entity(entity["id"])
    if task_type_id in preview_files and len(preview_files[task_type_id]) > 0:
        preview_file = preview_files[task_type_id][0]
        playlisted_entity.update({
            "preview_file_id":
            preview_file["id"],
            "preview_file_extension":
            preview_file["extension"],
            "preview_file_status":
            preview_file["status"],
            "preview_file_annotations":
            preview_file["annotations"],
            "preview_file_previews":
            preview_file["previews"],
        })
    playlisted_entity["preview_files"] = preview_files
    return playlisted_entity
示例#3
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},
            project_id=str(entity.project_id),
        )
    else:
        events.emit(
            "asset:casting-update",
            {"asset_id": entity_id},
            project_id=str(entity.project_id),
        )
    return casting
示例#4
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()
            entity = self.get_model_or_404(instance_id)
            self.check_update_permissions(entity.serialize(), data)

            extra_data = copy.copy(entity.data) or {}
            if "data" not in data or data["data"] is None:
                data["data"] = {}
            extra_data.update(data["data"])
            data["data"] = extra_data

            previous_version = entity.serialize()
            data = self.update_data(data, instance_id)
            if data.get("source_id", None) == "null":
                data["source_id"] = None

            is_ready_for_changed = \
                str(entity.ready_for) != data.get("ready_for", "")
            entity.update(data)
            entity_dict = self.serialize_instance(entity)

            if shots_service.is_shot(entity_dict):
                shots_service.clear_shot_cache(entity_dict["id"])
                self.save_version_if_needed(entity_dict, previous_version)
            elif assets_service.is_asset(entity):
                if is_ready_for_changed:
                    breakdown_service.refresh_casting_stats(entity_dict)
                assets_service.clear_asset_cache(entity_dict["id"])
            elif shots_service.is_sequence(entity_dict):
                shots_service.clear_sequence_cache(entity_dict["id"])
            elif shots_service.is_episode(entity_dict):
                shots_service.clear_episode_cache(entity_dict["id"])

            self.emit_update_event(entity_dict)
            return entity_dict, 200

        except StatementError as exception:
            current_app.logger.error(str(exception), exc_info=1)
            return {"error": True, "message": str(exception)}, 400
        except TypeError as exception:
            current_app.logger.error(str(exception), exc_info=1)
            return {"error": True, "message": str(exception)}, 400
        except IntegrityError as exception:
            current_app.logger.error(str(exception), exc_info=1)
            return {"error": True, "message": str(exception)}, 400
        except StatementError as exception:
            current_app.logger.error(str(exception), exc_info=1)
            return {"error": True, "message": str(exception)}, 400
        except NotFound as exception:
            return {"error": True, "message": str(exception)}, 404
        except Exception as exception:
            current_app.logger.error(str(exception), exc_info=1)
            return {"error": True, "message": str(exception)}, 400
示例#5
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_dict = entity.serialize(relations=True)
    if shots_service.is_episode(entity_dict):
        assets = _extract_removal(entity_dict, casting)
        for asset_id in assets:
            _remove_asset_from_episode_shots(asset_id, entity_id)
    entity.update({"entities_out": [], "entities_out_length": 0})
    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", ""),
            )
            if shots_service.is_episode(entity_dict):
                events.emit(
                    "asset:update",
                    {"asset_id": cast["asset_id"]},
                    project_id=entity.project_id,
                )

    entity_id = str(entity.id)
    nb_entities_out = len(casting)
    entity.update({"nb_entities_out": nb_entities_out})
    entity_dict = entity.serialize()
    if shots_service.is_shot(entity_dict):
        refresh_shot_casting_stats(entity_dict)
        events.emit(
            "shot:casting-update",
            {
                "shot_id": entity_id,
                "nb_entities_out": nb_entities_out
            },
            project_id=str(entity.project_id),
        )
    elif shots_service.is_episode(entity_dict):
        events.emit(
            "episode:casting-update",
            {
                "episode_id": entity_id,
                "nb_entities_out": nb_entities_out
            },
            project_id=str(entity.project_id),
        )
    else:
        events.emit(
            "asset:casting-update",
            {"asset_id": entity_id},
            project_id=str(entity.project_id),
        )
    return casting
示例#6
0
 def get_type_name(self, entity_dict):
     type_name = "asset"
     if shots_service.is_shot(entity_dict):
         type_name = "shot"
     elif shots_service.is_sequence(entity_dict):
         type_name = "sequence"
     elif shots_service.is_episode(entity_dict):
         type_name = "episode"
     return type_name
示例#7
0
def get_folder_from_episode(entity):
    if shots_service.is_shot(entity) or shots_service.is_scene(entity):
        sequence = shots_service.get_sequence_from_shot(entity)
    elif shots_service.is_sequence(entity):
        sequence = entity

    try:
        episode = shots_service.get_episode_from_sequence(sequence)
        episode_name = episode["name"]
    except:
        episode_name = "e001"

    return episode_name
示例#8
0
def get_folder_from_sequence(entity):
    if shots_service.is_shot(entity) or shots_service.is_scene(entity):
        sequence = shots_service.get_sequence_from_shot(entity)
        sequence_name = sequence["name"]
    elif shots_service.is_sequence(entity):
        sequence_name = entity["name"]
    else:
        sequence_name = ""

    if "Seq" in sequence_name:
        sequence_number = sequence.name[3:]
        sequence_name = "S%s" % sequence_number.zfill(3)
    return sequence_name
示例#9
0
def get_file_name_template(tree, mode, entity):
    try:
        if entity["type"] == "AssetInstance":
            return tree[mode]["file_name"]["instance"]
        elif shots_service.is_shot(entity):
            return tree[mode]["file_name"]["shot"]
        elif shots_service.is_sequence(entity):
            return tree[mode]["file_name"]["sequence"]
        elif shots_service.is_scene(entity):
            return tree[mode]["file_name"]["scene"]
        else:
            return tree[mode]["file_name"]["asset"]
    except KeyError:
        raise MalformedFileTreeException
示例#10
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()
            entity = self.get_model_or_404(instance_id)
            self.check_update_permissions(entity.serialize(), data)

            extra_data = copy.copy(entity.data) or {}
            if "data" not in data or data["data"] is None:
                data["data"] = {}
            extra_data.update(data["data"])
            data["data"] = extra_data

            previous_version = entity.serialize()
            data = self.update_data(data, instance_id)
            if data.get("source_id", None) == "null":
                data["source_id"] = None

            changes_dict = self.make_changes_dict(previous_version, data)
            entity.update(data)

            entity_dict = entity.serialize()

            if shots_service.is_shot(entity_dict):
                self.save_version_if_needed(entity_dict, previous_version)
            self.emit_update_event(entity_dict, data={"changes": changes_dict})
            return entity_dict, 200

        except StatementError as exception:
            current_app.logger.error(str(exception), exc_info=1)
            return {"error": True, "message": str(exception)}, 400
        except TypeError as exception:
            current_app.logger.error(str(exception), exc_info=1)
            return {"error": True, "message": str(exception)}, 400
        except IntegrityError as exception:
            current_app.logger.error(str(exception), exc_info=1)
            return {"error": True, "message": str(exception)}, 400
        except StatementError as exception:
            current_app.logger.error(str(exception), exc_info=1)
            return {"error": True, "message": str(exception)}, 400
        except NotFound as exception:
            return {"error": True, "message": str(exception)}, 404
        except Exception as exception:
            current_app.logger.error(str(exception), exc_info=1)
            return {"error": True, "message": str(exception)}, 400
示例#11
0
def get_folder_path_template(tree, mode, entity):
    try:
        if entity["type"] == "AssetInstance":
            if entity.get("target_asset_id", None) is not None:
                return tree[mode]["folder_path"]["instance_asset"]
            else:
                return tree[mode]["folder_path"]["instance"]
        elif shots_service.is_shot(entity):
            return tree[mode]["folder_path"]["shot"]
        elif shots_service.is_sequence(entity):
            return tree[mode]["folder_path"]["sequence"]
        elif shots_service.is_scene(entity):
            return tree[mode]["folder_path"]["scene"]
        else:
            return tree[mode]["folder_path"]["asset"]
    except KeyError:
        raise MalformedFileTreeException
示例#12
0
    def import_row(self, row, project_id):
        asset_key = slugify("%s%s" % (row["Asset Type"], row["Asset"]))
        if row.get("Episode") == "MP":
            row["Episode"] = ""
        target_key = slugify(
            "%s%s%s" % (row.get("Episode", ""), row["Parent"], row["Name"])
        )
        occurences = 1
        if len(row["Occurences"]) > 0:
            occurences = int(row["Occurences"])

        asset_id = self.asset_map.get(asset_key, None)
        target_id = self.shot_map.get(target_key, None)
        label = slugify(row.get("Label", "fixed"))
        if target_id is None:
            target_id = self.asset_map.get(target_key, None)

        if asset_id is not None and target_id is not None:
            entity = entities_service.get_entity_raw(target_id)
            link = breakdown_service.get_entity_link_raw(target_id, asset_id)
            if link is None:
                breakdown_service.create_casting_link(
                    target_id, asset_id, occurences, label
                )
                entity.update({"nb_entities_out": entity.nb_entities_out + 1})
            else:
                link.update({"nb_occurences": occurences, "label": label})
            entity_id = str(entity.id)
            if shots_service.is_shot(entity.serialize()):
                breakdown_service.refresh_shot_casting_stats(
                    entity.serialize()
                )
                events.emit(
                    "shot:casting-update",
                    {
                        "shot_id": entity_id,
                        "nb_entities_out": entity.nb_entities_out,
                    },
                    project_id=str(entity.project_id),
                )
            else:
                events.emit(
                    "asset:casting-update",
                    {"asset_id": entity_id},
                    project_id=str(entity.project_id),
                )
示例#13
0
def get_full_entity_name(entity_id):
    """
    Get full entity name whether it's an asset or a shot. If it's a shot
    the result is "Episode name / Sequence name / Shot name". If it's an
    asset the result is "Asset type name / Asset name".
    """
    entity = Entity.get(entity_id)
    if shots_service.is_shot(entity.serialize()):
        sequence = Entity.get(entity.parent_id)
        if sequence.parent_id is None:
            return "%s / %s" % (sequence.name, entity.name)
        else:
            episode = Entity.get(sequence.parent_id)
            return "%s / %s / %s" % (episode.name, sequence.name, entity.name)
    else:
        asset_type = EntityType.get(entity.entity_type_id)
        name = "%s / %s" % (asset_type.name, entity.name)
    return name
示例#14
0
def _create_episode_casting_link(entity, asset_id, nb_occurences=1, label=""):
    """
    When an asset is casted in a shot, the asset is automatically casted in
    the episode.
    """
    if shots_service.is_shot(entity):
        sequence = shots_service.get_sequence(entity["parent_id"])
        if sequence["parent_id"] is not None:
            link = EntityLink.get_by(entity_in_id=sequence["parent_id"],
                                     entity_out_id=asset_id)
            if link is None:
                link = EntityLink.create(
                    entity_in_id=sequence["parent_id"],
                    entity_out_id=asset_id,
                    nb_occurences=1,
                    label=label,
                )
                events.emit(
                    "asset:update",
                    {"asset_id": asset_id},
                    project_id=entity["project_id"],
                )
    return entity
示例#15
0
 def test_is_shot(self):
     self.assertTrue(shots_service.is_shot(self.shot.serialize()))
     self.assertFalse(shots_service.is_shot(self.asset.serialize()))
示例#16
0
def check_metadata_department_access(entity, new_data={}):
    """
    Return true if current user is a manager and has a task assigned for this
    project or is a supervisor and is allowed to modify data accorded to
    his departments
    """
    is_allowed = False
    if permissions.has_admin_permissions() or (
        permissions.has_manager_permissions()
        and check_belong_to_project(entity["project_id"])
    ):
        is_allowed = True
    elif permissions.has_supervisor_permissions() and check_belong_to_project(
        entity["project_id"]
    ):
        # checks that the supervisor only modifies columns
        # for which he is authorized
        allowed_columns = set(["data"])
        if len(set(new_data.keys()) - allowed_columns) == 0:
            user_departments = persons_service.get_current_user(
                relations=True
            )["departments"]
            if user_departments == []:
                is_allowed = True
            else:
                entity_type = None
                if shots_service.is_shot(entity):
                    entity_type = "Shot"
                elif assets_service.is_asset(
                    entities_service.get_entity_raw(entity["id"])
                ):
                    entity_type = "Asset"
                elif edits_service.is_edit(entity):
                    entity_type = "Edit"
                if entity_type:
                    descriptors = [
                        descriptor
                        for descriptor in projects_service.get_metadata_descriptors(
                            entity["project_id"]
                        )
                        if descriptor["entity_type"] == entity_type
                    ]
                    found_and_in_departments = False
                    for descriptor_name in new_data["data"].keys():
                        found_and_in_departments = False
                        for descriptor in descriptors:
                            if descriptor["field_name"] == descriptor_name:
                                found_and_in_departments = (
                                    len(
                                        set(descriptor["departments"])
                                        & set(user_departments)
                                    )
                                    > 0
                                )
                                break
                        if not found_and_in_departments:
                            break
                    if found_and_in_departments:
                        is_allowed = True

    if not is_allowed:
        raise permissions.PermissionDenied
    return is_allowed