A tool for tailing the firehose and matching images against known perceptual hashes, and then labeling them.
1import type Redis from "ioredis";
2import { logger } from "../logger/index";
3
4export class PhashCache {
5 private redis: Redis;
6 private ttl: number;
7 private readonly PHASH_PREFIX = "phash:cache:";
8
9 constructor(redis: Redis, ttlSeconds: number) {
10 this.redis = redis;
11 this.ttl = ttlSeconds;
12 }
13
14 async get(cid: string): Promise<string | null> {
15 const key = this.PHASH_PREFIX + cid;
16 const cached = await this.redis.get(key);
17
18 if (cached) {
19 logger.debug({ cid }, "Phash cache hit");
20 }
21
22 return cached;
23 }
24
25 async set(cid: string, phash: string): Promise<void> {
26 const key = this.PHASH_PREFIX + cid;
27 await this.redis.set(key, phash, "EX", this.ttl);
28 logger.debug({ cid, phash }, "Phash cached");
29 }
30
31 async delete(cid: string): Promise<void> {
32 const key = this.PHASH_PREFIX + cid;
33 await this.redis.del(key);
34 }
35
36 async clear(): Promise<void> {
37 const pattern = `${this.PHASH_PREFIX}*`;
38 const keys = await this.redis.keys(pattern);
39
40 if (keys.length > 0) {
41 await this.redis.del(...keys);
42 logger.info({ count: keys.length }, "Cleared phash cache");
43 }
44 }
45
46 async getStats(): Promise<{ size: number }> {
47 const pattern = `${this.PHASH_PREFIX}*`;
48 const keys = await this.redis.keys(pattern);
49 return { size: keys.length };
50 }
51}