Add worker.js
This commit is contained in:
commit
99f66230cd
1 changed files with 162 additions and 0 deletions
162
worker.js
Normal file
162
worker.js
Normal file
|
|
@ -0,0 +1,162 @@
|
|||
const languages = new Set(["en", "fr", "es", "it", "pl", "tr", "ja", "zh", "sv"]);
|
||||
const contentTypes = new Set(["sfw", "nsfw"]);
|
||||
const urlBase = "https://api.comick.fun/chapter/";
|
||||
const genreBase = "https://api.comick.io/genre/";
|
||||
const cache = new Map();
|
||||
const genreCache = new Map();
|
||||
|
||||
export default {
|
||||
async fetch(request) {
|
||||
const url = new URL(request.url);
|
||||
const path = url.pathname;
|
||||
|
||||
if (path === "/info") {
|
||||
return getInfoResponse();
|
||||
}
|
||||
|
||||
try {
|
||||
const language = findLanguage(url);
|
||||
const contentType = findContentType(url);
|
||||
const cacheKey = `${language}-${contentType}`;
|
||||
|
||||
let data;
|
||||
if (cache.has(cacheKey)) {
|
||||
data = cache.get(cacheKey);
|
||||
} else {
|
||||
const apiUrl = `${urlBase}?lang=${language}&page=1&order=new&accept_erotic_content=${contentType === 'nsfw'}`;
|
||||
data = await fetchData(apiUrl);
|
||||
cache.set(cacheKey, data); // Cache the response
|
||||
}
|
||||
|
||||
// Fetch genres if not already cached
|
||||
if (!genreCache.size) {
|
||||
const genres = await fetchData(genreBase);
|
||||
const genreMap = genres.reduce((acc, genre) => {
|
||||
acc[genre.id] = genre.name;
|
||||
return acc;
|
||||
}, {});
|
||||
genreCache.set('allGenres', genreMap);
|
||||
}
|
||||
|
||||
const rssData = generateRSS(data, language, contentType, url);
|
||||
return new Response(rssData, {
|
||||
headers: {
|
||||
"Content-Type": "application/rss+xml",
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Error processing request:", error);
|
||||
return new Response("Internal Server Error", {
|
||||
status: 500,
|
||||
headers: {
|
||||
"Content-Type": "text/plain",
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
function getInfoResponse() {
|
||||
return new Response(`
|
||||
<html>
|
||||
<head>
|
||||
<title>Worker Info</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Welcome to Manga-RSS!</h1>
|
||||
<p>Unfortunately, the GitHub repo was taken down and the python script stopped working, but after rewriting the project in JavaScript, I was able to bring it back. To use this new version with even more supported languages, you just append /[language] to the base url and either /sfw or /nsfw for the content rating.</p>
|
||||
</body>
|
||||
</html>`, {
|
||||
headers: {
|
||||
"Content-Type": "text/html",
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async function fetchData(apiUrl) {
|
||||
const init = {
|
||||
headers: {
|
||||
"content-type": "application/json;charset=UTF-8",
|
||||
"User-Agent": "Mozilla/5.0",
|
||||
},
|
||||
};
|
||||
|
||||
try {
|
||||
const responseFromApi = await fetch(apiUrl, init);
|
||||
if (!responseFromApi.ok) {
|
||||
throw new Error(`Failed to fetch data from API (${responseFromApi.status} ${responseFromApi.statusText})`);
|
||||
}
|
||||
|
||||
const contentType = (responseFromApi.headers.get("content-type") || "").toLowerCase();
|
||||
return contentType.includes("application/json") ? responseFromApi.json() : responseFromApi.text();
|
||||
} catch (error) {
|
||||
console.error("Error fetching data:", error);
|
||||
throw new Error("Failed to fetch data from the API");
|
||||
}
|
||||
}
|
||||
|
||||
function findLanguage(url) {
|
||||
for (const lang of languages) {
|
||||
if (url.pathname.includes(`/${lang}`)) {
|
||||
return lang;
|
||||
}
|
||||
}
|
||||
return "en";
|
||||
}
|
||||
|
||||
function findContentType(url) {
|
||||
for (const type of contentTypes) {
|
||||
if (url.pathname.includes(`/${type}`)) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
return "sfw";
|
||||
}
|
||||
|
||||
function encodeHTML(text) {
|
||||
return text.replace(/</g, '').replace(/>/g, '');
|
||||
}
|
||||
|
||||
function getGenreNames(genreIds) {
|
||||
const allGenres = genreCache.get('allGenres');
|
||||
return genreIds.map(id => `<li>${encodeHTML(allGenres[id] || 'Unknown Genre')}</li>`).join('');
|
||||
}
|
||||
|
||||
function generateRSS(data, language, contentType, url) {
|
||||
const rssHeader = `<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||
<channel>
|
||||
<title>ComicK - ${language} ${contentType.toUpperCase()} RSS Feed</title>
|
||||
<link>https://github.com/ld3z/manga-rss</link>
|
||||
<description>A simple RSS feed for ComicK!</description>
|
||||
<atom:link href="${url.origin + url.pathname}" rel="self" type="application/rss+xml"/>`;
|
||||
|
||||
const rssItems = data.map(comicData => {
|
||||
const comic = comicData.md_comics;
|
||||
|
||||
const title = `<![CDATA[${encodeHTML(`${comic.title} - Chapter ${comicData.chap}`)}]]>`;
|
||||
|
||||
// Embed the image in the description as an <img> tag
|
||||
const coverImageURL = comic.md_covers[0] ? `https://meo.comick.pictures/${comic.md_covers[0].b2key}` : '';
|
||||
const description = coverImageURL ? `<![CDATA[Chapter ${comicData.chap} of ${comic.title} is now available on ComicK!<br><strong>Genres:</strong><ul>${getGenreNames(comic.genres)}</ul><br><img src="${coverImageURL}" alt="Cover Image" width="200" height="300" />]]>` :
|
||||
`<![CDATA[Chapter ${comicData.chap} of ${comic.title} is now available on ComicK!<br><strong>Genres:</strong><ul>${getGenreNames(comic.genres)}</ul>]]>`;
|
||||
|
||||
// Extract and format the 'updated_at' field from the API response
|
||||
const pubDate = comicData.updated_at ? new Date(comicData.updated_at).toUTCString() : new Date().toUTCString();
|
||||
|
||||
return `
|
||||
<item>
|
||||
<guid>https://comick.io/comic/${comic.slug}</guid>
|
||||
<title>${title}</title>
|
||||
<link>https://comick.io/comic/${comic.slug}</link>
|
||||
<description>${description}</description>
|
||||
<pubDate>${pubDate}</pubDate>
|
||||
</item>`;
|
||||
}).join('');
|
||||
|
||||
const rssFooter = `
|
||||
</channel>
|
||||
</rss>`;
|
||||
|
||||
return `${rssHeader}${rssItems}${rssFooter}`;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue