mirror of
https://github.com/BreizhHardware/Jellystat.git
synced 2026-01-19 00:37:22 +01:00
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
This commit is contained in:
123
backend/migrations/033_js_library_stats_overview_view.js
Normal file
123
backend/migrations/033_js_library_stats_overview_view.js
Normal file
@@ -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;
|
||||
`);
|
||||
};
|
||||
|
||||
@@ -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,
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "jfstat",
|
||||
"version": "1.0.4.5",
|
||||
"version": "1.0.4.6",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@emotion/react": "^11.10.6",
|
||||
|
||||
@@ -105,12 +105,12 @@ function LibraryCard(props) {
|
||||
|
||||
<Row className="space-between-end card-row">
|
||||
<Col className="card-label">Total Files</Col>
|
||||
<Col className="text-end">{props.metadata.files}</Col>
|
||||
<Col className="text-end">{props.metadata && props.metadata.files ? props.metadata.files :0}</Col>
|
||||
</Row>
|
||||
|
||||
<Row className="space-between-end card-row">
|
||||
<Col className="card-label">Library Size</Col>
|
||||
<Col className="text-end">{formatFileSize(props.metadata.Size)}</Col>
|
||||
<Col className="text-end">{formatFileSize(props.metadata && props.metadata.Size ? props.metadata.Size:0)}</Col>
|
||||
</Row>
|
||||
|
||||
<Row className="space-between-end card-row">
|
||||
|
||||
@@ -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() {
|
||||
<div xs={1} md={2} lg={4} className="g-0 libraries-container">
|
||||
{data &&
|
||||
data.map((item) => (
|
||||
|
||||
<LibraryCard key={item.Id} data={item} metadata={metadata.find(data => data.Id === item.Id)} base_url={config.hostUrl}/>
|
||||
|
||||
<ErrorBoundary key={item.Id} >
|
||||
<LibraryCard data={item} metadata={metadata.find(data => data.Id === item.Id)} base_url={config.hostUrl}/>
|
||||
</ErrorBoundary>
|
||||
|
||||
))}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user