From 76d715a7512a12b931492ac69f8994019ce112de Mon Sep 17 00:00:00 2001 From: mrjvs Date: Sat, 11 Nov 2023 16:17:13 +0100 Subject: [PATCH] remove old log and finish metrics for scrapePart Co-authored-by: William Oldham --- src/backend/helpers/report.ts | 102 +++++++++++++++++----- src/hooks/useProviderScrape.tsx | 2 + src/pages/parts/player/ScrapingPart.tsx | 8 +- src/stores/__old/watched/migrations/v4.ts | 1 - 4 files changed, 87 insertions(+), 26 deletions(-) diff --git a/src/backend/helpers/report.ts b/src/backend/helpers/report.ts index c3448908..c2508b23 100644 --- a/src/backend/helpers/report.ts +++ b/src/backend/helpers/report.ts @@ -1,8 +1,10 @@ +import { ScrapeMedia } from "@movie-web/providers"; import { ofetch } from "ofetch"; import { useCallback } from "react"; -import { useBackendUrl } from "@/hooks/auth/useBackendUrl"; -import { ScrapingSegment } from "@/hooks/useProviderScrape"; +import { ScrapingItems, ScrapingSegment } from "@/hooks/useProviderScrape"; + +const metricsEndpoint = "https://backend.movie-web.app/metrics/providers"; export type ProviderMetric = { tmdbId: string; @@ -15,37 +17,93 @@ export type ProviderMetric = { embedId?: string; errorMessage?: string; fullError?: string; + hostname?: string; }; -export async function reportProviders( - url: string, - items: ProviderMetric[] -): Promise { - return ofetch("/metrics/providers", { +export async function reportProviders(items: ProviderMetric[]): Promise { + return ofetch(metricsEndpoint, { method: "POST", body: { - items, + items: items.map((v) => ({ + ...v, + hostname: window.location.hostname, + })), }, - baseURL: url, }); } -export function scrapSegmentToProviderMetric( - _segment: ScrapingSegment -): ProviderMetric { - // TODO actually convert this - return {} as any; +const segmentStatusMap: Record< + ScrapingSegment["status"], + ProviderMetric["status"] | null +> = { + success: "success", + notfound: "notfound", + failure: "failed", + pending: null, + waiting: null, +}; + +export function scrapeSegmentToProviderMetric( + media: ScrapeMedia, + providerId: string, + segment: ScrapingSegment +): ProviderMetric | null { + const status = segmentStatusMap[segment.status]; + if (!status) return null; + let episodeId: string | undefined; + let seasonId: string | undefined; + if (media.type === "show") { + episodeId = media.episode.tmdbId; + seasonId = media.season.tmdbId; + } + let error: undefined | Error; + if (segment.error instanceof Error) error = segment.error; + + return { + status, + providerId, + title: media.title, + tmdbId: media.tmdbId, + type: media.type, + embedId: segment.embedId, + episodeId, + seasonId, + errorMessage: segment.reason ?? error?.message, + fullError: error + ? `${error.toString()}\n\n${error.stack ?? ""}` + : undefined, + }; +} + +export function scrapePartsToProviderMetric( + media: ScrapeMedia, + order: ScrapingItems[], + sources: Record +): ProviderMetric[] { + const output: ProviderMetric[] = []; + + order.forEach((orderItem) => { + const source = sources[orderItem.id]; + orderItem.children.forEach((embedId) => { + const embed = sources[embedId]; + if (!embed.embedId) return; + const metric = scrapeSegmentToProviderMetric(media, source.id, embed); + if (!metric) return; + output.push(metric); + }); + + const metric = scrapeSegmentToProviderMetric(media, source.id, source); + if (!metric) return; + output.push(metric); + }); + + return output; } export function useReportProviders() { - const url = useBackendUrl(); - // TODO constant url - const report = useCallback( - (items: ProviderMetric[]) => { - reportProviders(url, items); - }, - [url] - ); + const report = useCallback((items: ProviderMetric[]) => { + reportProviders(items); + }, []); return { report }; } diff --git a/src/hooks/useProviderScrape.tsx b/src/hooks/useProviderScrape.tsx index 74ca596d..b7282175 100644 --- a/src/hooks/useProviderScrape.tsx +++ b/src/hooks/useProviderScrape.tsx @@ -11,6 +11,7 @@ export interface ScrapingItems { export interface ScrapingSegment { name: string; id: string; + embedId?: string; status: "failure" | "pending" | "notfound" | "success" | "waiting"; reason?: string; error?: unknown; @@ -73,6 +74,7 @@ export function useScrape() { const source = providers.getMetadata(v.embedScraperId); if (!source) throw new Error("invalid source id"); const out: ScrapingSegment = { + embedId: v.embedScraperId, name: source.name, id: v.id, status: "waiting", diff --git a/src/pages/parts/player/ScrapingPart.tsx b/src/pages/parts/player/ScrapingPart.tsx index 60a86585..06f69a15 100644 --- a/src/pages/parts/player/ScrapingPart.tsx +++ b/src/pages/parts/player/ScrapingPart.tsx @@ -4,7 +4,7 @@ import { useEffect, useRef } from "react"; import type { AsyncReturnType } from "type-fest"; import { - scrapSegmentToProviderMetric, + scrapePartsToProviderMetric, useReportProviders, } from "@/backend/helpers/report"; import { usePlayer } from "@/components/player/hooks/usePlayer"; @@ -64,8 +64,10 @@ export function ScrapingPart(props: ScrapingProps) { resultRef.current.sourceOrder ); report( - Object.values(resultRef.current.sources).map((v) => - scrapSegmentToProviderMetric(v) + scrapePartsToProviderMetric( + props.media, + resultRef.current.sourceOrder, + resultRef.current.sources ) ); props.onGetStream?.(output); diff --git a/src/stores/__old/watched/migrations/v4.ts b/src/stores/__old/watched/migrations/v4.ts index 70e5c3af..1b6dc4db 100644 --- a/src/stores/__old/watched/migrations/v4.ts +++ b/src/stores/__old/watched/migrations/v4.ts @@ -73,6 +73,5 @@ export function migrateV4Videos(old: WatchedStoreData) { } } - console.log(newItems); return newItems; }