From 59e10ab810cbed07e989af48e5f30a1030e62c7a Mon Sep 17 00:00:00 2001
From: David Trattnig <david.trattnig@o94.at>
Date: Wed, 24 Jun 2020 12:06:46 +0200
Subject: [PATCH] Update API.

---
 src/rest/controllers/internal_controller.py |  59 +++--
 src/rest/controllers/public_controller.py   |  64 +-----
 src/rest/models/__init__.py                 |   3 +-
 src/rest/models/clock_info.py               | 116 ++++++++++
 src/rest/models/schedule.py                 | 225 ++++++++++++++++++++
 src/rest/swagger/swagger.yaml               | 112 +++++-----
 src/rest/test/test_internal_controller.py   |  12 ++
 src/rest/test/test_public_controller.py     |  33 ---
 8 files changed, 440 insertions(+), 184 deletions(-)
 create mode 100644 src/rest/models/clock_info.py
 create mode 100644 src/rest/models/schedule.py

diff --git a/src/rest/controllers/internal_controller.py b/src/rest/controllers/internal_controller.py
index 0bc4630..845f9df 100644
--- a/src/rest/controllers/internal_controller.py
+++ b/src/rest/controllers/internal_controller.py
@@ -1,57 +1,33 @@
-#
-# Aura Engine API (https://gitlab.servus.at/aura/engine-api)
-#
-# Copyright (C) 2020 - The Aura Engine Team.
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-
 import connexion
 import six
 
+from src.rest.models.clock_info import ClockInfo  # noqa: E501
 from src.rest.models.health_info import HealthInfo  # noqa: E501
 from src.rest.models.play_log_entry import PlayLogEntry  # noqa: E501
 from src.rest.models.status_entry import StatusEntry  # noqa: E501
 from src.rest import util
 
-from src.service.playlist_service import playlistService
-from src.service.track_service import trackService
-from src.service.engine_service import engineService
-
 
-def get_report(year_month):  # noqa: E501
-    """Report for one month
+def activate_engine(engine_number):  # noqa: E501
+    """Set active engine
 
-    Returns a report for the given month  # noqa: E501
+    Activates one engine and deactivates the other  # noqa: E501
 
-    :param year_month: Month to create the report for in the format \&quot;yyyy_mm\&quot;
-    :type year_month: str
+    :param engine_number: Number of the engine
+    :type engine_number: int
 
-    :rtype: List[PlayLogEntry]
+    :rtype: None
     """
     return 'do some magic!'
 
 
-def activate_engine(engine_number):  # noqa: E501
-    """Set active engine
+def clock_info():  # noqa: E501
+    """Get all information to display the studio clock
 
-    Activates one engine and deactivates the other  # noqa: E501
+    Retrieves the currently playing schedule, its playlist and entries plus the next schedule for being used by the studio clock.  # noqa: E501
 
-    :param engine_number: Number of the engine
-    :type engine_number: int
 
-    :rtype: None
+    :rtype: ClockInfo
     """
     return 'do some magic!'
 
@@ -80,6 +56,19 @@ def get_engine_health(engine_number):  # noqa: E501
     return 'do some magic!'
 
 
+def get_report(year_month):  # noqa: E501
+    """Report for one month
+
+    Returns a report for the given month  # noqa: E501
+
+    :param year_month: Month to create the report for in the format \&quot;yyyy_mm\&quot;
+    :type year_month: str
+
+    :rtype: List[PlayLogEntry]
+    """
+    return 'do some magic!'
+
+
 def log_engine_health(engine_number):  # noqa: E501
     """Log health info
 
diff --git a/src/rest/controllers/public_controller.py b/src/rest/controllers/public_controller.py
index e8e82b4..275939a 100644
--- a/src/rest/controllers/public_controller.py
+++ b/src/rest/controllers/public_controller.py
@@ -1,32 +1,11 @@
-#
-# Aura Engine API (https://gitlab.servus.at/aura/engine-api)
-#
-# Copyright (C) 2020 - The Aura Engine Team.
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-
 import connexion
 import six
 
 from src.rest.models.play_log_entry import PlayLogEntry  # noqa: E501
-from src.rest.models.playlist import Playlist  # noqa: E501
 from src.rest import util
 
-from src.service.playlist_service import playlistService
-from src.service.track_service import trackService
-from src.service.engine_service import engineService
+from src.server import track_service
+
 
 
 def current_track():  # noqa: E501
@@ -37,20 +16,7 @@ def current_track():  # noqa: E501
 
     :rtype: PlayLogEntry
     """
-    return trackService.current_track()
-
-
-def get_track(track_id):  # noqa: E501
-    """Get a single track by ID
-
-    Retrieves a single track by its ID.  # noqa: E501
-
-    :param track_id: ID of the track-service entry
-    :type track_id: int
-
-    :rtype: PlayLogEntry
-    """
-    return trackService.get_track(track_id)
+    return track_service.current_track()
 
 
 def list_tracks(offset=None, limit=None):  # noqa: E501
@@ -65,26 +31,4 @@ def list_tracks(offset=None, limit=None):  # noqa: E501
 
     :rtype: List[PlayLogEntry]
     """
-    return trackService.list_tracks(offset, limit)
-
-
-def current_playlist():  # noqa: E501
-    """Get current playlist
-
-    Retrieves the currently playing playlist.  # noqa: E501
-
-
-    :rtype: Playlist
-    """
-    return playlistService.current_playlist()
-
-
-def next_playlist():  # noqa: E501
-    """Get next playlist
-
-    Retrieves the playlist playing next  # noqa: E501
-
-
-    :rtype: Playlist
-    """
-    return playlistService.next_playlist()
+    return track_service.list_tracks(offset, limit)
diff --git a/src/rest/models/__init__.py b/src/rest/models/__init__.py
index 7514045..ba5bd0e 100644
--- a/src/rest/models/__init__.py
+++ b/src/rest/models/__init__.py
@@ -3,8 +3,9 @@
 # flake8: noqa
 from __future__ import absolute_import
 # import models into model package
+from src.rest.models.clock_info import ClockInfo
 from src.rest.models.health_info import HealthInfo
 from src.rest.models.play_log_entry import PlayLogEntry
-from src.rest.models.playlist import Playlist
 from src.rest.models.playlist_entry import PlaylistEntry
+from src.rest.models.schedule import Schedule
 from src.rest.models.status_entry import StatusEntry
diff --git a/src/rest/models/clock_info.py b/src/rest/models/clock_info.py
new file mode 100644
index 0000000..7fa83ff
--- /dev/null
+++ b/src/rest/models/clock_info.py
@@ -0,0 +1,116 @@
+# coding: utf-8
+
+from __future__ import absolute_import
+from datetime import date, datetime  # noqa: F401
+
+from typing import List, Dict  # noqa: F401
+
+from src.rest.models.base_model_ import Model
+from src.rest.models.play_log_entry import PlayLogEntry  # noqa: F401,E501
+from src.rest.models.schedule import Schedule  # noqa: F401,E501
+from src.rest import util
+
+
+class ClockInfo(Model):
+    """NOTE: This class is auto generated by the swagger code generator program.
+
+    Do not edit the class manually.
+    """
+    def __init__(self, current_track=None, current_schedule=None, next_schedule=None):  # noqa: E501
+        """ClockInfo - a model defined in Swagger
+
+        :param current_track: The current_track of this ClockInfo.  # noqa: E501
+        :type current_track: PlayLogEntry
+        :param current_schedule: The current_schedule of this ClockInfo.  # noqa: E501
+        :type current_schedule: Schedule
+        :param next_schedule: The next_schedule of this ClockInfo.  # noqa: E501
+        :type next_schedule: Schedule
+        """
+        self.swagger_types = {
+            'current_track': PlayLogEntry,
+            'current_schedule': Schedule,
+            'next_schedule': Schedule
+        }
+
+        self.attribute_map = {
+            'current_track': 'current_track',
+            'current_schedule': 'current_schedule',
+            'next_schedule': 'next_schedule'
+        }
+        self._current_track = current_track
+        self._current_schedule = current_schedule
+        self._next_schedule = next_schedule
+
+    @classmethod
+    def from_dict(cls, dikt):
+        """Returns the dict as a model
+
+        :param dikt: A dict.
+        :type: dict
+        :return: The ClockInfo of this ClockInfo.  # noqa: E501
+        :rtype: ClockInfo
+        """
+        return util.deserialize_model(dikt, cls)
+
+    @property
+    def current_track(self):
+        """Gets the current_track of this ClockInfo.
+
+
+        :return: The current_track of this ClockInfo.
+        :rtype: PlayLogEntry
+        """
+        return self._current_track
+
+    @current_track.setter
+    def current_track(self, current_track):
+        """Sets the current_track of this ClockInfo.
+
+
+        :param current_track: The current_track of this ClockInfo.
+        :type current_track: PlayLogEntry
+        """
+
+        self._current_track = current_track
+
+    @property
+    def current_schedule(self):
+        """Gets the current_schedule of this ClockInfo.
+
+
+        :return: The current_schedule of this ClockInfo.
+        :rtype: Schedule
+        """
+        return self._current_schedule
+
+    @current_schedule.setter
+    def current_schedule(self, current_schedule):
+        """Sets the current_schedule of this ClockInfo.
+
+
+        :param current_schedule: The current_schedule of this ClockInfo.
+        :type current_schedule: Schedule
+        """
+
+        self._current_schedule = current_schedule
+
+    @property
+    def next_schedule(self):
+        """Gets the next_schedule of this ClockInfo.
+
+
+        :return: The next_schedule of this ClockInfo.
+        :rtype: Schedule
+        """
+        return self._next_schedule
+
+    @next_schedule.setter
+    def next_schedule(self, next_schedule):
+        """Sets the next_schedule of this ClockInfo.
+
+
+        :param next_schedule: The next_schedule of this ClockInfo.
+        :type next_schedule: Schedule
+        """
+
+        self._next_schedule = next_schedule
diff --git a/src/rest/models/schedule.py b/src/rest/models/schedule.py
new file mode 100644
index 0000000..7b839c5
--- /dev/null
+++ b/src/rest/models/schedule.py
@@ -0,0 +1,225 @@
+# coding: utf-8
+
+from __future__ import absolute_import
+from datetime import date, datetime  # noqa: F401
+
+from typing import List, Dict  # noqa: F401
+
+from src.rest.models.base_model_ import Model
+from src.rest.models.playlist_entry import PlaylistEntry  # noqa: F401,E501
+from src.rest import util
+
+
+class Schedule(Model):
+    """NOTE: This class is auto generated by the swagger code generator program.
+
+    Do not edit the class manually.
+    """
+    def __init__(self, show_name=None, schedule_id=None, schedule_start=None, schedule_end=None, playlist_id=None, fallback_type=None, entries=None):  # noqa: E501
+        """Schedule - a model defined in Swagger
+
+        :param show_name: The show_name of this Schedule.  # noqa: E501
+        :type show_name: str
+        :param schedule_id: The schedule_id of this Schedule.  # noqa: E501
+        :type schedule_id: int
+        :param schedule_start: The schedule_start of this Schedule.  # noqa: E501
+        :type schedule_start: datetime
+        :param schedule_end: The schedule_end of this Schedule.  # noqa: E501
+        :type schedule_end: datetime
+        :param playlist_id: The playlist_id of this Schedule.  # noqa: E501
+        :type playlist_id: int
+        :param fallback_type: The fallback_type of this Schedule.  # noqa: E501
+        :type fallback_type: int
+        :param entries: The entries of this Schedule.  # noqa: E501
+        :type entries: List[PlaylistEntry]
+        """
+        self.swagger_types = {
+            'show_name': str,
+            'schedule_id': int,
+            'schedule_start': datetime,
+            'schedule_end': datetime,
+            'playlist_id': int,
+            'fallback_type': int,
+            'entries': List[PlaylistEntry]
+        }
+
+        self.attribute_map = {
+            'show_name': 'show_name',
+            'schedule_id': 'schedule_id',
+            'schedule_start': 'schedule_start',
+            'schedule_end': 'schedule_end',
+            'playlist_id': 'playlist_id',
+            'fallback_type': 'fallback_type',
+            'entries': 'entries'
+        }
+        self._show_name = show_name
+        self._schedule_id = schedule_id
+        self._schedule_start = schedule_start
+        self._schedule_end = schedule_end
+        self._playlist_id = playlist_id
+        self._fallback_type = fallback_type
+        self._entries = entries
+
+    @classmethod
+    def from_dict(cls, dikt):
+        """Returns the dict as a model
+
+        :param dikt: A dict.
+        :type: dict
+        :return: The Schedule of this Schedule.  # noqa: E501
+        :rtype: Schedule
+        """
+        return util.deserialize_model(dikt, cls)
+
+    @property
+    def show_name(self):
+        """Gets the show_name of this Schedule.
+
+
+        :return: The show_name of this Schedule.
+        :rtype: str
+        """
+        return self._show_name
+
+    @show_name.setter
+    def show_name(self, show_name):
+        """Sets the show_name of this Schedule.
+
+
+        :param show_name: The show_name of this Schedule.
+        :type show_name: str
+        """
+        if show_name is None:
+            raise ValueError("Invalid value for `show_name`, must not be `None`")  # noqa: E501
+
+        self._show_name = show_name
+
+    @property
+    def schedule_id(self):
+        """Gets the schedule_id of this Schedule.
+
+
+        :return: The schedule_id of this Schedule.
+        :rtype: int
+        """
+        return self._schedule_id
+
+    @schedule_id.setter
+    def schedule_id(self, schedule_id):
+        """Sets the schedule_id of this Schedule.
+
+
+        :param schedule_id: The schedule_id of this Schedule.
+        :type schedule_id: int
+        """
+
+        self._schedule_id = schedule_id
+
+    @property
+    def schedule_start(self):
+        """Gets the schedule_start of this Schedule.
+
+
+        :return: The schedule_start of this Schedule.
+        :rtype: datetime
+        """
+        return self._schedule_start
+
+    @schedule_start.setter
+    def schedule_start(self, schedule_start):
+        """Sets the schedule_start of this Schedule.
+
+
+        :param schedule_start: The schedule_start of this Schedule.
+        :type schedule_start: datetime
+        """
+        if schedule_start is None:
+            raise ValueError("Invalid value for `schedule_start`, must not be `None`")  # noqa: E501
+
+        self._schedule_start = schedule_start
+
+    @property
+    def schedule_end(self):
+        """Gets the schedule_end of this Schedule.
+
+
+        :return: The schedule_end of this Schedule.
+        :rtype: datetime
+        """
+        return self._schedule_end
+
+    @schedule_end.setter
+    def schedule_end(self, schedule_end):
+        """Sets the schedule_end of this Schedule.
+
+
+        :param schedule_end: The schedule_end of this Schedule.
+        :type schedule_end: datetime
+        """
+        if schedule_end is None:
+            raise ValueError("Invalid value for `schedule_end`, must not be `None`")  # noqa: E501
+
+        self._schedule_end = schedule_end
+
+    @property
+    def playlist_id(self):
+        """Gets the playlist_id of this Schedule.
+
+
+        :return: The playlist_id of this Schedule.
+        :rtype: int
+        """
+        return self._playlist_id
+
+    @playlist_id.setter
+    def playlist_id(self, playlist_id):
+        """Sets the playlist_id of this Schedule.
+
+
+        :param playlist_id: The playlist_id of this Schedule.
+        :type playlist_id: int
+        """
+
+        self._playlist_id = playlist_id
+
+    @property
+    def fallback_type(self):
+        """Gets the fallback_type of this Schedule.
+
+
+        :return: The fallback_type of this Schedule.
+        :rtype: int
+        """
+        return self._fallback_type
+
+    @fallback_type.setter
+    def fallback_type(self, fallback_type):
+        """Sets the fallback_type of this Schedule.
+
+
+        :param fallback_type: The fallback_type of this Schedule.
+        :type fallback_type: int
+        """
+
+        self._fallback_type = fallback_type
+
+    @property
+    def entries(self):
+        """Gets the entries of this Schedule.
+
+
+        :return: The entries of this Schedule.
+        :rtype: List[PlaylistEntry]
+        """
+        return self._entries
+
+    @entries.setter
+    def entries(self, entries):
+        """Sets the entries of this Schedule.
+
+
+        :param entries: The entries of this Schedule.
+        :type entries: List[PlaylistEntry]
+        """
+
+        self._entries = entries
diff --git a/src/rest/swagger/swagger.yaml b/src/rest/swagger/swagger.yaml
index d2f2bc9..ff401ee 100644
--- a/src/rest/swagger/swagger.yaml
+++ b/src/rest/swagger/swagger.yaml
@@ -77,33 +77,6 @@ paths:
         "400":
           description: bad input parameter
       x-openapi-router-controller: src.rest.controllers.public_controller
-  /trackservice/{track_id}:
-    get:
-      tags:
-      - public
-      summary: Get a single track by ID
-      description: |
-        Retrieves a single track by its ID.
-      operationId: get_track
-      parameters:
-      - name: track_id
-        in: path
-        description: ID of the track-service entry
-        required: true
-        style: simple
-        explode: false
-        schema:
-          type: integer
-      responses:
-        "200":
-          description: Track matching the given ID
-          content:
-            application/json:
-              schema:
-                $ref: '#/components/schemas/PlayLogEntry'
-        "400":
-          description: bad input parameter
-      x-openapi-router-controller: src.rest.controllers.public_controller
   /trackservice/current:
     get:
       tags:
@@ -122,42 +95,24 @@ paths:
         "400":
           description: bad input parameter
       x-openapi-router-controller: src.rest.controllers.public_controller
-  /playlist/current:
+  /clock:
     get:
       tags:
-      - public
-      summary: Get current playlist
-      description: |
-        Retrieves the currently playing playlist.
-      operationId: current_playlist
-      responses:
-        "200":
-          description: Playlist currently playing
-          content:
-            application/json:
-              schema:
-                $ref: '#/components/schemas/Playlist'
-        "400":
-          description: bad input parameter
-      x-openapi-router-controller: src.rest.controllers.public_controller
-  /playlist/next:
-    get:
-      tags:
-      - public
-      summary: Get next playlist
+      - internal
+      summary: Get all information to display the studio clock
       description: |
-        Retrieves the playlist playing next
-      operationId: next_playlist
+        Retrieves the currently playing schedule, its playlist and entries plus the next schedule for being used by the studio clock.
+      operationId: clock_info
       responses:
         "200":
-          description: Playlist playing next
+          description: Schedule info for clock
           content:
             application/json:
               schema:
-                $ref: '#/components/schemas/Playlist'
+                $ref: '#/components/schemas/ClockInfo'
         "400":
           description: bad input parameter
-      x-openapi-router-controller: src.rest.controllers.public_controller
+      x-openapi-router-controller: src.rest.controllers.internal_controller
   /report/{year_month}:
     get:
       tags:
@@ -415,9 +370,56 @@ components:
       example:
         details: Stringified JSON Object
         log_time: 2020-08-29T09:12:33.001Z
-    Playlist:
+    ClockInfo:
+      type: object
+      properties:
+        current_track:
+          $ref: '#/components/schemas/PlayLogEntry'
+        current_schedule:
+          $ref: '#/components/schemas/Schedule'
+        next_schedule:
+          $ref: '#/components/schemas/Schedule'
+      example:
+        current_track:
+          track_album: Bricolage
+          show_funding_category: Standard
+          show_id: 1
+          schedule_fallback_type: 0
+          track_title: Chomp Samba
+          show_name: Special Music Show
+          track_artist: Amon Tobin
+          show_topic: Music
+          track_type: 2
+          schedule_playlist_id: 1
+          show_type: Feature
+          track_start: 2020-08-29T09:12:33.001Z
+          schedule_repetition: false
+          schedule_end: 2020-08-29T09:12:33.001Z
+          track_duration: 234
+          show_category: Progressive
+          schedule_id: 1
+          schedule_start: 2020-08-29T09:12:33.001Z
+        current_schedule:
+          entries:
+          - duration: 363
+            artist: xxyyxx
+            album: XXYYXX
+            title: Alone
+            type: 1
+          - duration: 363
+            artist: xxyyxx
+            album: XXYYXX
+            title: Alone
+            type: 1
+          playlist_id: 38
+          show_name: Future Pop
+          fallback_type: 0
+          schedule_end: 2020-08-29T09:12:33.001Z
+          schedule_id: 23
+          schedule_start: 2020-08-29T09:12:33.001Z
+    Schedule:
       required:
-      - entries
+      - playlist_entries
       - schedule_end
       - schedule_start
       - show_name
diff --git a/src/rest/test/test_internal_controller.py b/src/rest/test/test_internal_controller.py
index d625f61..2d7c2e5 100644
--- a/src/rest/test/test_internal_controller.py
+++ b/src/rest/test/test_internal_controller.py
@@ -22,6 +22,7 @@ from __future__ import absolute_import
 from flask import json
 from six import BytesIO
 
+from src.rest.models.clock_info import ClockInfo  # noqa: E501
 from src.rest.models.health_info import HealthInfo  # noqa: E501
 from src.rest.models.play_log_entry import PlayLogEntry  # noqa: E501
 from src.rest.models.status_entry import StatusEntry  # noqa: E501
@@ -42,6 +43,17 @@ class TestInternalController(BaseTestCase):
         self.assert200(response,
                        'Response body is : ' + response.data.decode('utf-8'))
 
+    def test_clock_info(self):
+        """Test case for clock_info
+
+        Get all information to display the studio clock
+        """
+        response = self.client.open(
+            '/api/v1/clock',
+            method='GET')
+        self.assert200(response,
+                       'Response body is : ' + response.data.decode('utf-8'))
+
     def test_get_active_engine(self):
         """Test case for get_active_engine
 
diff --git a/src/rest/test/test_public_controller.py b/src/rest/test/test_public_controller.py
index 93fee44..8a38b22 100644
--- a/src/rest/test/test_public_controller.py
+++ b/src/rest/test/test_public_controller.py
@@ -23,24 +23,12 @@ from flask import json
 from six import BytesIO
 
 from src.rest.models.play_log_entry import PlayLogEntry  # noqa: E501
-from src.rest.models.playlist import Playlist  # noqa: E501
 from src.rest.test import BaseTestCase
 
 
 class TestPublicController(BaseTestCase):
     """PublicController integration test stubs"""
 
-    def test_current_playlist(self):
-        """Test case for current_playlist
-
-        Get current playlist
-        """
-        response = self.client.open(
-            '/api/v1/playlist/current',
-            method='GET')
-        self.assert200(response,
-                       'Response body is : ' + response.data.decode('utf-8'))
-
     def test_current_track(self):
         """Test case for current_track
 
@@ -52,16 +40,6 @@ class TestPublicController(BaseTestCase):
         self.assert200(response,
                        'Response body is : ' + response.data.decode('utf-8'))
 
-    def test_get_track(self):
-        """Test case for get_track
-
-        Get a single track by ID
-        """
-        response = self.client.open(
-            '/api/v1/trackservice/{track_id}'.format(track_id=56),
-            method='GET')
-        self.assert200(response,
-                       'Response body is : ' + response.data.decode('utf-8'))
 
     def test_list_tracks(self):
         """Test case for list_tracks
@@ -77,17 +55,6 @@ class TestPublicController(BaseTestCase):
         self.assert200(response,
                        'Response body is : ' + response.data.decode('utf-8'))
 
-    def test_next_playlist(self):
-        """Test case for next_playlist
-
-        Get next playlist
-        """
-        response = self.client.open(
-            '/api/v1/playlist/next',
-            method='GET')
-        self.assert200(response,
-                       'Response body is : ' + response.data.decode('utf-8'))
-
 
 if __name__ == '__main__':
     import unittest
-- 
GitLab