def get_full_shot(shot_id): shot = get_shot(shot_id) sequence = Entity.get(shot["parent_id"]) project = Project.get(shot["project_id"]) shot["project_name"] = project.name shot["sequence_id"] = str(sequence.id) shot["sequence_name"] = sequence.name if sequence.parent_id is not None: episode = Entity.get(sequence.parent_id) shot["episode_id"] = str(episode.id) shot["episode_name"] = episode.name tasks = Task.query \ .filter_by(entity_id=shot_id) \ .all() task_dicts = [] for task in tasks: task_dicts.append({ "id": str(task.id), "task_status_id": str(task.task_status_id), "task_type_id": str(task.task_type_id), "assignees": [str(assignee.id) for assignee in task.assignees] }) shot["tasks"] = task_dicts return shot
def get_full_scene(scene_id): scene = get_scene(scene_id) project = Project.get(scene["project_id"]) sequence = Entity.get(scene["parent_id"]) scene["project_name"] = project.name scene["sequence_id"] = str(sequence.id) scene["sequence_name"] = sequence.name if sequence.parent_id is not None: episode = Entity.get(sequence.parent_id) scene["episode_id"] = str(episode.id) scene["episode_name"] = episode.name return scene
def task_to_review(task_id, person, comment, preview_path=""): """ Change the task status to "waiting for approval" if it is not already the case. It emits a *task:to-review* event. Change the real start date time to now. """ task = get_task_raw(task_id) to_review_status = get_to_review_status() task_dict_before = task.serialize() 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_before": task_dict_before, "task_after": task_dict_after }) return task_dict_after
def to_review_task(task, output_file_dict): to_review_status = get_to_review_status() task_dict_before = task.serialize() 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) person = Person.get(output_file_dict["person_id"]) task_dict_after = task.serialize() task_dict_after["output_file"] = output_file_dict 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.serialize() events.emit("task:to-review", { "task_before": task_dict_before, "task_after": task_dict_after }) return task
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()
def task_to_review(task_id, person, comment, preview_path=""): task = get_task_raw(task_id) to_review_status = get_to_review_status() task_dict_before = task.serialize() 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_before": task_dict_before, "task_after": task_dict_after }) return task_dict_after
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) news = News.get_by(preview_file_id=preview_file.id) if entity.preview_file_id == preview_file.id: entity.update({"preview_file_id": None}) if news is not None: news.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()
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 }, ) entity_type = EntityType.get(entity.entity_type_id) entity_type_name = "asset" if entity_type.name in ["Shot", "Scene", "Sequence", "Episode"]: entity_type_name = entity_type.name.lower() events.emit( "%s:update" % entity_type_name, {"%s_id" % entity_type_name: str(entity.id)}, ) return entity.serialize()
def test_delete_entry(self): asset_id = str(self.asset.id) events.register("asset:delete", "handle_event", self) delete_func = sync_service.delete_entry("assets", "asset", Entity) delete_func({"asset_id": asset_id}) self.assertIsNone(Entity.get(asset_id)) self.assertTrue("asset_id" in self.last_event_data)
def extract_assets(self, sg_shot, asset_map): assets = [] if "assets" in sg_shot and len(sg_shot["assets"]) > 0: for sg_asset in sg_shot["assets"]: entity_id = asset_map[sg_asset["id"]] asset = Entity.get(entity_id) assets.append(asset) return assets
def get_entity_from_preview_file(preview_file_id): """ Get entity dict of related preview file. """ preview_file = files_service.get_preview_file_raw(preview_file_id) task = Task.get(preview_file.task_id) entity = Entity.get(task.entity_id) return entity.serialize()
def get_sequence_from_shot(shot): """ Return parent sequence of given shot. """ try: sequence = Entity.get(shot["parent_id"]) except: raise SequenceNotFoundException("Wrong parent_id for given shot.") return sequence.serialize(obj_type="Sequence")
def extract_assets(self, sg_shot): assets = [] if "assets" in sg_shot and len(sg_shot["assets"]) > 0: for sg_asset in sg_shot["assets"]: entity_id = self.get_asset_id(sg_asset["id"]) if entity_id is not None: asset = Entity.get(entity_id) assets.append(asset) return assets
def build_asset_instance_name(asset_id, number): """ Helpers to generate normalized asset instance name. It is used to build default instance names. """ asset = Entity.get(asset_id) asset_name = slugify(asset.name, separator="_", lowercase=False) number = str(number).zfill(4) return "%s_%s" % (asset_name, number)
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 get_episode_from_sequence(sequence): """ Return parent episode of given sequence. """ try: episode = Entity.get(sequence["parent_id"]) except: raise EpisodeNotFoundException("Wrong parent_id for given sequence.") return episode.serialize(obj_type="Episode")
def get_file_name(task, mode="output", version=1, comment=""): entity = Entity.get(task.entity_id) project = get_project(entity) tree = get_tree_from_project(project) file_name = get_file_name_root(tree, mode, entity, task) file_name = add_version_suffix_to_file_name(file_name, version) file_name = add_comment_suffix_to_file_name(file_name, comment) return u"%s" % file_name
def get_asset_raw(entity_id): try: entity = Entity.get(entity_id) except StatementError: raise AssetNotFoundException if entity is None or not is_asset(entity): raise AssetNotFoundException return entity
def get_sequence_subscriptions(task): """ Return all sequence subscriptions for given task. It returns something only if the task is related to a shot of which the sequence has a subscription. """ sequence_subscriptions = [] entity = Entity.get(task["entity_id"]) if entity is not None and entity.parent_id is not None: sequence_subscriptions = Subscription.get_all_by( task_type_id=task["task_type_id"], entity_id=entity.parent_id) return sequence_subscriptions
def get_asset_types_for_shot(shot_id): shot = Entity.get(shot_id) asset_type_ids = [x.entity_type_id for x in shot.entities_out] if len(asset_type_ids) > 0: query = EntityType.query query = query.filter(EntityType.id.in_(asset_type_ids)) result = query.all() else: result = [] return EntityType.serialize_list(result, obj_type="AssetType")
def get_folder_path(task, mode="working", sep=os.sep): entity = Entity.get(task.entity_id) project = get_project(entity) tree = get_tree_from_project(project) root_path = get_root_path(tree, mode, sep) style = tree[mode]["folder_path"].get("style", "") folder_template = get_folder_path_template(tree, mode, entity) folder_path = update_variable(folder_template, entity, task, style) folder_path = change_folder_path_separators(folder_path, sep) return join_path(root_path, folder_path, "")
def get_asset_raw(entity_id): """ Return a given asset as an active record. """ try: entity = Entity.get(entity_id) except StatementError: raise AssetNotFoundException if entity is None or not is_asset(entity): raise AssetNotFoundException return entity
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")
def get_asset_types_for_shot(shot_id): """ Retrieve all asset types related to asset casted in a given shot. """ shot = Entity.get(shot_id) asset_type_ids = [x.entity_type_id for x in shot.entities_out] if len(asset_type_ids) > 0: query = EntityType.query query = query.filter(EntityType.id.in_(asset_type_ids)) result = query.all() else: result = [] return EntityType.serialize_list(result, obj_type="AssetType")
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", [], False) 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)
def update_entity_preview(entity_id, preview_file_id): 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()
def task_to_review(task_id, person, comment, preview_path={}, change_status=True): """ Deprecated 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() clear_task_cache(task_id) 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
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"])
def test_entity(self): entity_dict = { "id": "49ed2011-3186-4405-8dc8-d6cb3a68ff1c", "entities_out": [], "created_at": "2019-06-20T12:28:16", "updated_at": "2019-08-16T11:44:31", "name": "Lama", "description": "", "canceled": False, "project_id": str(self.project.id), "entity_type_id": str(self.asset_type_character.id), "preview_file_id": None, "entities_in": [], "type": "Asset" } Entity.create_from_import(entity_dict) entity = Entity.get(entity_dict["id"]) self.assertEqual(entity_dict["name"], entity.name)
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