mirror of
https://github.com/ajnart/homarr.git
synced 2026-02-27 00:40:58 +01:00
fix: Tdarr widget empty statistics tab (#2883)
Co-authored-by: Manuel <30572287+manuel-rw@users.noreply.github.com>
This commit is contained in:
@@ -4,6 +4,7 @@ export interface TdarrPieSegment {
|
||||
}
|
||||
|
||||
export interface TdarrStatistics {
|
||||
libraryName: string;
|
||||
totalFileCount: number;
|
||||
totalTranscodeCount: number;
|
||||
totalHealthCheckCount: number;
|
||||
@@ -11,19 +12,12 @@ export interface TdarrStatistics {
|
||||
failedHealthCheckCount: number;
|
||||
stagedTranscodeCount: number;
|
||||
stagedHealthCheckCount: number;
|
||||
pies: {
|
||||
libraryName: string;
|
||||
libraryId: string;
|
||||
totalFiles: number;
|
||||
totalTranscodes: number;
|
||||
savedSpace: number;
|
||||
totalHealthChecks: number;
|
||||
transcodeStatus: TdarrPieSegment[];
|
||||
healthCheckStatus: TdarrPieSegment[];
|
||||
videoCodecs: TdarrPieSegment[];
|
||||
videoContainers: TdarrPieSegment[];
|
||||
videoResolutions: TdarrPieSegment[];
|
||||
audioCodecs: TdarrPieSegment[];
|
||||
audioContainers: TdarrPieSegment[];
|
||||
}[];
|
||||
totalSavedSpace: number;
|
||||
transcodeStatus: TdarrPieSegment[];
|
||||
healthCheckStatus: TdarrPieSegment[];
|
||||
videoCodecs: TdarrPieSegment[];
|
||||
videoContainers: TdarrPieSegment[];
|
||||
videoResolutions: TdarrPieSegment[];
|
||||
audioCodecs: TdarrPieSegment[];
|
||||
audioContainers: TdarrPieSegment[];
|
||||
}
|
||||
|
||||
@@ -20,15 +20,13 @@ export class TdarrIntegration extends Integration {
|
||||
}
|
||||
|
||||
public async getStatisticsAsync(): Promise<TdarrStatistics> {
|
||||
const url = this.url("/api/v2/cruddb");
|
||||
const url = this.url("/api/v2/stats/get-pies");
|
||||
const response = await fetchWithTrustedCertificatesAsync(url, {
|
||||
method: "POST",
|
||||
headers: { "content-type": "application/json" },
|
||||
headers: { accept: "application/json", "Content-Type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
data: {
|
||||
collection: "StatisticsJSONDB",
|
||||
mode: "getById",
|
||||
docID: "statistics",
|
||||
libraryId: "", // empty string to get all libraries
|
||||
},
|
||||
}),
|
||||
});
|
||||
@@ -36,28 +34,29 @@ export class TdarrIntegration extends Integration {
|
||||
const statisticsData = await getStatisticsSchema.parseAsync(await response.json());
|
||||
|
||||
return {
|
||||
totalFileCount: statisticsData.totalFileCount,
|
||||
totalTranscodeCount: statisticsData.totalTranscodeCount,
|
||||
totalHealthCheckCount: statisticsData.totalHealthCheckCount,
|
||||
failedTranscodeCount: statisticsData.table3Count,
|
||||
failedHealthCheckCount: statisticsData.table6Count,
|
||||
stagedTranscodeCount: statisticsData.table1Count,
|
||||
stagedHealthCheckCount: statisticsData.table4Count,
|
||||
pies: statisticsData.pies.map((pie) => ({
|
||||
libraryName: pie[0],
|
||||
libraryId: pie[1],
|
||||
totalFiles: pie[2],
|
||||
totalTranscodes: pie[3],
|
||||
savedSpace: pie[4] * 1_000_000_000, // file_size is in GB, convert to bytes,
|
||||
totalHealthChecks: pie[5],
|
||||
transcodeStatus: pie[6],
|
||||
healthCheckStatus: pie[7],
|
||||
videoCodecs: pie[8],
|
||||
videoContainers: pie[9],
|
||||
videoResolutions: pie[10],
|
||||
audioCodecs: pie[11],
|
||||
audioContainers: pie[12],
|
||||
})),
|
||||
libraryName: "All",
|
||||
totalFileCount: statisticsData.pieStats.totalFiles,
|
||||
totalTranscodeCount: statisticsData.pieStats.totalTranscodeCount,
|
||||
totalHealthCheckCount: statisticsData.pieStats.totalHealthCheckCount,
|
||||
// The Tdarr API only returns a category if there is at least one item in it
|
||||
failedTranscodeCount:
|
||||
statisticsData.pieStats.status.transcode.find((transcode) => transcode.name === "Transcode error")?.value ?? 0,
|
||||
failedHealthCheckCount:
|
||||
statisticsData.pieStats.status.healthcheck.find((healthcheck) => healthcheck.name === "Error")?.value ?? 0,
|
||||
stagedTranscodeCount:
|
||||
statisticsData.pieStats.status.transcode.find((transcode) => transcode.name === "Transcode success")?.value ??
|
||||
0,
|
||||
stagedHealthCheckCount:
|
||||
statisticsData.pieStats.status.healthcheck.find((healthcheck) => healthcheck.name === "Queued")?.value ?? 0,
|
||||
|
||||
totalSavedSpace: statisticsData.pieStats.sizeDiff * 1_000_000_000, // sizeDiff is in GB, convert to bytes
|
||||
transcodeStatus: statisticsData.pieStats.status.transcode,
|
||||
healthCheckStatus: statisticsData.pieStats.status.healthcheck,
|
||||
videoCodecs: statisticsData.pieStats.video.codecs,
|
||||
videoContainers: statisticsData.pieStats.video.containers,
|
||||
videoResolutions: statisticsData.pieStats.video.resolutions,
|
||||
audioCodecs: statisticsData.pieStats.audio.codecs,
|
||||
audioContainers: statisticsData.pieStats.audio.containers,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -124,7 +123,7 @@ export class TdarrIntegration extends Integration {
|
||||
healthCheck: item.HealthCheck,
|
||||
transcode: item.TranscodeDecisionMaker,
|
||||
filePath: item.file,
|
||||
fileSize: item.file_size * 1_000_000, // file_size is in MB, convert to bytes
|
||||
fileSize: Math.floor(item.file_size * 1_000_000), // file_size is in MB, convert to bytes, floor because it returns as float
|
||||
container: item.container,
|
||||
codec: item.video_codec_name,
|
||||
resolution: item.video_resolution,
|
||||
@@ -162,7 +161,7 @@ export class TdarrIntegration extends Integration {
|
||||
healthCheck: item.HealthCheck,
|
||||
transcode: item.TranscodeDecisionMaker,
|
||||
filePath: item.file,
|
||||
fileSize: item.file_size * 1_000_000, // file_size is in MB, convert to bytes
|
||||
fileSize: Math.floor(item.file_size * 1_000_000), // file_size is in MB, convert to bytes, floor because it returns as float
|
||||
container: item.container,
|
||||
codec: item.video_codec_name,
|
||||
resolution: item.video_resolution,
|
||||
|
||||
@@ -1,72 +1,60 @@
|
||||
import { z } from "zod";
|
||||
|
||||
export const getStatisticsSchema = z.object({
|
||||
totalFileCount: z.number(),
|
||||
totalTranscodeCount: z.number(),
|
||||
totalHealthCheckCount: z.number(),
|
||||
table3Count: z.number(),
|
||||
table6Count: z.number(),
|
||||
table1Count: z.number(),
|
||||
table4Count: z.number(),
|
||||
pies: z.array(
|
||||
z.tuple([
|
||||
z.string(), // Library Name
|
||||
z.string(), // Library ID
|
||||
z.number(), // File count
|
||||
z.number(), // Number of transcodes
|
||||
z.number(), // Space saved (in GB)
|
||||
z.number(), // Number of health checks
|
||||
z.array(
|
||||
pieStats: z.object({
|
||||
totalFiles: z.number(),
|
||||
totalTranscodeCount: z.number(),
|
||||
sizeDiff: z.number(),
|
||||
totalHealthCheckCount: z.number(),
|
||||
status: z.object({
|
||||
transcode: z.array(
|
||||
z.object({
|
||||
// Transcode Status (Pie segments)
|
||||
name: z.string(),
|
||||
value: z.number(),
|
||||
}),
|
||||
),
|
||||
z.array(
|
||||
healthcheck: z.array(
|
||||
z.object({
|
||||
// Health Status (Pie segments)
|
||||
name: z.string(),
|
||||
value: z.number(),
|
||||
}),
|
||||
),
|
||||
z.array(
|
||||
}),
|
||||
video: z.object({
|
||||
codecs: z.array(
|
||||
z.object({
|
||||
// Video files - Codecs (Pie segments)
|
||||
name: z.string(),
|
||||
value: z.number(),
|
||||
}),
|
||||
),
|
||||
z.array(
|
||||
containers: z.array(
|
||||
z.object({
|
||||
// Video files - Containers (Pie segments)
|
||||
name: z.string(),
|
||||
value: z.number(),
|
||||
}),
|
||||
),
|
||||
z.array(
|
||||
resolutions: z.array(
|
||||
z.object({
|
||||
// Video files - Resolutions (Pie segments)
|
||||
name: z.string(),
|
||||
value: z.number(),
|
||||
}),
|
||||
),
|
||||
z.array(
|
||||
}),
|
||||
audio: z.object({
|
||||
codecs: z.array(
|
||||
z.object({
|
||||
// Audio files - Codecs (Pie segments)
|
||||
name: z.string(),
|
||||
value: z.number(),
|
||||
}),
|
||||
),
|
||||
z.array(
|
||||
containers: z.array(
|
||||
z.object({
|
||||
// Audio files - Containers (Pie segments)
|
||||
name: z.string(),
|
||||
value: z.number(),
|
||||
}),
|
||||
),
|
||||
]),
|
||||
),
|
||||
}),
|
||||
}),
|
||||
});
|
||||
|
||||
export const getNodesResponseSchema = z.record(
|
||||
|
||||
@@ -17,9 +17,10 @@ interface StatisticsPanelProps {
|
||||
export function StatisticsPanel(props: StatisticsPanelProps) {
|
||||
const t = useI18n("widget.mediaTranscoding.panel.statistics");
|
||||
|
||||
const allLibs = props.statistics.pies.find((pie) => pie.libraryName === "All");
|
||||
const allLibs = props.statistics;
|
||||
|
||||
if (!allLibs) {
|
||||
// Check if Tdarr hs any Files
|
||||
if (!(allLibs.totalFileCount > 0)) {
|
||||
return (
|
||||
<Center style={{ flex: "1" }}>
|
||||
<Title order={6}>{t("empty")}</Title>
|
||||
@@ -40,7 +41,7 @@ export function StatisticsPanel(props: StatisticsPanelProps) {
|
||||
<StatisticItem
|
||||
icon={IconDatabaseHeart}
|
||||
label={t("savedSpace")}
|
||||
value={humanFileSize(Math.floor(allLibs.savedSpace))}
|
||||
value={humanFileSize(Math.floor(allLibs.totalSavedSpace))}
|
||||
/>
|
||||
</Group>
|
||||
<Group justify="center" wrap="wrap" grow>
|
||||
|
||||
Reference in New Issue
Block a user