diff --git a/tubearchivist/api/urls.py b/tubearchivist/api/urls.py index ff4c2fce..99be8e7c 100644 --- a/tubearchivist/api/urls.py +++ b/tubearchivist/api/urls.py @@ -31,39 +31,4 @@ urlpatterns = [ views.NotificationView.as_view(), name="api-notification", ), - path( - "stats/video/", - views.StatVideoView.as_view(), - name="api-stats-video", - ), - path( - "stats/channel/", - views.StatChannelView.as_view(), - name="api-stats-channel", - ), - path( - "stats/playlist/", - views.StatPlaylistView.as_view(), - name="api-stats-playlist", - ), - path( - "stats/download/", - views.StatDownloadView.as_view(), - name="api-stats-download", - ), - path( - "stats/watch/", - views.StatWatchProgress.as_view(), - name="api-stats-watch", - ), - path( - "stats/downloadhist/", - views.StatDownloadHist.as_view(), - name="api-stats-downloadhist", - ), - path( - "stats/biggestchannels/", - views.StatBiggestChannel.as_view(), - name="api-stats-biggestchannels", - ), ] diff --git a/tubearchivist/api/views.py b/tubearchivist/api/views.py index 4afc9975..685b47c5 100644 --- a/tubearchivist/api/views.py +++ b/tubearchivist/api/views.py @@ -1,14 +1,5 @@ """all API views""" -from api.src.aggs import ( - BiggestChannel, - Channel, - Download, - DownloadHist, - Playlist, - Video, - WatchProgress, -) from api.src.search_processor import SearchProcess from appsettings.src.reindex import ReindexProgress from home.src.es.connect import ElasticWrap @@ -283,94 +274,3 @@ class NotificationView(ApiBaseView): query = f"{query}:{filter_by}" return Response(RedisArchivist().list_items(query)) - - -class StatVideoView(ApiBaseView): - """resolves to /api/stats/video/ - GET: return video stats - """ - - def get(self, request): - """get stats""" - # pylint: disable=unused-argument - - return Response(Video().process()) - - -class StatChannelView(ApiBaseView): - """resolves to /api/stats/channel/ - GET: return channel stats - """ - - def get(self, request): - """get stats""" - # pylint: disable=unused-argument - - return Response(Channel().process()) - - -class StatPlaylistView(ApiBaseView): - """resolves to /api/stats/playlist/ - GET: return playlist stats - """ - - def get(self, request): - """get stats""" - # pylint: disable=unused-argument - - return Response(Playlist().process()) - - -class StatDownloadView(ApiBaseView): - """resolves to /api/stats/download/ - GET: return download stats - """ - - def get(self, request): - """get stats""" - # pylint: disable=unused-argument - - return Response(Download().process()) - - -class StatWatchProgress(ApiBaseView): - """resolves to /api/stats/watchprogress/ - GET: return watch/unwatch progress stats - """ - - def get(self, request): - """handle get request""" - # pylint: disable=unused-argument - - return Response(WatchProgress().process()) - - -class StatDownloadHist(ApiBaseView): - """resolves to /api/stats/downloadhist/ - GET: return download video count histogram for last days - """ - - def get(self, request): - """handle get request""" - # pylint: disable=unused-argument - - return Response(DownloadHist().process()) - - -class StatBiggestChannel(ApiBaseView): - """resolves to /api/stats/biggestchannels/ - GET: return biggest channels - param: order - """ - - order_choices = ["doc_count", "duration", "media_size"] - - def get(self, request): - """handle get request""" - - order = request.GET.get("order", "doc_count") - if order and order not in self.order_choices: - message = {"message": f"invalid order parameter {order}"} - return Response(message, status=400) - - return Response(BiggestChannel(order).process()) diff --git a/tubearchivist/config/settings.py b/tubearchivist/config/settings.py index b9c1b0d2..1b893029 100644 --- a/tubearchivist/config/settings.py +++ b/tubearchivist/config/settings.py @@ -68,6 +68,7 @@ INSTALLED_APPS = [ "download", "task", "appsettings", + "stats", "config", ] diff --git a/tubearchivist/config/urls.py b/tubearchivist/config/urls.py index f0324718..d9e71068 100644 --- a/tubearchivist/config/urls.py +++ b/tubearchivist/config/urls.py @@ -26,5 +26,6 @@ urlpatterns = [ path("api/download/", include("download.urls")), path("api/task/", include("task.urls")), path("api/appsettings/", include("appsettings.urls")), + path("api/stats/", include("stats.urls")), path("admin/", admin.site.urls), ] diff --git a/tubearchivist/stats/__init__.py b/tubearchivist/stats/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tubearchivist/stats/migrations/__init__.py b/tubearchivist/stats/migrations/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tubearchivist/stats/src/__init__.py b/tubearchivist/stats/src/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tubearchivist/api/src/aggs.py b/tubearchivist/stats/src/aggs.py similarity index 100% rename from tubearchivist/api/src/aggs.py rename to tubearchivist/stats/src/aggs.py diff --git a/tubearchivist/stats/urls.py b/tubearchivist/stats/urls.py new file mode 100644 index 00000000..35fa89d4 --- /dev/null +++ b/tubearchivist/stats/urls.py @@ -0,0 +1,42 @@ +"""all stats API urls""" + +from django.urls import path +from stats import views + +urlpatterns = [ + path( + "video/", + views.StatVideoView.as_view(), + name="api-stats-video", + ), + path( + "channel/", + views.StatChannelView.as_view(), + name="api-stats-channel", + ), + path( + "playlist/", + views.StatPlaylistView.as_view(), + name="api-stats-playlist", + ), + path( + "download/", + views.StatDownloadView.as_view(), + name="api-stats-download", + ), + path( + "watch/", + views.StatWatchProgress.as_view(), + name="api-stats-watch", + ), + path( + "downloadhist/", + views.StatDownloadHist.as_view(), + name="api-stats-downloadhist", + ), + path( + "biggestchannels/", + views.StatBiggestChannel.as_view(), + name="api-stats-biggestchannels", + ), +] diff --git a/tubearchivist/stats/views.py b/tubearchivist/stats/views.py new file mode 100644 index 00000000..49af7baa --- /dev/null +++ b/tubearchivist/stats/views.py @@ -0,0 +1,104 @@ +"""all stats API views""" + +from api.views import ApiBaseView +from rest_framework.response import Response +from stats.src.aggs import ( + BiggestChannel, + Channel, + Download, + DownloadHist, + Playlist, + Video, + WatchProgress, +) + + +class StatVideoView(ApiBaseView): + """resolves to /api/stats/video/ + GET: return video stats + """ + + def get(self, request): + """get stats""" + # pylint: disable=unused-argument + + return Response(Video().process()) + + +class StatChannelView(ApiBaseView): + """resolves to /api/stats/channel/ + GET: return channel stats + """ + + def get(self, request): + """get stats""" + # pylint: disable=unused-argument + + return Response(Channel().process()) + + +class StatPlaylistView(ApiBaseView): + """resolves to /api/stats/playlist/ + GET: return playlist stats + """ + + def get(self, request): + """get stats""" + # pylint: disable=unused-argument + + return Response(Playlist().process()) + + +class StatDownloadView(ApiBaseView): + """resolves to /api/stats/download/ + GET: return download stats + """ + + def get(self, request): + """get stats""" + # pylint: disable=unused-argument + + return Response(Download().process()) + + +class StatWatchProgress(ApiBaseView): + """resolves to /api/stats/watchprogress/ + GET: return watch/unwatch progress stats + """ + + def get(self, request): + """handle get request""" + # pylint: disable=unused-argument + + return Response(WatchProgress().process()) + + +class StatDownloadHist(ApiBaseView): + """resolves to /api/stats/downloadhist/ + GET: return download video count histogram for last days + """ + + def get(self, request): + """handle get request""" + # pylint: disable=unused-argument + + return Response(DownloadHist().process()) + + +class StatBiggestChannel(ApiBaseView): + """resolves to /api/stats/biggestchannels/ + GET: return biggest channels + param: order + """ + + order_choices = ["doc_count", "duration", "media_size"] + + def get(self, request): + """handle get request""" + + order = request.GET.get("order", "doc_count") + if order and order not in self.order_choices: + message = {"message": f"invalid order parameter {order}"} + return Response(message, status=400) + + return Response(BiggestChannel(order).process())