diff --git a/gazu/casting.py b/gazu/casting.py index 3ca6c330..d5a855c1 100644 --- a/gazu/casting.py +++ b/gazu/casting.py @@ -45,6 +45,25 @@ def update_asset_casting(project, asset, casting, client=default): return raw.put(path, casting, client=client) +def update_episode_casting(project, episode, casting, client=default): + """ + Change casting of given episode with given casting (list of asset ids displayed + into the episode). + + Args: + episode (str / dict): The episode dict or the episode ID. + casting (dict): The casting description. + Ex: `casting = [{"asset_id": "asset-1", "nb_occurences": 3}]` + + Returns: + dict: Related episode. + """ + episode = normalize_model_parameter(episode) + project = normalize_model_parameter(project) + path = "data/projects/%s/entities/%s/casting" % (project["id"], episode["id"]) + return raw.put(path, casting, client=client) + + def get_asset_type_casting(project, asset_type, client=default): """ Return casting for given asset_type. @@ -117,6 +136,23 @@ def get_asset_casting(asset, client=default): return raw.get(path, client=client) +def get_episode_casting(episode, client=default): + """ + Return casting for given episode. + `[{"episode_id": "episode-1", "nb_occurences": 3}]}` + Args: + episode (dict): The episode dict + + Returns: + dict: Casting for given episode. + """ + path = "/data/projects/%s/entities/%s/casting" % ( + episode["project_id"], + episode["id"], + ) + return raw.get(path, client=client) + + def get_asset_cast_in(asset, client=default): """ Return entity list where given asset is casted. diff --git a/gazu/playlist.py b/gazu/playlist.py index 80823472..8677eacc 100644 --- a/gazu/playlist.py +++ b/gazu/playlist.py @@ -151,3 +151,115 @@ def update_playlist(playlist, client=default): return raw.put( "data/playlists/%s" % playlist["id"], playlist, client=client ) + + +def get_entity_preview_files(entity, client=default): + """ + Get all preview files grouped by task type for a given entity. + + Args: + entity (str / dict): The entity to retrieve files from or its ID. + + Returns: + dict: A dict where keys are task type IDs and value array of revisions. + """ + entity = normalize_model_parameter(entity) + return raw.get( + "data/playlists/entities/%s/preview-files" % entity["id"], + client=client + ) + + +def add_entity_to_playlist( + playlist, + entity, + preview_file=None, + persist=True, + client=default +): + """ + Add an entity to the playlist, use the last uploaded preview as revision + to review. + + Args: + playlist (dict): Playlist object to modify. + entity (str / dict): The entity to add or its ID. + preview_file (str / dict): Set it to force a give revision to review. + persist (bool): Set it to True to save the result to the API. + + Returns: + dict: Updated playlist. + """ + entity = normalize_model_parameter(entity) + + if preview_file is None: + preview_files = get_entity_preview_files(entity) + for task_type_id in preview_files.keys(): + task_type_files = preview_files[task_type_id] + first_file = task_type_files[0] + if preview_file is None or \ + preview_file["created_at"] < first_file["created_at"]: + preview_file = first_file + + preview_file = normalize_model_parameter(preview_file) + playlist["shots"].append({ + "entity_id": entity["id"], + "preview_file_id": preview_file["id"] + }) + if persist: + update_playlist(playlist, client=client) + return playlist + + +def remove_entity_from_playlist( + playlist, + entity, + persist=True, + client=default +): + """ + Remove all occurences of a given entity from a playlist. + + Args: + playlist (dict): Playlist object to modify + entity (str / dict): the entity to remove or its ID + + Returns: + dict: Updated playlist. + """ + entity = normalize_model_parameter(entity) + playlist["shots"] = [ + entry + for entry in playlist["shots"] + if entry["entity_id"] != entity["id"] + ] + if persist: + update_playlist(playlist, client=client) + return playlist + + +def update_entity_preview( + playlist, + entity, + preview_file, + persist=True, + client=default +): + """ + Remove all occurences of a given entity from a playlist. + + Args: + playlist (dict): Playlist object to modify + entity (str / dict): the entity to add or its ID + + Returns: + dict: Updated playlist. + """ + entity = normalize_model_parameter(entity) + preview_file = normalize_model_parameter(preview_file) + for entry in playlist["shots"]: + if entry["entity_id"] == entity["id"]: + entry["preview_file_id"] = preview_file["id"] + if persist: + update_playlist(playlist, client=client) + return playlist diff --git a/tests/test_casting.py b/tests/test_casting.py index 4f90cd03..ddc35778 100644 --- a/tests/test_casting.py +++ b/tests/test_casting.py @@ -37,6 +37,19 @@ def test_update_asset_casting(self): ) self.assertEqual(casting[0]["asset_id"], fakeid("asset-1")) + def test_update_episode_casting(self): + casting = [{"asset_id": fakeid("asset-1"), "nb_occurences": 3}] + path = "data/projects/%s/entities/%s/casting" % ( + fakeid("project-01"), + fakeid("episode-01"), + ) + with requests_mock.mock() as mock: + mock.put(gazu.client.get_full_url(path), text=json.dumps(casting)) + episode = {"id": fakeid("episode-01")} + project = {"id": fakeid("project-01")} + casting = gazu.casting.update_episode_casting(project, episode, casting) + self.assertEqual(casting[0]["asset_id"], fakeid("asset-1")) + def test_get_asset_type_casting(self): casting = { fakeid("asset-2"): [ @@ -92,6 +105,21 @@ def test_get_shot_casting(self): casting = gazu.casting.get_shot_casting(shot) self.assertEqual(casting[0]["asset_id"], fakeid("asset-1")) + def test_get_episode_casting(self): + casting = [{"asset_id": fakeid("asset-1"), "nb_occurences": 3}] + path = "data/projects/%s/entities/%s/casting" % ( + fakeid("project-01"), + fakeid("episode-01"), + ) + with requests_mock.mock() as mock: + mock.get(gazu.client.get_full_url(path), text=json.dumps(casting)) + episode = { + "id": fakeid("episode-01"), + "project_id": fakeid("project-01"), + } + casting = gazu.casting.get_episode_casting(episode) + self.assertEqual(casting[0]["asset_id"], fakeid("asset-1")) + def test_get_asset_casting(self): casting = [{"asset_id": fakeid("asset-1"), "nb_occurences": 3}] path = "data/projects/%s/entities/%s/casting" % ( diff --git a/tests/test_playlist.py b/tests/test_playlist.py index 7e2f4c7f..7b02b31c 100644 --- a/tests/test_playlist.py +++ b/tests/test_playlist.py @@ -166,3 +166,48 @@ def test_update_playlist(self): playlist = {"id": fakeid("playlist-1"), "name": "name_changed"} playlist = gazu.playlist.update_playlist(playlist) self.assertEqual(playlist["id"], fakeid("playlist-1")) + + def test_add_entity_to_playlist(self): + with requests_mock.mock() as mock: + mock.put( + gazu.client.get_full_url( + "data/playlists/%s" % fakeid("playlist-1") + ), + text=json.dumps( + {"id": fakeid("playlist-1"), "name": "name_changed"} + ), + ) + mock.get( + gazu.client.get_full_url( + "data/playlists/entities/%s/preview-files" % fakeid("shot-1") + ), + text=json.dumps( + {fakeid("task-type-1"): [{"id": fakeid("preview-1")}]} + ), + ) + playlist = { + "id": fakeid("playlist-1"), + "name": "name_changed", + "shots": [] + } + shot = { + "id": fakeid("shot-1"), + "name": "SH01" + } + playlist = gazu.playlist.add_entity_to_playlist(playlist, shot) + self.assertEqual(playlist["id"], fakeid("playlist-1")) + self.assertEqual(playlist["shots"], [{ + "entity_id": fakeid("shot-1"), + "preview_file_id": fakeid("preview-1") + }]) + playlist = gazu.playlist.update_entity_preview( + playlist, + shot, + fakeid("preview-2") + ) + self.assertEqual(playlist["shots"], [{ + "entity_id": fakeid("shot-1"), + "preview_file_id": fakeid("preview-2") + }]) + playlist = gazu.playlist.remove_entity_from_playlist(playlist, shot) + self.assertEqual(playlist["shots"], [])