aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lib/ACDB.ts4
-rw-r--r--src/lib/Birthday/aniSearch.ts10
-rw-r--r--src/lib/Tools/CharacterBirthdays.svelte86
-rw-r--r--src/routes/api/birthdays/anisearch/+server.ts34
4 files changed, 108 insertions, 26 deletions
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<ACDBBirthdaysEntry[]> =>
+export const ACDBBirthdays = async (month: number, day: number): Promise<ACDBBirthday[]> =>
(
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<aniSearchBirthday[]> =>
+ 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 @@
-<script>
- import { ACDBBirthdays } from '$lib/ACDB';
+<script lang="ts">
+ import { ACDBBirthdays, type ACDBBirthday } from '$lib/ACDB';
+ import { aniSearchBirthdays, type aniSearchBirthday } from '$lib/Birthday/aniSearch';
import Error from '$lib/Error.svelte';
+ import { onMount } from 'svelte';
+
+ interface Birthday {
+ name: string;
+ image: string;
+ origin?: string;
+ }
let date = new Date();
+ let month = date.getMonth() + 1;
+ let day = date.getDate();
+ let anisearchBirthdays: Promise<aniSearchBirthday[]>;
+
+ onMount(async () => {
+ anisearchBirthdays = aniSearchBirthdays(month, day);
+ });
+
+ const combineBirthdaySources = (
+ acdbArray: ACDBBirthday[],
+ aniSearchArray: aniSearchBirthday[]
+ ): Birthday[] =>
+ Array.from(
+ new Map(
+ [
+ ...aniSearchArray.map((entry) => ({
+ name: entry.name,
+ image: entry.image
+ })),
+ ...acdbArray.map((entry) => ({
+ name: entry.name,
+ image: entry.character_image,
+ origin: entry.origin
+ }))
+ ].map((entry) => [entry.name, entry])
+ ).values()
+ );
</script>
-{#await ACDBBirthdays(date.getMonth() + 1, date.getDate())}
- <p>Loading ...</p>
-{:then birthdays}
- <p>
- 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.
- </p>
+{#await ACDBBirthdays(month, day)}
+ <p>Loading set one ...</p>
+{:then acdbBirthdays}
+ {#await anisearchBirthdays}
+ <p>Loading set two ...</p>
+ {:then anisearch}
+ {@const birthdays = combineBirthdaySources(acdbBirthdays, anisearch)}
- <div id="characters">
- {#each birthdays as birthday}
- <div>
- <a
- href={`https://anilist.co/search/characters?search=${encodeURIComponent(
- birthday.name
- ).replace(/%20/g, '+')}`}
- target="_blank"
- >
- {birthday.name}
- <img src={birthday.character_image} alt="Character (Large)" class="character-image" />
- </a>
- </div>
- {/each}
- </div>
+ <div id="characters">
+ {#each birthdays as birthday}
+ <div>
+ <a
+ href={`https://anilist.co/search/characters?search=${encodeURIComponent(
+ birthday.name
+ ).replace(/%20/g, '+')}`}
+ target="_blank"
+ >
+ {birthday.name}
+ <img src={birthday.image} alt="Character (Large)" class="character-image" />
+ </a>
+ </div>
+ {/each}
+ </div>
+ {:catch}
+ <Error type="Character" />
+ {/await}
{:catch}
<Error type="Character" />
{/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()
+ };
+ })
+ );
+};