From 37bbfef0ba8cc5eaef229f0b5bceed9673e9ca19 Mon Sep 17 00:00:00 2001 From: Thegan Govender Date: Sat, 3 Jun 2023 01:40:29 +0200 Subject: [PATCH] Fix for sync issues Change to Included mixed libraries broke sync as Jellyfin does not populate a CollectionType for this library type breaking the no-null constraint. A default value of 'mixed' will be passed instead of a null. Modified js_library_stats_overview to account for empty libraries Modified Libraries view to cater for the above changes + added error boundaries --- .../033_js_library_stats_overview_view.js | 123 ++++++++++++++++++ backend/models/jf_libraries.js | 2 +- package.json | 2 +- src/pages/components/library/library-card.js | 4 +- src/pages/libraries.js | 8 +- 5 files changed, 131 insertions(+), 8 deletions(-) create mode 100644 backend/migrations/033_js_library_stats_overview_view.js diff --git a/backend/migrations/033_js_library_stats_overview_view.js b/backend/migrations/033_js_library_stats_overview_view.js new file mode 100644 index 0000000..e99a910 --- /dev/null +++ b/backend/migrations/033_js_library_stats_overview_view.js @@ -0,0 +1,123 @@ +exports.up = function(knex) { + const query = ` + CREATE OR REPLACE VIEW public.js_library_stats_overview + AS + SELECT DISTINCT ON (l."Id") l."Id", + l."Name", + l."ServerId", + l."IsFolder", + l."Type", + l."CollectionType", + l."ImageTagsPrimary", + i."Id" AS "ItemId", + i."Name" AS "ItemName", + i."Type" AS "ItemType", + i."PrimaryImageHash", + s."IndexNumber" AS "SeasonNumber", + e."IndexNumber" AS "EpisodeNumber", + e."Name" AS "EpisodeName", + ( SELECT count(*) AS count + FROM jf_playback_activity a + JOIN jf_library_items i_1 ON a."NowPlayingItemId" = i_1."Id" + WHERE i_1."ParentId" = l."Id") AS "Plays", + ( SELECT sum(a."PlaybackDuration") AS sum + FROM jf_playback_activity a + JOIN jf_library_items i_1 ON a."NowPlayingItemId" = i_1."Id" + WHERE i_1."ParentId" = l."Id") AS total_playback_duration, + COALESCE(cv."Library_Count",0)"Library_Count", + COALESCE(cv."Season_Count",0)"Season_Count", + COALESCE(cv."Episode_Count",0)"Episode_Count", + now() - latest_activity."ActivityDateInserted" AS "LastActivity" + FROM jf_libraries l + left JOIN jf_library_count_view cv ON cv."Id" = l."Id" + LEFT JOIN ( SELECT jf_playback_activity."Id", + jf_playback_activity."IsPaused", + jf_playback_activity."UserId", + jf_playback_activity."UserName", + jf_playback_activity."Client", + jf_playback_activity."DeviceName", + jf_playback_activity."DeviceId", + jf_playback_activity."ApplicationVersion", + jf_playback_activity."NowPlayingItemId", + jf_playback_activity."NowPlayingItemName", + jf_playback_activity."SeasonId", + jf_playback_activity."SeriesName", + jf_playback_activity."EpisodeId", + jf_playback_activity."PlaybackDuration", + jf_playback_activity."ActivityDateInserted", + jf_playback_activity."PlayMethod", + i_1."ParentId" + FROM jf_playback_activity + JOIN jf_library_items i_1 ON i_1."Id" = jf_playback_activity."NowPlayingItemId" + ORDER BY jf_playback_activity."ActivityDateInserted" DESC) latest_activity ON l."Id" = latest_activity."ParentId" + LEFT JOIN jf_library_items i ON i."Id" = latest_activity."NowPlayingItemId" + LEFT JOIN jf_library_seasons s ON s."Id" = latest_activity."SeasonId" + LEFT JOIN jf_library_episodes e ON e."EpisodeId" = latest_activity."EpisodeId" + ORDER BY l."Id", latest_activity."ActivityDateInserted" DESC; + `; + + return knex.schema.raw(query).catch(function(error) { + console.error(error); + }); +}; + + + + exports.down = function(knex) { + return knex.schema.raw(` + CREATE VIEW js_library_stats_overview AS + SELECT DISTINCT ON (l."Id") l."Id", + l."Name", + l."ServerId", + l."IsFolder", + l."Type", + l."CollectionType", + l."ImageTagsPrimary", + i."Id" AS "ItemId", + i."Name" AS "ItemName", + i."Type" AS "ItemType", + i."PrimaryImageHash", + s."IndexNumber" AS "SeasonNumber", + e."IndexNumber" AS "EpisodeNumber", + e."Name" AS "EpisodeName", + ( SELECT count(*) AS count + FROM jf_playback_activity a + JOIN jf_library_items i_1 ON a."NowPlayingItemId" = i_1."Id" + WHERE i_1."ParentId" = l."Id") AS "Plays", + ( SELECT sum(a."PlaybackDuration") AS sum + FROM jf_playback_activity a + JOIN jf_library_items i_1 ON a."NowPlayingItemId" = i_1."Id" + WHERE i_1."ParentId" = l."Id") AS total_playback_duration, + cv."Library_Count", + cv."Season_Count", + cv."Episode_Count", + now() - latest_activity."ActivityDateInserted" AS "LastActivity" + FROM jf_libraries l + JOIN jf_library_count_view cv ON cv."Id" = l."Id" + LEFT JOIN ( SELECT jf_playback_activity."Id", + jf_playback_activity."IsPaused", + jf_playback_activity."UserId", + jf_playback_activity."UserName", + jf_playback_activity."Client", + jf_playback_activity."DeviceName", + jf_playback_activity."DeviceId", + jf_playback_activity."ApplicationVersion", + jf_playback_activity."NowPlayingItemId", + jf_playback_activity."NowPlayingItemName", + jf_playback_activity."SeasonId", + jf_playback_activity."SeriesName", + jf_playback_activity."EpisodeId", + jf_playback_activity."PlaybackDuration", + jf_playback_activity."ActivityDateInserted", + jf_playback_activity."PlayMethod", + i_1."ParentId" + FROM jf_playback_activity + JOIN jf_library_items i_1 ON i_1."Id" = jf_playback_activity."NowPlayingItemId" + ORDER BY jf_playback_activity."ActivityDateInserted" DESC) latest_activity ON l."Id" = latest_activity."ParentId" + LEFT JOIN jf_library_items i ON i."Id" = latest_activity."NowPlayingItemId" + LEFT JOIN jf_library_seasons s ON s."Id" = latest_activity."SeasonId" + LEFT JOIN jf_library_episodes e ON e."EpisodeId" = latest_activity."EpisodeId" + ORDER BY l."Id", latest_activity."ActivityDateInserted" DESC; + `); + }; + \ No newline at end of file diff --git a/backend/models/jf_libraries.js b/backend/models/jf_libraries.js index bed869e..aeab06f 100644 --- a/backend/models/jf_libraries.js +++ b/backend/models/jf_libraries.js @@ -15,7 +15,7 @@ ServerId: item.ServerId, IsFolder: item.IsFolder, Type: item.Type, - CollectionType: item.CollectionType, + CollectionType: item.CollectionType? item.CollectionType : 'mixed', ImageTagsPrimary: item.ImageTags && item.ImageTags.Primary ? item.ImageTags.Primary : null, }); diff --git a/package.json b/package.json index 7fa049f..f0c7c5b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jfstat", - "version": "1.0.4.5", + "version": "1.0.4.6", "private": true, "dependencies": { "@emotion/react": "^11.10.6", diff --git a/src/pages/components/library/library-card.js b/src/pages/components/library/library-card.js index a82e89f..608da9c 100644 --- a/src/pages/components/library/library-card.js +++ b/src/pages/components/library/library-card.js @@ -105,12 +105,12 @@ function LibraryCard(props) { Total Files - {props.metadata.files} + {props.metadata && props.metadata.files ? props.metadata.files :0} Library Size - {formatFileSize(props.metadata.Size)} + {formatFileSize(props.metadata && props.metadata.Size ? props.metadata.Size:0)} diff --git a/src/pages/libraries.js b/src/pages/libraries.js index b96d9d6..9fb7d4c 100644 --- a/src/pages/libraries.js +++ b/src/pages/libraries.js @@ -5,7 +5,7 @@ import Config from "../lib/config"; import "./css/library/libraries.css"; import Loading from "./components/general/loading"; import LibraryCard from "./components/library/library-card"; - +import ErrorBoundary from "./components/general/ErrorBoundary"; function Libraries() { @@ -82,9 +82,9 @@ function Libraries() {
{data && data.map((item) => ( - - data.Id === item.Id)} base_url={config.hostUrl}/> - + + data.Id === item.Id)} base_url={config.hostUrl}/> + ))}