diff --git a/backend/routes/stats.js b/backend/routes/stats.js index 2a78f66..a727991 100644 --- a/backend/routes/stats.js +++ b/backend/routes/stats.js @@ -407,9 +407,9 @@ router.post("/getLibraryLastPlayed", async (req, res) => { } }); -router.post("/getViewsOverTime", async (req, res) => { +router.get("/getViewsOverTime", async (req, res) => { try { - const { days } = req.body; + const { days } = req.query; let _days = days; if (days === undefined) { _days = 30; @@ -446,9 +446,9 @@ router.post("/getViewsOverTime", async (req, res) => { } }); -router.post("/getViewsByDays", async (req, res) => { +router.get("/getViewsByDays", async (req, res) => { try { - const { days } = req.body; + const { days } = req.query; let _days = days; if (days === undefined) { _days = 30; @@ -481,9 +481,9 @@ router.post("/getViewsByDays", async (req, res) => { } }); -router.post("/getViewsByHour", async (req, res) => { +router.get("/getViewsByHour", async (req, res) => { try { - const { days } = req.body; + const { days } = req.query; let _days = days; if (days === undefined) { _days = 30; @@ -516,6 +516,41 @@ router.post("/getViewsByHour", async (req, res) => { } }); +router.get("/getViewsByLibraryType", async (req, res) => { + try { + const { days = 30 } = req.query; + + const { rows } = await db.query(` + SELECT COALESCE(i."Type", 'Other') AS type, COUNT(a."NowPlayingItemId") AS count + FROM jf_playback_activity a LEFT JOIN jf_library_items i ON i."Id" = a."NowPlayingItemId" + WHERE a."ActivityDateInserted" BETWEEN NOW() - CAST($1 || ' days' as INTERVAL) AND NOW() + GROUP BY i."Type" + `, [days]); + + const supportedTypes = new Set(["Audio", "Movie", "Series", "Other"]); + /** @type {Map} */ + const reorganizedData = new Map(); + + rows.forEach((item) => { + const { type, count } = item; + + if (!supportedTypes.has(type)) return; + reorganizedData.set(type, count); + }); + + supportedTypes.forEach((type) => { + if (reorganizedData.has(type)) return; + reorganizedData.set(type, 0); + }); + + res.send(Object.fromEntries(reorganizedData)); + } catch (error) { + console.log(error); + res.status(503); + res.send(error); + } +}); + router.get("/getGenreUserStats", async (req, res) => { try { const { size = 50, page = 1, userid } = req.query; diff --git a/backend/swagger.json b/backend/swagger.json index 84ec7fe..00fc18b 100644 --- a/backend/swagger.json +++ b/backend/swagger.json @@ -3504,7 +3504,7 @@ } }, "/stats/getViewsOverTime": { - "post": { + "get": { "tags": [ "Stats" ], @@ -3526,16 +3526,9 @@ "type": "string" }, { - "name": "body", - "in": "body", - "schema": { - "type": "object", - "properties": { - "days": { - "example": "any" - } - } - } + "name": "days", + "in": "query", + "type": "string" } ], "responses": { @@ -3558,7 +3551,7 @@ } }, "/stats/getViewsByDays": { - "post": { + "get": { "tags": [ "Stats" ], @@ -3580,16 +3573,9 @@ "type": "string" }, { - "name": "body", - "in": "body", - "schema": { - "type": "object", - "properties": { - "days": { - "example": "any" - } - } - } + "name": "days", + "in": "query", + "type": "string" } ], "responses": { @@ -3612,7 +3598,7 @@ } }, "/stats/getViewsByHour": { - "post": { + "get": { "tags": [ "Stats" ], @@ -3634,16 +3620,56 @@ "type": "string" }, { - "name": "body", - "in": "body", - "schema": { - "type": "object", - "properties": { - "days": { - "example": "any" - } - } - } + "name": "days", + "in": "query", + "type": "string" + } + ], + "responses": { + "200": { + "description": "OK" + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Not Found" + }, + "503": { + "description": "Service Unavailable" + } + } + } + }, + "/stats/getViewsByLibraryType": { + "get": { + "tags": [ + "Stats" + ], + "description": "", + "parameters": [ + { + "name": "authorization", + "in": "header", + "type": "string" + }, + { + "name": "x-api-token", + "in": "header", + "type": "string" + }, + { + "name": "req", + "in": "query", + "type": "string" + }, + { + "name": "days", + "in": "query", + "type": "string" } ], "responses": { diff --git a/src/pages/components/statistics/daily-play-count.jsx b/src/pages/components/statistics/daily-play-count.jsx index 3e896fc..e7b9316 100644 --- a/src/pages/components/statistics/daily-play-count.jsx +++ b/src/pages/components/statistics/daily-play-count.jsx @@ -17,12 +17,11 @@ function DailyPlayStats(props) { useEffect(() => { const fetchLibraries = () => { - const url = `/stats/getViewsOverTime`; + const url = `/stats/getViewsOverTime?days=${props.days}`; axios - .post( + .get( url, - { days: props.days }, { headers: { Authorization: `Bearer ${token}`, diff --git a/src/pages/components/statistics/play-stats-by-day.jsx b/src/pages/components/statistics/play-stats-by-day.jsx index d04843c..c7f5c09 100644 --- a/src/pages/components/statistics/play-stats-by-day.jsx +++ b/src/pages/components/statistics/play-stats-by-day.jsx @@ -13,12 +13,11 @@ function PlayStatsByDay(props) { useEffect(() => { const fetchLibraries = () => { - const url = `/stats/getViewsByDays`; + const url = `/stats/getViewsByDays?days=${props.days}`; axios - .post( + .get( url, - { days: props.days }, { headers: { Authorization: `Bearer ${token}`, diff --git a/src/pages/components/statistics/play-stats-by-hour.jsx b/src/pages/components/statistics/play-stats-by-hour.jsx index 4403400..f1895d3 100644 --- a/src/pages/components/statistics/play-stats-by-hour.jsx +++ b/src/pages/components/statistics/play-stats-by-hour.jsx @@ -12,12 +12,11 @@ function PlayStatsByHour(props) { useEffect(() => { const fetchLibraries = () => { - const url = `/stats/getViewsByHour`; + const url = `/stats/getViewsByHour?days=${props.days}`; axios - .post( + .get( url, - { days: props.days }, { headers: { Authorization: `Bearer ${token}`,