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)
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
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
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
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
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
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
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
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
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
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
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), )
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
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
def test_is_shot(self): self.assertTrue(shots_service.is_shot(self.shot.serialize())) self.assertFalse(shots_service.is_shot(self.asset.serialize()))
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