diff --git a/src/components/SlugInput.astro b/src/components/SlugInput.astro index c5a953b..f680986 100644 --- a/src/components/SlugInput.astro +++ b/src/components/SlugInput.astro @@ -103,7 +103,25 @@ import { availableLanguages, languageMap } from '../lib/api'; function updateRSSLink() { const slugString = [...slugs].join(','); const lang = langSelect?.value || 'en'; - generateRSSLink!.setAttribute('href', `/rss/custom/${slugString}.xml?lang=${lang}`); + + // Call the API to get a short feed ID + fetch('/api/create-feed', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + slugs: [...slugs], + lang + }) + }) + .then(response => response.json()) + .then(data => { + generateRSSLink!.setAttribute('href', `/rss/${data.feedId}.xml`); + }) + .catch(error => { + console.error('Error generating short URL:', error); + }); } function renderSlugList() { diff --git a/src/lib/api.ts b/src/lib/api.ts index fed06a3..5db454c 100644 --- a/src/lib/api.ts +++ b/src/lib/api.ts @@ -117,6 +117,9 @@ interface ChapterDetail { md_comics: { title: string; slug: string; + md_covers?: { + b2key: string; + }[]; }; } @@ -154,11 +157,13 @@ export async function getChaptersByHid( ordering: '-created_at' }); + // Fetch comic details including cover const comicResponse = await fetchWithRetry( `https://api.comick.fun/comic/${hid}` ); const comicData = await comicResponse.json(); const comicTitle = comicData?.comic?.title || 'Unknown Comic'; + const covers = comicData?.comic?.md_covers || []; const response = await fetchWithRetry( `https://api.comick.fun/comic/${hid}/chapters?${queryParams}` @@ -187,7 +192,8 @@ export async function getChaptersByHid( updated_at: chapter.publish_at || chapter.created_at || chapter.updated_at, md_comics: { title: comicTitle, - slug: slug + slug: slug, + md_covers: covers // Add covers to the response } })); diff --git a/src/pages/api/create-feed.ts b/src/pages/api/create-feed.ts new file mode 100644 index 0000000..92a8f3c --- /dev/null +++ b/src/pages/api/create-feed.ts @@ -0,0 +1,34 @@ +import type { APIRoute } from "astro"; +import { createHash } from 'crypto'; + +// In-memory storage (replace with database in production) +const feedMappings = new Map(); + +export const POST: APIRoute = async ({ request }) => { + try { + const { slugs, lang } = await request.json(); + + if (!Array.isArray(slugs) || slugs.length === 0) { + return new Response("Invalid slugs array", { status: 400 }); + } + + // Create a unique hash based on slugs and language + const dataString = `${slugs.sort().join(',')}:${lang}`; + const hash = createHash('md5').update(dataString).digest('hex').slice(0, 8); + + // Store the mapping + feedMappings.set(hash, { slugs, lang }); + + return new Response(JSON.stringify({ feedId: hash }), { + status: 200, + headers: { + 'Content-Type': 'application/json' + } + }); + } catch (error) { + return new Response("Invalid request", { status: 400 }); + } +}; + +// Export the mappings for use in other files +export { feedMappings }; \ No newline at end of file diff --git a/src/pages/rss/[feedId].xml.ts b/src/pages/rss/[feedId].xml.ts new file mode 100644 index 0000000..6cbef08 --- /dev/null +++ b/src/pages/rss/[feedId].xml.ts @@ -0,0 +1,46 @@ +import rss from "@astrojs/rss"; +import { getChaptersForSlugs, isValidLanguage } from "../../lib/api"; +import type { APIRoute } from "astro"; +import { feedMappings } from "../api/create-feed"; + +export const GET: APIRoute = async ({ params }) => { + const feedId = params.feedId?.replace('.xml', ''); + + if (!feedId || !feedMappings.has(feedId)) { + return new Response("Feed not found", { status: 404 }); + } + + const { slugs, lang } = feedMappings.get(feedId)!; + + if (!isValidLanguage(lang)) { + return new Response("Invalid language", { status: 400 }); + } + + const chapters = await getChaptersForSlugs(slugs, lang); + + if (chapters.length === 0) { + return new Response("No chapters found for the provided comics", { status: 404 }); + } + + return rss({ + title: `ComicK - Custom Feed (${lang.toUpperCase()})`, + description: `Custom RSS feed for selected comics: ${slugs.join(', ')}`, + site: "https://github.com/ld3z/manga-rss", + items: chapters.map((chapter) => ({ + title: `${chapter.md_comics.title} - Chapter ${chapter.chap}`, + link: `https://comick.io/comic/${chapter.md_comics.slug}`, + pubDate: new Date(chapter.updated_at), + description: ` +
+ ${ + chapter.md_comics.md_covers?.[0] + ? `Cover` + : "" + } +

New chapter available: Chapter ${chapter.chap}

+
+ `, + })), + }); +}; \ No newline at end of file