diff --git a/deno.json b/deno.json index 562aab51..52d57926 100644 --- a/deno.json +++ b/deno.json @@ -21,6 +21,7 @@ "soapbox": "curl -O https://dl.soapbox.pub/main/soapbox.zip && mkdir -p public && mv soapbox.zip public/ && cd public/ && unzip -o soapbox.zip && rm soapbox.zip", "trends": "deno run -A --env-file --deny-read=.env scripts/trends.ts", "clean:deps": "deno cache --reload src/app.ts", + "db:populate:nip05": "deno run -A --env-file --deny-read=.env scripts/db-populate-nip05.ts", "db:populate-search": "deno run -A --env-file --deny-read=.env scripts/db-populate-search.ts", "db:populate-extensions": "deno run -A --env-file --deny-read=.env scripts/db-populate-extensions.ts", "db:streak:recompute": "deno run -A --env-file --deny-read=.env scripts/db-streak-recompute.ts", diff --git a/scripts/db-populate-nip05.ts b/scripts/db-populate-nip05.ts new file mode 100644 index 00000000..b2b05651 --- /dev/null +++ b/scripts/db-populate-nip05.ts @@ -0,0 +1,45 @@ +import { NSchema as n } from '@nostrify/nostrify'; + +import { Storages } from '@/storages.ts'; +import { faviconCache } from '@/utils/favicon.ts'; +import { nip05Cache } from '@/utils/nip05.ts'; + +const store = await Storages.db(); +const kysely = await Storages.kysely(); +const statsQuery = kysely.selectFrom('author_stats').select('pubkey'); + +for await (const { pubkey } of statsQuery.stream(10)) { + const signal = AbortSignal.timeout(30_000); // generous timeout + + try { + const [author] = await store.query([{ kinds: [0], authors: [pubkey], limit: 1 }]); + + if (!author) { + continue; + } + + // Parse metadata. + const metadata = n.json().pipe(n.metadata()).catch({}).safeParse(author.content); + if (!metadata.success) continue; + + // Update nip05. + const { nip05 } = metadata.data; + if (nip05) { + try { + await nip05Cache.fetch(nip05, { signal }); + } catch { + // Ignore. + } + } + + // Update favicon. + const domain = nip05?.split('@')[1].toLowerCase(); + if (domain) { + await faviconCache.fetch(domain, { signal }); + } + } catch { + continue; + } +} + +Deno.exit(); diff --git a/src/utils/favicon.ts b/src/utils/favicon.ts index 2ee7c7f7..549ae8df 100644 --- a/src/utils/favicon.ts +++ b/src/utils/favicon.ts @@ -23,7 +23,7 @@ export const faviconCache = new SimpleLRU( const url = await fetchFavicon(domain, signal); - insertFavicon(kysely, domain, url.href).catch(() => {}); + await insertFavicon(kysely, domain, url.href); return url; }, diff --git a/src/utils/nip05.ts b/src/utils/nip05.ts index d180d610..6bed4c6d 100644 --- a/src/utils/nip05.ts +++ b/src/utils/nip05.ts @@ -110,7 +110,12 @@ async function insertNip05(kysely: Kysely, nip05: string, pubkey: s nip05_hostname: tld.hostname, nip05_last_verified_at: ts, }) - .where('nip05_last_verified_at', '<', ts) + .where((eb) => + eb.or([ + eb('author_stats.nip05_last_verified_at', '<', ts), + eb('author_stats.nip05_last_verified_at', 'is', null), + ]) + ) ) .execute(); }