From 897f58be64ce0a9ea10389cc5339f09c53d7204b Mon Sep 17 00:00:00 2001
From: David Trattnig <david.trattnig@o94.at>
Date: Thu, 25 Jun 2020 19:40:06 +0200
Subject: [PATCH] List tracks pagination.

---
 src/models.py                             | 25 ++++++++++++++++++++++-
 src/rest/controllers/public_controller.py | 16 +++++++--------
 src/rest/swagger/swagger.yaml             |  6 +++---
 src/service.py                            | 18 +++++++++-------
 4 files changed, 45 insertions(+), 20 deletions(-)

diff --git a/src/models.py b/src/models.py
index 1cf739f..5fd43b4 100644
--- a/src/models.py
+++ b/src/models.py
@@ -21,6 +21,7 @@
 import datetime
 
 from sqlalchemy import create_engine, Column, DateTime, String, Integer, Boolean
+from sqlalchemy.event import listen
 from flask_sqlalchemy import SQLAlchemy
 from flask_marshmallow import Marshmallow
 
@@ -83,6 +84,28 @@ class PlayLog(db.Model):
         return track
 
 
+    @staticmethod
+    def paginate(page, page_size):
+        """
+        Returns a list of entries for a given page.
+        """
+        def q(page=0, page_size=None):
+            query = db.session.query(PlayLog)
+            listen(query, 'before_compile', apply_limit(page, page_size), retval=True)
+            return query
+
+        def apply_limit(page, page_size):
+            def wrapped(query):
+                if page_size:
+                    query = query.limit(page_size)
+                    if page:
+                        query = query.offset(page * page_size)
+                return query
+            return wrapped
+
+        return q(page, page_size)
+
+
     @staticmethod
     def select_last_hours(n):
         """
@@ -131,7 +154,7 @@ class PlayLogSchema(ma.SQLAlchemyAutoSchema):
         sqla_session = db.session
 
 
-class TrackServiceSchema(ma.SQLAlchemySchema):
+class TrackSchema(ma.SQLAlchemySchema):
     """
     Schema for trackservice entries.
     """
diff --git a/src/rest/controllers/public_controller.py b/src/rest/controllers/public_controller.py
index d0e2870..f9fc50d 100644
--- a/src/rest/controllers/public_controller.py
+++ b/src/rest/controllers/public_controller.py
@@ -1,4 +1,3 @@
-
 import datetime
 import connexion
 import six
@@ -7,8 +6,6 @@ from src.rest.models.play_log_entry import PlayLogEntry  # noqa: E501
 from src.rest import util
 
 from flask import current_app
-
-
 def current_track():  # noqa: E501
     """Get current track
 
@@ -21,17 +18,18 @@ def current_track():  # noqa: E501
     return service.current_track()
 
 
-def list_tracks(offset=None, limit=None):  # noqa: E501
+def list_tracks(page=None, limit=None):  # noqa: E501
     """List recent tracks in the play-log
 
-    Lists the most recent track-service entries.  # noqa: E501
+    Lists the track-service entries for a given page.  # noqa: E501
 
-    :param offset: The number of items to skip before starting to collect the result set
-    :type offset: int
-    :param limit: The numbers of items to return
+    :param page: The number of items to skip before starting to collect the result set
+    :type page: int
+    :param limit: The numbers of items to return per page
     :type limit: int
 
     :rtype: List[PlayLogEntry]
     """
     service = current_app.config['SERVICE']
-    return service.list_tracks(offset, limit)
\ No newline at end of file
+    return service.list_tracks(offset, limit)
+    
\ No newline at end of file
diff --git a/src/rest/swagger/swagger.yaml b/src/rest/swagger/swagger.yaml
index 6faa7e1..467ce79 100644
--- a/src/rest/swagger/swagger.yaml
+++ b/src/rest/swagger/swagger.yaml
@@ -41,10 +41,10 @@ paths:
       - public
       summary: List recent tracks in the play-log
       description: |
-        Lists the most recent track-service entries.
+        Lists the track-service entries for a given page.
       operationId: list_tracks
       parameters:
-      - name: offset
+      - name: page
         in: query
         description: The number of items to skip before starting to collect the result
           set
@@ -55,7 +55,7 @@ paths:
           type: integer
       - name: limit
         in: query
-        description: The numbers of items to return
+        description: The numbers of items to return per page
         required: false
         style: form
         explode: true
diff --git a/src/service.py b/src/service.py
index 712db26..6223f08 100644
--- a/src/service.py
+++ b/src/service.py
@@ -19,7 +19,8 @@
 
 import datetime
 
-from models import PlayLog, TrackServiceSchema
+from models import PlayLog, TrackSchema
+
 
 
 class ApiService():
@@ -44,22 +45,25 @@ class ApiService():
             (PlayLogEntry)
         """
         track = PlayLog.select_current()
-        track_schema = TrackServiceSchema()
+        track_schema = TrackSchema()
         return track_schema.dump(track)
 
 
-    def list_tracks(self, offset=None, limit=None):  
+    def list_tracks(self, page=None, size=None):  
         """
-        Lists the most recent track-service entries.  
+        Lists track-service entries with pagination.
 
         Args:
-            offset (Integer): The number of items to skip before starting to collect the result set
-            limit (Integer): The numbers of items to return
+            page (Integer): The number of the page to return
+            size (Integer): The numbers of items to return
 
         Returns:
             (List[PlayLogEntry])
         """
-        return "some list of tracks"
+        if not size or size > 50 or size < 1: size = 20
+        tracklist = PlayLog.paginate(page, size)
+        tracklist_schema = TrackSchema(many=True)
+        return tracklist_schema.dump(tracklist)
 
 
     def clock_info(self):
-- 
GitLab