aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/utils/videoLabels.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/utils/videoLabels.ts')
-rw-r--r--src/utils/videoLabels.ts65
1 files changed, 65 insertions, 0 deletions
diff --git a/src/utils/videoLabels.ts b/src/utils/videoLabels.ts
new file mode 100644
index 00000000..ca12c6e4
--- /dev/null
+++ b/src/utils/videoLabels.ts
@@ -0,0 +1,65 @@
+import { Category, VideoID } from "../types";
+import { getHash } from "@ajayyy/maze-utils/lib/hash";
+import Utils from "../utils";
+import { logWarn } from "./logger";
+
+const utils = new Utils();
+
+export interface LabelCacheEntry {
+ timestamp: number;
+ videos: Record<VideoID, Category>;
+}
+
+const labelCache: Record<string, LabelCacheEntry> = {};
+const cacheLimit = 1000;
+
+async function getLabelHashBlock(hashPrefix: string): Promise<LabelCacheEntry | null> {
+ // Check cache
+ const cachedEntry = labelCache[hashPrefix];
+ if (cachedEntry) {
+ return cachedEntry;
+ }
+
+ const response = await utils.asyncRequestToServer("GET", `/api/videoLabels/${hashPrefix}`);
+ if (response.status !== 200) {
+ // No video labels or server down
+ labelCache[hashPrefix] = {
+ timestamp: Date.now(),
+ videos: {},
+ };
+ return null;
+ }
+
+ try {
+ const data = JSON.parse(response.responseText);
+
+ const newEntry: LabelCacheEntry = {
+ timestamp: Date.now(),
+ videos: Object.fromEntries(data.map(video => [video.videoID, video.segments[0].category])),
+ };
+ labelCache[hashPrefix] = newEntry;
+
+ if (Object.keys(labelCache).length > cacheLimit) {
+ // Remove oldest entry
+ const oldestEntry = Object.entries(labelCache).reduce((a, b) => a[1].timestamp < b[1].timestamp ? a : b);
+ delete labelCache[oldestEntry[0]];
+ }
+
+ return newEntry;
+ } catch (e) {
+ logWarn(`Error parsing video labels: ${e}`);
+
+ return null;
+ }
+}
+
+export async function getVideoLabel(videoID: VideoID): Promise<Category | null> {
+ const prefix = (await getHash(videoID, 1)).slice(0, 3);
+ const result = await getLabelHashBlock(prefix);
+
+ if (result) {
+ return result.videos[videoID] ?? null;
+ }
+
+ return null;
+} \ No newline at end of file