From 5ee37eb0cbc59441dd8ddfa20df53670a5e98190 Mon Sep 17 00:00:00 2001 From: Simon Date: Fri, 1 Sep 2023 09:28:56 +0700 Subject: [PATCH] add biggest chanel aggs --- tubearchivist/api/src/aggs.py | 10 +++---- tubearchivist/api/views.py | 2 +- .../home/templates/home/settings.html | 16 +++++++++++ tubearchivist/static/css/style.css | 5 ++++ tubearchivist/static/stats.js | 28 +++++++++++++++++++ 5 files changed, 55 insertions(+), 6 deletions(-) diff --git a/tubearchivist/api/src/aggs.py b/tubearchivist/api/src/aggs.py index f663d134..b8db502b 100644 --- a/tubearchivist/api/src/aggs.py +++ b/tubearchivist/api/src/aggs.py @@ -211,11 +211,8 @@ class BiggestChannel(AggBase): } order_choices = ["doc_count", "duration", "media_size"] - def process(self, order_by=False): - """process aggregation""" - - if order_by and order_by in self.order_choices: - self.data["aggs"][self.name]["multi_terms"]["order"] = order_by + def process(self): + """process aggregation, order_by validated in the view""" aggregations = self.get() buckets = aggregations[self.name]["buckets"] @@ -226,6 +223,9 @@ class BiggestChannel(AggBase): "name": i["key"][0].title(), "doc_count": i["doc_count"]["value"], "duration": i["duration"]["value"], + "duration_str": DurationConverter().get_str( + i["duration"]["value"] + ), "media_size": i["media_size"]["value"], } for i in buckets diff --git a/tubearchivist/api/views.py b/tubearchivist/api/views.py index cf9521f4..24db6dda 100644 --- a/tubearchivist/api/views.py +++ b/tubearchivist/api/views.py @@ -1025,7 +1025,7 @@ class StatBiggestChannel(ApiBaseView): def get(self, request): """handle get request""" - order = request.GET.get("order") + order = request.GET.get("order", False) if order and order not in self.order_choices: message = {"message": f"invalid order parameter {order}"} return Response(message, status=400) diff --git a/tubearchivist/home/templates/home/settings.html b/tubearchivist/home/templates/home/settings.html index 8a2256e8..edaaeaf0 100644 --- a/tubearchivist/home/templates/home/settings.html +++ b/tubearchivist/home/templates/home/settings.html @@ -12,5 +12,21 @@

Watch Progress

+
+

Biggest Channels

+
+ + + + + + + + + + +
NameVideosDurationMedia Size
+
+
{% endblock settings_content %} diff --git a/tubearchivist/static/css/style.css b/tubearchivist/static/css/style.css index df9dfadd..a70cba4a 100644 --- a/tubearchivist/static/css/style.css +++ b/tubearchivist/static/css/style.css @@ -82,6 +82,7 @@ ul { td, th, span, label { font-family: Sen-Regular, sans-serif; color: var(--main-font); + text-align: left; } select, input { @@ -655,6 +656,10 @@ video:-webkit-full-screen { grid-template-columns: 1fr 1fr; } +.info-box-1 { + grid-template-columns: 1fr; +} + .info-box img { width: 80px; margin: 0 15px; diff --git a/tubearchivist/static/stats.js b/tubearchivist/static/stats.js index 0bc5e402..0bdba344 100644 --- a/tubearchivist/static/stats.js +++ b/tubearchivist/static/stats.js @@ -96,9 +96,37 @@ function buildWatchTile(title, watchDetail) { return tile; } +function biggestChannel() { + let apiEndpoint = '/api/stats/biggestchannels/'; + let responseData = apiRequest(apiEndpoint, 'GET'); + let tBody = document.getElementById('biggestChannelTable'); + for (let i = 0; i < responseData.length; i++) { + const channelData = responseData[i]; + let tableRow = buildChannelRow(channelData); + tBody.appendChild(tableRow); + } +} + +function buildChannelRow(channelData) { + let tableRow = document.createElement('tr'); + tableRow.innerHTML = ` + ${channelData.name} + ${channelData.doc_count} + ${channelData.duration_str} + ${humanFileSize(channelData.media_size)} + `; + return tableRow; +} + +function humanFileSize(size) { + let i = size === 0 ? 0 : Math.floor(Math.log(size) / Math.log(1024)); + return (size / Math.pow(1024, i)).toFixed(1) * 1 + ' ' + ['B', 'kB', 'MB', 'GB', 'TB'][i]; +} + function buildStats() { primaryStats(); watchStats(); + biggestChannel(); } buildStats();