diff options
| author | Fuwn <[email protected]> | 2023-10-22 14:03:08 -0700 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2023-10-22 14:03:08 -0700 |
| commit | 0c6fbd9b1afe8e5967a127bffa68570ee88bfe92 (patch) | |
| tree | df5afd62f88a26e61bc92e3848d6d2c5a659dd7b | |
| parent | feat(tools): default selection query (diff) | |
| download | due.moe-0c6fbd9b1afe8e5967a127bffa68570ee88bfe92.tar.xz due.moe-0c6fbd9b1afe8e5967a127bffa68570ee88bfe92.zip | |
feat(tools): episode discussion collector
| -rw-r--r-- | src/lib/AniList/forum.ts | 58 | ||||
| -rw-r--r-- | src/lib/Tools/EpisodeDiscussionCollector.svelte | 44 | ||||
| -rw-r--r-- | src/routes/tools/+page.svelte | 4 |
3 files changed, 106 insertions, 0 deletions
diff --git a/src/lib/AniList/forum.ts b/src/lib/AniList/forum.ts new file mode 100644 index 00000000..6b95fa07 --- /dev/null +++ b/src/lib/AniList/forum.ts @@ -0,0 +1,58 @@ +import { user } from './user'; + +export interface Thread { + id: number; + title: string; + createdAt: number; +} + +export interface ThreadPage { + data: { + Page: { + threads: Thread[]; + pageInfo: { + hasNextPage: boolean; + currentPage: number; + }; + }; + }; +} + +const threadPage = async (page: number, userId: number): Promise<ThreadPage> => + await ( + await fetch('https://graphql.anilist.co', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Accept: 'application/json' + }, + body: JSON.stringify({ + query: `{ Page(perPage: 50, page: ${page}) { + threads(userId: ${userId}) { id title createdAt } + pageInfo { hasNextPage } +} }` + }) + }) + ).json(); + +export const threads = async (username: string): Promise<Thread[]> => { + const allThreads = []; + const userId = (await user(username)).id; + let page = 1; + let currentPage = await threadPage(page, userId); + + for (const thread of currentPage.data.Page.threads) { + allThreads.push(thread); + } + + while (currentPage.data.Page.pageInfo.hasNextPage) { + page += 1; + currentPage = await threadPage(page, userId); + + for (const thread of currentPage.data.Page.threads) { + allThreads.push(thread); + } + } + + return allThreads; +}; diff --git a/src/lib/Tools/EpisodeDiscussionCollector.svelte b/src/lib/Tools/EpisodeDiscussionCollector.svelte new file mode 100644 index 00000000..a9acd8ae --- /dev/null +++ b/src/lib/Tools/EpisodeDiscussionCollector.svelte @@ -0,0 +1,44 @@ +<script lang="ts"> + import { threads } from '$lib/AniList/forum'; + + let searchInput = ''; + let searchInputFinal = ''; +</script> + +<p> + <input type="text" placeholder="Username" bind:value={searchInput} /> + <a href={`#`} on:click={() => (searchInputFinal = searchInput)}>Search</a> +</p> + +{#if searchInputFinal !== ''} + {#await threads(searchInputFinal)} + Loading ... + {:then threads} + <ul> + {#each threads + .filter((thread) => thread.title.includes('[Spoilers]') && thread.title.includes('Episode')) + .sort((a, b) => b.createdAt - a.createdAt) as thread} + <li> + <a href={`https://anilist.co/forum/thread/${thread.id}`} target="_blank"> + {thread.title.replace('[Spoilers]', '')} + </a> + </li> + {/each} + </ul> + {:catch} + <p> + Threads could not be loaded. You might have been <a + href="https://en.wikipedia.org/wiki/Rate_limiting" + target="_blank">rate limited</a + >. + </p> + <p> + Try again in a few minutes. If the problem persists, please contact <a + href="https://anilist.co/user/fuwn" + target="_blank">@fuwn</a + > on AniList. + </p> + {/await} +{:else} + <p>Enter a username to search for to continue.</p> +{/if} diff --git a/src/routes/tools/+page.svelte b/src/routes/tools/+page.svelte index 8ddc0aac..5a12fb0f 100644 --- a/src/routes/tools/+page.svelte +++ b/src/routes/tools/+page.svelte @@ -3,6 +3,7 @@ import { todaysCharacterBirthdays } from '$lib/AniList/character'; import Wrapped from '$lib/Tools/Wrapped.svelte'; import { browser } from '$app/environment'; + import EpisodeDiscussionCollector from '$lib/Tools/EpisodeDiscussionCollector.svelte'; export let data; @@ -16,6 +17,7 @@ <option value="todays_character_birthdays">Today's Character Birthdays</option> <option value="activity_history_hole_risks">Activity History Hole Risks</option> <option value="wrapped">Wrapped (Beta)</option> + <option value="episode_discussion_collector">Episode Discussion Collector (Beta)</option> </select> </p> @@ -25,6 +27,8 @@ <ActivityHistory user={data.user} /> {:else if tool === 'wrapped'} <div id="wrapped"><Wrapped user={data.user} /></div> +{:else if tool === 'episode_discussion_collector'} + <EpisodeDiscussionCollector /> {:else if tool === 'todays_character_birthdays'} <ul> {#await todaysCharacterBirthdays()} |