diff --git a/src/rest/controllers/internal_controller.py b/src/rest/controllers/internal_controller.py index 38c73ab9391c31637a63027c2ed461abda6f354b..29ae60410fb2dd6a724dcd6394337b5535117dc6 100644 --- a/src/rest/controllers/internal_controller.py +++ b/src/rest/controllers/internal_controller.py @@ -14,7 +14,7 @@ from src.rest import util def add_playlog(body): # noqa: E501 """Adds an entry to the playlog - Stores the passed playlog entry # noqa: E501 + Stores the passed playlog entry in the local database. Also note, similar to the `ClockInfo` storage endpoint, this information is only stored to the database if a) it is a main node or b) if it's a sync node, and the `log_source` is the currently active engine. # noqa: E501 :param body: :type body: dict | bytes diff --git a/src/rest/models/health_log.py b/src/rest/models/health_log.py index f6a160994733f51904dcdfb8ef46a803dc967945..59a210204d8b39fef62319869acf76f18c09cba6 100644 --- a/src/rest/models/health_log.py +++ b/src/rest/models/health_log.py @@ -100,6 +100,7 @@ class HealthLog(Model): def details(self): """Gets the details of this HealthLog. + Stringified JSON Object # noqa: E501 :return: The details of this HealthLog. :rtype: str @@ -110,6 +111,7 @@ class HealthLog(Model): def details(self, details): """Sets the details of this HealthLog. + Stringified JSON Object # noqa: E501 :param details: The details of this HealthLog. :type details: str diff --git a/src/rest/models/play_log.py b/src/rest/models/play_log.py index f9eec304de9ed262a6a17eb856c78a789c4016ae..a74cad7e1f76c57b6394433b4462a1169aaf6037 100644 --- a/src/rest/models/play_log.py +++ b/src/rest/models/play_log.py @@ -14,7 +14,7 @@ class PlayLog(Model): Do not edit the class manually. """ - def __init__(self, track_start=None, track_artist=None, track_album=None, track_title=None, track_duration=None, track_type=None, track_num=None, playlist_id=None, schedule_id=None, show_id=None, show_name=None, log_source=None, is_synced=None): # noqa: E501 + def __init__(self, track_start=None, track_artist=None, track_album=None, track_title=None, track_duration=None, track_type=None, track_num=None, playlist_id=None, schedule_id=None, show_id=None, show_name=None, log_source=None, custom_json=None, is_synced=None): # noqa: E501 """PlayLog - a model defined in Swagger :param track_start: The track_start of this PlayLog. # noqa: E501 @@ -41,6 +41,8 @@ class PlayLog(Model): :type show_name: str :param log_source: The log_source of this PlayLog. # noqa: E501 :type log_source: int + :param custom_json: The custom_json of this PlayLog. # noqa: E501 + :type custom_json: str :param is_synced: The is_synced of this PlayLog. # noqa: E501 :type is_synced: bool """ @@ -57,6 +59,7 @@ class PlayLog(Model): 'show_id': int, 'show_name': str, 'log_source': int, + 'custom_json': str, 'is_synced': bool } @@ -73,6 +76,7 @@ class PlayLog(Model): 'show_id': 'show_id', 'show_name': 'show_name', 'log_source': 'log_source', + 'custom_json': 'custom_json', 'is_synced': 'is_synced' } self._track_start = track_start @@ -87,6 +91,7 @@ class PlayLog(Model): self._show_id = show_id self._show_name = show_name self._log_source = log_source + self._custom_json = custom_json self._is_synced = is_synced @classmethod @@ -358,6 +363,29 @@ class PlayLog(Model): self._log_source = log_source + @property + def custom_json(self): + """Gets the custom_json of this PlayLog. + + A stringified JSON Object allowing the future extension of the API with custom fields. # noqa: E501 + + :return: The custom_json of this PlayLog. + :rtype: str + """ + return self._custom_json + + @custom_json.setter + def custom_json(self, custom_json): + """Sets the custom_json of this PlayLog. + + A stringified JSON Object allowing the future extension of the API with custom fields. # noqa: E501 + + :param custom_json: The custom_json of this PlayLog. + :type custom_json: str + """ + + self._custom_json = custom_json + @property def is_synced(self): """Gets the is_synced of this PlayLog. diff --git a/src/rest/swagger/swagger.yaml b/src/rest/swagger/swagger.yaml index 0c6553b07bc1a3ddf6013f51d59ec046af2ec8cf..21bacfd9232ca1c4d5896d23f0b9ff7090c6b1d3 100644 --- a/src/rest/swagger/swagger.yaml +++ b/src/rest/swagger/swagger.yaml @@ -137,9 +137,9 @@ paths: tags: - internal summary: Set current studio clock information such as schedule info and track-list - for engine 1 or 2 + for engine 1 or 2 within the Engine API database. description: | - Set current studio clock information (source, schedule and track-list) and the next schedule of the given play-out source (engine1, engine2). Please note, the `current_track` information is ignored in the PUT request. It's only populated in the GET request. To store current track information use `/playlog/store` instead. + Set current studio clock information (source, schedule and track-list) and the next schedule of the given play-out source (engine1, engine2). Please note, the `current_track` information is ignored in the PUT request. It's only dynamically populated in the GET request by reading the most recent playlog. To store current track information use `/playlog/store` instead. Also note, similar to the `PlayLog` storage endpoint, this information is only stored to the database if a) it is a main node or b) if it's a sync node, and the `engine_source` is the currently active engine. operationId: set_clock_info requestBody: content: @@ -159,7 +159,7 @@ paths: - internal summary: Adds an entry to the playlog description: | - Stores the passed playlog entry + Stores the passed playlog entry in the local database. Also note, similar to the `ClockInfo` storage endpoint, this information is only stored to the database if a) it is a main node or b) if it's a sync node, and the `log_source` is the currently active engine. operationId: add_playlog requestBody: content: @@ -423,6 +423,8 @@ components: show_name: type: string example: Electronic Music from Brazil + description: Holds all information required to display a public Track Service + entry. This schema is a sub-set of the `PlayLog` schema. example: track_album: '... And the Circus Leaves Town' show_id: 42 @@ -481,6 +483,11 @@ components: description: From which engine the entry has been logged from e.g. "1" for Engine 1 or "2" for Engine 2 example: 1 + custom_json: + type: string + description: A stringified JSON Object allowing the future extension of + the API with custom fields. + example: '{ "custom": "Stringified JSON Object" }' is_synced: type: boolean description: For Engine API internal use only - On a main node such as Engine @@ -488,6 +495,8 @@ components: the sync node. On the sync node in contrast this flag indicates if the playlog has been passively synced from one of the main nodes. example: true + description: Holds all information available to the currently playing track. + This schema is a super-set of the `Track` schema. example: track_album: Bricolage show_id: 42 @@ -502,6 +511,7 @@ components: log_source: 1 track_duration: 808 schedule_id: 23 + custom_json: '{ "custom": "Stringified JSON Object" }' HealthLog: required: - details @@ -518,10 +528,75 @@ components: example: true details: type: string - example: Stringified JSON Object + description: Stringified JSON Object + example: '{ "health_info": "{\"engine\": {\"version\": \"0.8.2\", \"status\": + \"OK\"}, \"soundsystem\": {\"version\": \"Liquidsoap 1.4.3\", \"uptime\": + \"0d 00h 00m 02s\", \"io\": {\"streams\": {\"stream_0\": {\"enabled\": + false, \"connected\": \"\"}, \"stream_1\": {\"enabled\": false, \"connected\": + \"\"}, \"stream_2\": {\"enabled\": false, \"connected\": \"\"}, \"stream_3\": + {\"enabled\": false, \"connected\": \"\"}, \"stream_4\": {\"enabled\": + false, \"connected\": \"\"}}, \"recorder\": {\"recorder_0\": {\"enabled\": + false, \"recording\": false}, \"recorder_1\": {\"enabled\": false, \"recording\": + false}, \"recorder_2\": {\"enabled\": false, \"recording\": false}, \"recorder_3\": + {\"enabled\": false, \"recording\": false}, \"recorder_4\": {\"enabled\": + false, \"recording\": false}}, \"linein\": {\"linein_0\": {\"enabled\": + true}, \"linein_1\": {\"enabled\": false}, \"linein_2\": {\"enabled\": + false}, \"linein_3\": {\"enabled\": false}, \"linein_4\": {\"enabled\": + false}}, \"lineout\": {\"lineout_0\": {\"enabled\": true}, \"lineout_1\": + {\"enabled\": false}, \"lineout_2\": {\"enabled\": false}, \"lineout_3\": + {\"enabled\": false}, \"lineout_4\": {\"enabled\": false}}}, \"mixer\": + {\"in_filesystem_0\": \"ready=false selected=false single=false volume=0% + remaining=0.00\", \"in_filesystem_1\": \"ready=false selected=false single=false + volume=0% remaining=0.00\", \"in_http_0\": \"ready=false selected=false + single=false volume=0% remaining=0.00\", \"in_http_1\": \"ready=false + selected=false single=false volume=0% remaining=0.00\", \"in_https_0\": + \"ready=false selected=false single=false volume=0% remaining=0.00\", + \"in_https_1\": \"ready=false selected=false single=false volume=0% remaining=0.00\", + \"linein_0\": \"ready=true selected=false single=false volume=0% remaining=(undef)\"}, + \"active\": true}, \"redis\": {\"active\": true}, \"api\": {\"steering\": + {\"url\": \"http://localhost:8000/api/v1/\", \"available\": true}, \"tank\": + {\"url\": \"http://localhost:8040/healthz/\", \"available\": true, \"status\": + {\"auth\": \"OK\", \"store\": \"OK\", \"importer\": \"OK\"}}, \"engine\": + {\"url\": \"http://localhost:8008/api/v1/ui/\", \"available\": true}}, + \"audio_store\": {\"path\": \"/home/david/Code/aura/tank-store\", \"exists\": + true, \"has_content\": true}}", "is_healthy": true, "is_synced": false, + "log_source": 1, "log_time": "2020-10-01T20:22:37" }' + description: Holds unspecified and extendable health information for both, valid + and invalid states of the playout engine(s). The data is stored in form of + stringified JSON. example: is_healthy: true - details: Stringified JSON Object + details: '{ "health_info": "{\"engine\": {\"version\": \"0.8.2\", \"status\": + \"OK\"}, \"soundsystem\": {\"version\": \"Liquidsoap 1.4.3\", \"uptime\": + \"0d 00h 00m 02s\", \"io\": {\"streams\": {\"stream_0\": {\"enabled\": false, + \"connected\": \"\"}, \"stream_1\": {\"enabled\": false, \"connected\": + \"\"}, \"stream_2\": {\"enabled\": false, \"connected\": \"\"}, \"stream_3\": + {\"enabled\": false, \"connected\": \"\"}, \"stream_4\": {\"enabled\": false, + \"connected\": \"\"}}, \"recorder\": {\"recorder_0\": {\"enabled\": false, + \"recording\": false}, \"recorder_1\": {\"enabled\": false, \"recording\": + false}, \"recorder_2\": {\"enabled\": false, \"recording\": false}, \"recorder_3\": + {\"enabled\": false, \"recording\": false}, \"recorder_4\": {\"enabled\": + false, \"recording\": false}}, \"linein\": {\"linein_0\": {\"enabled\": + true}, \"linein_1\": {\"enabled\": false}, \"linein_2\": {\"enabled\": false}, + \"linein_3\": {\"enabled\": false}, \"linein_4\": {\"enabled\": false}}, + \"lineout\": {\"lineout_0\": {\"enabled\": true}, \"lineout_1\": {\"enabled\": + false}, \"lineout_2\": {\"enabled\": false}, \"lineout_3\": {\"enabled\": + false}, \"lineout_4\": {\"enabled\": false}}}, \"mixer\": {\"in_filesystem_0\": + \"ready=false selected=false single=false volume=0% remaining=0.00\", \"in_filesystem_1\": + \"ready=false selected=false single=false volume=0% remaining=0.00\", \"in_http_0\": + \"ready=false selected=false single=false volume=0% remaining=0.00\", \"in_http_1\": + \"ready=false selected=false single=false volume=0% remaining=0.00\", \"in_https_0\": + \"ready=false selected=false single=false volume=0% remaining=0.00\", \"in_https_1\": + \"ready=false selected=false single=false volume=0% remaining=0.00\", \"linein_0\": + \"ready=true selected=false single=false volume=0% remaining=(undef)\"}, + \"active\": true}, \"redis\": {\"active\": true}, \"api\": {\"steering\": + {\"url\": \"http://localhost:8000/api/v1/\", \"available\": true}, \"tank\": + {\"url\": \"http://localhost:8040/healthz/\", \"available\": true, \"status\": + {\"auth\": \"OK\", \"store\": \"OK\", \"importer\": \"OK\"}}, \"engine\": + {\"url\": \"http://localhost:8008/api/v1/ui/\", \"available\": true}}, \"audio_store\": + {\"path\": \"/home/david/Code/aura/tank-store\", \"exists\": true, \"has_content\": + true}}", "is_healthy": true, "is_synced": false, "log_source": 1, "log_time": + "2020-10-01T20:22:37" }' log_time: 2020-08-29T09:12:33.001Z ClockInfo: type: object @@ -537,6 +612,14 @@ components: $ref: '#/components/schemas/Schedule' next_schedule: $ref: '#/components/schemas/Schedule' + description: Holds the most recent data required to display the studio clock. + The field `engine_source` will most likey be the same value as `current_track.log_source`. + This value represents which engine the record has been logged from. If it + is not equal for both fields, it most likely indicates an error or an engine + 1 to engine 2 transition process. Another reason is you are using the API + in some quite futuristic environment, where e.g. an external audio backup + player is able to log its meta data of what it is playing to the Engine API, + while the actual `ClockInfo` was logged from an engine instance instead. example: engine_source: 1 current_playlist: @@ -570,6 +653,7 @@ components: log_source: 1 track_duration: 808 schedule_id: 23 + custom_json: '{ "custom": "Stringified JSON Object" }' current_schedule: show_id: 42 playlist_id: 38 @@ -609,6 +693,8 @@ components: fallback_type: type: integer example: 0 + description: Holds data describing some schedule. Used by `ClockInfo` for the + studio clock. example: show_id: 42 playlist_id: 38 @@ -629,6 +715,8 @@ components: type: array items: $ref: '#/components/schemas/PlaylistEntry' + description: Holds data describing some playlist. Used by `ClockInfo` for the + studio clock. example: entries: - track_album: Bricolage @@ -673,6 +761,8 @@ components: track_num: type: integer example: 7 + description: Holds data describing some playlist entry. Used by `Playlist`, + indirectly by the studio clock data. example: track_album: Bricolage track_start: 2020-08-29T09:12:33.001Z diff --git a/src/rest/test/test_internal_controller.py b/src/rest/test/test_internal_controller.py index 2a2590c208f33a5ea224c67148dfccf9753d0f44..1cba8770b27afeafbe2f394145445e8516107353 100644 --- a/src/rest/test/test_internal_controller.py +++ b/src/rest/test/test_internal_controller.py @@ -136,7 +136,7 @@ class TestInternalController(BaseTestCase): def test_set_clock_info(self): """Test case for set_clock_info - Set current studio clock information such as schedule info and track-list for engine 1 or 2 + Set current studio clock information such as schedule info and track-list for engine 1 or 2 within the Engine API database. """ body = ClockInfo() response = self.client.open(