From 841b28a408df43b5380fa00388075a07129f7146 Mon Sep 17 00:00:00 2001 From: Fuwn Date: Sun, 3 Dec 2023 15:43:05 -0800 Subject: feat(birthdays): add second birthday source --- bun.lockb | Bin 109085 -> 122930 bytes package.json | 1 + src/lib/ACDB.ts | 4 +- src/lib/Birthday/aniSearch.ts | 10 +++ src/lib/Tools/CharacterBirthdays.svelte | 86 +++++++++++++++++++------- src/routes/api/birthdays/anisearch/+server.ts | 34 ++++++++++ 6 files changed, 109 insertions(+), 26 deletions(-) create mode 100644 src/lib/Birthday/aniSearch.ts create mode 100644 src/routes/api/birthdays/anisearch/+server.ts diff --git a/bun.lockb b/bun.lockb index 591339b3..c67f2b8a 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/package.json b/package.json index e4477c82..ef257893 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,7 @@ "dependencies": { "dexie": "^4.0.1-alpha.25", "html2canvas": "^1.4.1", + "jsdom": "^23.0.1", "modern-screenshot": "^4.4.33", "rss-parser": "^3.13.0", "socket.io": "^4.7.2", diff --git a/src/lib/ACDB.ts b/src/lib/ACDB.ts index 29537fb8..97e40f58 100644 --- a/src/lib/ACDB.ts +++ b/src/lib/ACDB.ts @@ -1,10 +1,10 @@ -export interface ACDBBirthdaysEntry { +export interface ACDBBirthday { character_image: string; name: string; origin: string; } -export const ACDBBirthdays = async (month: number, day: number): Promise => +export const ACDBBirthdays = async (month: number, day: number): Promise => ( await ( await fetch(`/api/acdb-birthdays?month=${month}&day=${day}`, { diff --git a/src/lib/Birthday/aniSearch.ts b/src/lib/Birthday/aniSearch.ts new file mode 100644 index 00000000..a938f7ba --- /dev/null +++ b/src/lib/Birthday/aniSearch.ts @@ -0,0 +1,10 @@ +export interface aniSearchBirthday { + name: string; + image: string; +} + +export const aniSearchBirthdays = async ( + month: number, + day: number +): Promise => + await (await fetch(`/api/birthdays/anisearch?month=${month}&day=${day}`, {})).json(); diff --git a/src/lib/Tools/CharacterBirthdays.svelte b/src/lib/Tools/CharacterBirthdays.svelte index d1d03ed0..c012d65e 100644 --- a/src/lib/Tools/CharacterBirthdays.svelte +++ b/src/lib/Tools/CharacterBirthdays.svelte @@ -1,33 +1,71 @@ - -{#await ACDBBirthdays(date.getMonth() + 1, date.getDate())} -

Loading ...

-{:then birthdays} -

- This tool does not use AniList's API, so it will have more characters than AniList, but also - some unexpected characters which may not be present in AniList. -

+{#await ACDBBirthdays(month, day)} +

Loading set one ...

+{:then acdbBirthdays} + {#await anisearchBirthdays} +

Loading set two ...

+ {:then anisearch} + {@const birthdays = combineBirthdaySources(acdbBirthdays, anisearch)} -
- {#each birthdays as birthday} - - {/each} -
+
+ {#each birthdays as birthday} + + {/each} +
+ {:catch} + + {/await} {:catch} {/await} diff --git a/src/routes/api/birthdays/anisearch/+server.ts b/src/routes/api/birthdays/anisearch/+server.ts new file mode 100644 index 00000000..7cafb5ea --- /dev/null +++ b/src/routes/api/birthdays/anisearch/+server.ts @@ -0,0 +1,34 @@ +import { JSDOM } from 'jsdom'; + +export const GET = async ({ url }: { url: URL }) => { + const document = new JSDOM( + await ( + await fetch( + `https://www.anisearch.com/character/birthdays?month=${url.searchParams.get('month')}` + ) + ).text() + ).window.document; + const section = document.querySelector(`#day-${url.searchParams.get('day')}`); + + if (!section) return Response.json([]); + + const ul = section.querySelector('ul.covers.simple'); + + if (!ul) return Response.json([]); + + return Response.json( + Array.from(ul.querySelectorAll('li')).map((li) => { + const anchor = li.querySelector('a'); + const title = li.querySelector('.title'); + + if (!anchor || !title) return { image: '', title: '' }; + + return { + image: anchor.getAttribute('data-bg') + ? `https://cdn.anisearch.com/images/${anchor.getAttribute('data-bg')}` + : null, + name: title.textContent.trim() + }; + }) + ); +}; -- cgit v1.2.3