diff --git a/tubearchivist/home/templates/home/settings.html b/tubearchivist/home/templates/home/settings.html
index 52a2693..93f3e74 100644
--- a/tubearchivist/home/templates/home/settings.html
+++ b/tubearchivist/home/templates/home/settings.html
@@ -5,10 +5,13 @@
Your Archive
-
Main Overview
+
Overview
+
Watch Progress
diff --git a/tubearchivist/static/stats.js b/tubearchivist/static/stats.js
index d575ea4..d85955a 100644
--- a/tubearchivist/static/stats.js
+++ b/tubearchivist/static/stats.js
@@ -5,158 +5,140 @@
/* globals apiRequest */
function primaryStats() {
- let apiEndpoint = '/api/stats/primary/';
- let responseData = apiRequest(apiEndpoint, 'GET');
- let primaryBox = document.getElementById('primaryBox');
+ let apiVideoEndpoint = '/api/stats/video/';
+ let responseData = apiRequest(apiVideoEndpoint, 'GET');
+ let primaryBox = document.getElementById('primaryBox');
clearLoading(primaryBox);
- let videoTile = buildVideoTile(responseData);
- primaryBox.appendChild(videoTile);
+ let totalTile = buildTotalVideoTile(responseData);
+ primaryBox.appendChild(totalTile);
- let channelTile = buildChannelTile(responseData);
- primaryBox.appendChild(channelTile);
+ let videosTypeTile = buildVideosTypeTile(responseData);
+ primaryBox.appendChild(videosTypeTile);
- let playlistTile = buildPlaylistTile(responseData);
- primaryBox.appendChild(playlistTile);
+ let shortsTypeTile = buildShortsTypeTile(responseData);
+ primaryBox.appendChild(shortsTypeTile);
- let downloadTile = buildDownloadTile(responseData);
- primaryBox.appendChild(downloadTile);
+ let streamsTypeTile = buildStreamsTypeTile(responseData);
+ primaryBox.appendChild(streamsTypeTile);
}
-function clearLoading(dashBox) {
- dashBox.querySelector('#loading').remove();
+function secondaryStats() {
+ let apiChannelEndpoint = '/api/stats/channel/';
+ let channelResponseData = apiRequest(apiChannelEndpoint, 'GET');
+ let secondaryBox = document.getElementById('secondaryBox');
+ clearLoading(secondaryBox);
+ let channelTile = buildChannelTile(channelResponseData);
+ secondaryBox.appendChild(channelTile);
+
+ let apiPlaylistEndpoint = '/api/stats/playlist/';
+ let playlistResponseData = apiRequest(apiPlaylistEndpoint, 'GET');
+ let playlistTile = buildPlaylistTile(playlistResponseData);
+ secondaryBox.appendChild(playlistTile);
+
+ let apiDownloadEndpoint = '/api/stats/download/';
+ let downloadResponseData = apiRequest(apiDownloadEndpoint, 'GET');
+ let downloadTile = buildDownloadTile(downloadResponseData);
+ secondaryBox.appendChild(downloadTile);
}
-function buildTile(titleText) {
- let tile = document.createElement('div');
- tile.classList.add('info-box-item');
-
- let title = document.createElement('h3');
-
- title.innerText = titleText;
- tile.appendChild(title);
-
+function buildTotalVideoTile(responseData) {
+ const totalCount = responseData.doc_count || 0;
+ const totalSize = humanFileSize(responseData.media_size || 0);
+ const content = {
+ Items: `${totalCount}`,
+ 'Media Size': `${totalSize}`,
+ };
+ const tile = buildTile('All: ');
+ const table = buildTileContenTable(content, 2);
+ tile.appendChild(table);
return tile;
}
-function buildTileContenTable(content, rowsWanted) {
- let contentEntries = Object.entries(content);
-
- const nbsp = '\u00A0'; // No-Break Space https://www.compart.com/en/unicode/U+00A0
-
- // Do not add spacing rows when on mobile device
- const isMobile = window.matchMedia('(max-width: 600px)');
- if (!isMobile.matches) {
- if (contentEntries.length < rowsWanted) {
- const rowsToAdd = rowsWanted - contentEntries.length;
-
- for (let i = 0; i < rowsToAdd; i++) {
- contentEntries.push([nbsp, nbsp]);
- }
- }
- }
-
- const table = document.createElement('table');
- table.classList.add('agg-channel-table');
- const tableBody = document.createElement('tbody');
-
- for (const [key, value] of contentEntries) {
- const row = document.createElement('tr');
-
- const leftCell = document.createElement('td');
- leftCell.classList.add('agg-channel-name');
-
- // Do not add ":" when its a spacing entry
- const keyText = key === nbsp ? key : `${key}: `;
- const leftText = document.createTextNode(keyText);
- leftCell.appendChild(leftText);
-
- const rightCell = document.createElement('td');
- rightCell.classList.add('agg-channel-right-align');
-
- const rightText = document.createTextNode(value);
- rightCell.appendChild(rightText);
-
- row.appendChild(leftCell);
- row.appendChild(rightCell);
-
- tableBody.appendChild(row);
- }
-
- table.appendChild(tableBody);
-
- return table;
+function buildVideosTypeTile(responseData) {
+ const videosCount = responseData.type_videos.doc_count || 0;
+ const videosSize = humanFileSize(responseData.type_videos.media_size || 0);
+ const content = {
+ Items: `${videosCount}`,
+ 'Media Size': `${videosSize}`,
+ };
+ const tile = buildTile('Regular Videos: ');
+ const table = buildTileContenTable(content, 2);
+ tile.appendChild(table);
+ return tile;
}
-function buildVideoTile(responseData) {
- let tile = buildTile(`Video types: `);
-
- const total = responseData.videos.total || 0;
- const videos = responseData.videos.videos || 0;
- const shorts = responseData.videos.shorts || 0;
- const streams = responseData.videos.streams || 0;
-
+function buildShortsTypeTile(responseData) {
+ const shortsCount = responseData.type_shorts.doc_count || 0;
+ const shortsSize = humanFileSize(responseData.type_shorts.media_size || 0);
const content = {
- Videos: `${videos}/${total}`,
- Shorts: `${shorts}/${total}`,
- Streams: `${streams}/${total}`,
+ Items: `${shortsCount}`,
+ 'Media Size': `${shortsSize}`,
};
-
- const table = buildTileContenTable(content, 3);
-
+ const tile = buildTile('Shorts: ');
+ const table = buildTileContenTable(content, 2);
tile.appendChild(table);
+ return tile;
+}
+function buildStreamsTypeTile(responseData) {
+ const streamsCount = responseData.type_streams.doc_count || 0;
+ const streamsSize = humanFileSize(responseData.type_streams.media_size || 0);
+ const content = {
+ Items: `${streamsCount}`,
+ 'Media Size': `${streamsSize}`,
+ };
+ const tile = buildTile('Streams: ');
+ const table = buildTileContenTable(content, 2);
+ tile.appendChild(table);
return tile;
}
function buildChannelTile(responseData) {
- let tile = buildTile(`Channels: `);
-
- const total = responseData.channels.total || 0;
- const subscribed = responseData.channels.sub_true || 0;
-
+ let tile = buildTile('Channels: ');
+ const total = responseData.doc_count || 0;
+ const subscribed = responseData.subscribed_true || 0;
+ const active = responseData.active_true || 0;
const content = {
- Subscribed: `${subscribed}/${total}`,
+ Subscribed: subscribed,
+ Active: active,
+ Total: total,
};
-
const table = buildTileContenTable(content, 3);
-
tile.appendChild(table);
return tile;
}
function buildPlaylistTile(responseData) {
- let tile = buildTile(`Playlists:`);
-
- const total = responseData.playlists.total || 0;
- const subscribed = responseData.playlists.sub_true || 0;
-
+ let tile = buildTile('Playlists: ');
+ const total = responseData.doc_count || 0;
+ const subscribed = responseData.subscribed_true || 0;
+ const active = responseData.active_true || 0;
const content = {
- Subscribed: `${subscribed}/${total}`,
+ Subscribed: subscribed,
+ Active: active,
+ Total: total,
};
-
- const table = buildTileContenTable(content, 3);
-
+ const table = buildTileContenTable(content, 2);
tile.appendChild(table);
return tile;
}
function buildDownloadTile(responseData) {
- let tile = buildTile('Downloads');
-
- const pending = responseData.downloads.pending || 0;
- const ignored = responseData.downloads.ignore || 0;
-
+ const pendingTotal = responseData.pending || 0;
+ let tile = buildTile(`Downloads Pending: ${pendingTotal}`);
+ const pendingVideos = responseData.pending_videos || 0;
+ const pendingShorts = responseData.pending_shorts || 0;
+ const pendingStreams = responseData.pending_streams || 0;
const content = {
- Pending: pending,
- Ignored: ignored,
+ Videos: pendingVideos,
+ Shorts: pendingShorts,
+ Streams: pendingStreams,
};
-
const table = buildTileContenTable(content, 3);
-
tile.appendChild(table);
return tile;
@@ -180,11 +162,6 @@ function watchStats() {
watchBox.appendChild(thirdCard);
}
-function capitalizeFirstLetter(string) {
- // source: https://stackoverflow.com/a/1026087
- return string.charAt(0).toUpperCase() + string.slice(1);
-}
-
function buildWatchTile(title, watchDetail) {
const items = watchDetail?.items ?? 0;
const duration = watchDetail?.duration ?? 0;
@@ -248,11 +225,6 @@ function buildDailyStat(dailyStat) {
return tile;
}
-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 buildChannelRow(id, name, value) {
let tableRow = document.createElement('tr');
@@ -309,6 +281,81 @@ function addBiggestChannelByMediaSize() {
}
}
+function clearLoading(dashBox) {
+ dashBox.querySelector('#loading').remove();
+}
+
+function capitalizeFirstLetter(string) {
+ // source: https://stackoverflow.com/a/1026087
+ return string.charAt(0).toUpperCase() + string.slice(1);
+}
+
+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 buildTile(titleText) {
+ let tile = document.createElement('div');
+ tile.classList.add('info-box-item');
+
+ let title = document.createElement('h3');
+
+ title.innerText = titleText;
+ tile.appendChild(title);
+
+ return tile;
+}
+
+function buildTileContenTable(content, rowsWanted) {
+ let contentEntries = Object.entries(content);
+
+ const nbsp = '\u00A0'; // No-Break Space https://www.compart.com/en/unicode/U+00A0
+
+ // Do not add spacing rows when on mobile device
+ const isMobile = window.matchMedia('(max-width: 600px)');
+ if (!isMobile.matches) {
+ if (contentEntries.length < rowsWanted) {
+ const rowsToAdd = rowsWanted - contentEntries.length;
+
+ for (let i = 0; i < rowsToAdd; i++) {
+ contentEntries.push([nbsp, nbsp]);
+ }
+ }
+ }
+
+ const table = document.createElement('table');
+ table.classList.add('agg-channel-table');
+ const tableBody = document.createElement('tbody');
+
+ for (const [key, value] of contentEntries) {
+ const row = document.createElement('tr');
+
+ const leftCell = document.createElement('td');
+ leftCell.classList.add('agg-channel-name');
+
+ // Do not add ":" when its a spacing entry
+ const keyText = key === nbsp ? key : `${key}: `;
+ const leftText = document.createTextNode(keyText);
+ leftCell.appendChild(leftText);
+
+ const rightCell = document.createElement('td');
+ rightCell.classList.add('agg-channel-right-align');
+
+ const rightText = document.createTextNode(value);
+ rightCell.appendChild(rightText);
+
+ row.appendChild(leftCell);
+ row.appendChild(rightCell);
+
+ tableBody.appendChild(row);
+ }
+
+ table.appendChild(tableBody);
+
+ return table;
+}
+
function biggestChannel() {
addBiggestChannelByDocCount();
addBiggestChannelByDuration();
@@ -317,6 +364,7 @@ function biggestChannel() {
async function buildStats() {
primaryStats();
+ secondaryStats();
watchStats();
downloadHist();
biggestChannel();