diff --git a/.gitignore b/.gitignore index b95dc49..df163ad 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,5 @@ dist/ # lefthook lefthook-local.yml + +src/data/*.json diff --git a/generate_10sen.ts b/generate_10sen.ts new file mode 100644 index 0000000..3b0334c --- /dev/null +++ b/generate_10sen.ts @@ -0,0 +1,74 @@ +import { writeFile } from "node:fs/promises"; +import ky from "ky"; +import * as v from "valibot"; + +const SOURCE_URL = "https://otodb.github.io/10sen-extract/data.json"; +const OUTPUT_PATH = new URL("./src/data/10sen.json", import.meta.url); + +const data10sen: Record< + string, + { count: number; url: string | null; title: string; type: string }[] +> = await ky.get(SOURCE_URL).json(); + +const resolved: { + year: string; + count: number; + title: string; + url: string | null; + thumbnail: string | null; +}[] = []; + +for (const [y, d] of Object.entries(data10sen)) { + console.log(`resolving: ${y} (${d.length} items)`); + for (const { count, title, url } of d) { + if (!url) { + resolved.push({ year: y, count, title, url, thumbnail: null }); + continue; + } + + const roxyUrl = new URL("https://roxy.otodb.net/json"); + roxyUrl.searchParams.set("q", url); + + try { + const roxyData = v.safeParse( + v.object({ + status: v.literal("ok"), + payload: v.object({ + title: v.string(), + url: v.string(), + thumbnail: v.string(), + }), + }), + await ky + .get(roxyUrl, { + retry: { limit: 3, methods: ["get"] }, + timeout: 20000, + throwHttpErrors: false, + }) + .json(), + ); + + if (!roxyData.success) { + resolved.push({ year: y, count, title, url, thumbnail: null }); + continue; + } + + resolved.push({ + year: y, + count, + url, + title: roxyData.output.payload.title, + thumbnail: roxyData.output.payload.thumbnail, + }); + console.log(`resolved: ${url}`); + } catch (e) { + console.error(e); + resolved.push({ year: y, count, title, url, thumbnail: null }); + } + } +} + +await writeFile( + OUTPUT_PATH, + JSON.stringify(Object.groupBy(resolved, (r) => r.year)), +); diff --git a/package.json b/package.json index be45f55..640c2d5 100644 --- a/package.json +++ b/package.json @@ -1,32 +1,34 @@ { - "name": "hofs", - "type": "module", - "private": true, - "scripts": { - "dev": "astro dev", - "start": "astro dev", - "build": "astro build", - "preview": "wrangler pages dev ./dist", - "typecheck": "tsc --noEmit", - "check": "biome check .", - "fmt": "biome check --write ." - }, - "packageManager": "npm@10.9.2", - "dependencies": { - "@astrojs/svelte": "^7.0.0", - "@astrojs/tailwind": "^5.1.0", - "@fontsource-variable/jetbrains-mono": "^5.1.2", - "@fontsource/zen-antique-soft": "^5.1.1", - "@tailwindcss/container-queries": "^0.1.1", - "astro": "^5.0.0", - "ky": "^1.7.4", - "svelte": "^5.0.0", - "tailwindcss": "^3.4.1", - "valibot": "^1.0.0-beta.9" - }, - "devDependencies": { - "@biomejs/biome": "1.9.4", - "typescript": "^5.0.0", - "wrangler": "^3.0.0" - } + "name": "hofs", + "type": "module", + "private": true, + "scripts": { + "dev": "astro dev", + "start": "astro dev", + "build": "astro build", + "prebuild": "npm run generate:10sen", + "generate:10sen": "node --experimental-strip-types generate_10sen.ts", + "preview": "wrangler pages dev ./dist", + "typecheck": "tsc --noEmit", + "check": "biome check .", + "fmt": "biome check --write ." + }, + "packageManager": "npm@10.9.2", + "dependencies": { + "@astrojs/svelte": "^7.0.0", + "@astrojs/tailwind": "^5.1.0", + "@fontsource-variable/jetbrains-mono": "^5.1.2", + "@fontsource/zen-antique-soft": "^5.1.1", + "@tailwindcss/container-queries": "^0.1.1", + "astro": "^5.0.0", + "ky": "^1.7.4", + "svelte": "^5.0.0", + "tailwindcss": "^3.4.1", + "valibot": "^1.0.0-beta.9" + }, + "devDependencies": { + "@biomejs/biome": "1.9.4", + "typescript": "^5.0.0", + "wrangler": "^3.0.0" + } } diff --git a/src/components/Card.astro b/src/components/Card.astro index 1af1f3c..244d394 100644 --- a/src/components/Card.astro +++ b/src/components/Card.astro @@ -1,15 +1,14 @@ --- -import getThumbnail from "./getThumbnail"; +import pseudoThumbnail from "../images/pseudo_thumbnail.jpg"; import { Image } from "astro:assets"; interface Props { title: string; url: string | null; - type: string; + thumbnail?: string | null; } -const { title, url } = Astro.props; +const { title, url, thumbnail } = Astro.props; -const thumbnail = await getThumbnail(url); const furl = url ? new URL(url) : "#"; --- @@ -20,7 +19,7 @@ const furl = url ? new URL(url) : "#";
デバイス規制などの技術的な問題で、視聴可能な動画のサムネイルが取得出来ていないケースがありますので、あくまで参考程度にしてください。