mangadex update fixes

This commit is contained in:
Daniel Bulant 2022-01-10 16:20:31 +01:00
parent a5c1c24e99
commit e2df1b923d
14 changed files with 182 additions and 88 deletions

View file

@ -14,5 +14,5 @@ module.exports = {
"svx", "svx",
"md" "md"
], ],
"started": "2021-05-20T14:57:51.302Z" "started": "2022-01-10T14:33:28.708Z"
} }

View file

@ -1,11 +1,11 @@
/** /**
* @roxi/routify 2.18.1 * @roxi/routify 2.18.4
* File generated Thu May 20 2021 18:09:03 GMT+0200 (GMT+02:00) * File generated Mon Jan 10 2022 15:33:28 GMT+0100 (Central European Standard Time)
*/ */
export const __version = "2.18.1" export const __version = "2.18.4"
export const __timestamp = "2021-05-20T16:09:03.946Z" export const __timestamp = "2022-01-10T14:33:28.723Z"
//buildRoutes //buildRoutes
import { buildClientTree } from "@roxi/routify/runtime/buildRoutes" import { buildClientTree } from "@roxi/routify/runtime/buildRoutes"
@ -24,7 +24,7 @@ export const _tree = {
"ownMeta": { "ownMeta": {
"preload": "proximity" "preload": "proximity"
}, },
"absolutePath": "/home/dan/Documents/node_projects/mangades/src/pages/_layout.svelte", "absolutePath": "/home/dan/projects/node/Mangades/src/pages/_layout.svelte",
"children": [ "children": [
{ {
"isFile": true, "isFile": true,
@ -34,7 +34,7 @@ export const _tree = {
"name": "_fallback", "name": "_fallback",
"ext": "svelte", "ext": "svelte",
"badExt": false, "badExt": false,
"absolutePath": "/home/dan/Documents/node_projects/mangades/src/pages/_fallback.svelte", "absolutePath": "/home/dan/projects/node/Mangades/src/pages/_fallback.svelte",
"importPath": "../src/pages/_fallback.svelte", "importPath": "../src/pages/_fallback.svelte",
"isLayout": false, "isLayout": false,
"isReset": false, "isReset": false,
@ -59,8 +59,85 @@ export const _tree = {
"name": "_layout", "name": "_layout",
"ext": "svelte", "ext": "svelte",
"badExt": false, "badExt": false,
"absolutePath": "/home/dan/Documents/node_projects/mangades/src/pages/[manga]/_layout.svelte", "absolutePath": "/home/dan/projects/node/Mangades/src/pages/[manga]/_layout.svelte",
"children": [ "children": [
{
"isFile": true,
"isDir": true,
"file": "_layout.svelte",
"filepath": "/[manga]/[chapter]/_layout.svelte",
"name": "_layout",
"ext": "svelte",
"badExt": false,
"absolutePath": "/home/dan/projects/node/Mangades/src/pages/[manga]/[chapter]/_layout.svelte",
"children": [
{
"isFile": true,
"isDir": false,
"file": "[page].svelte",
"filepath": "/[manga]/[chapter]/[page].svelte",
"name": "[page]",
"ext": "svelte",
"badExt": false,
"absolutePath": "/home/dan/projects/node/Mangades/src/pages/[manga]/[chapter]/[page].svelte",
"importPath": "../src/pages/[manga]/[chapter]/[page].svelte",
"isLayout": false,
"isReset": false,
"isIndex": false,
"isFallback": false,
"isPage": true,
"ownMeta": {},
"meta": {
"recursive": true,
"preload": "proximity",
"prerender": true
},
"path": "/:manga/:chapter/:page",
"id": "__manga__chapter__page",
"component": () => import('../src/pages/[manga]/[chapter]/[page].svelte').then(m => m.default)
},
{
"isFile": true,
"isDir": false,
"file": "index.svelte",
"filepath": "/[manga]/[chapter]/index.svelte",
"name": "index",
"ext": "svelte",
"badExt": false,
"absolutePath": "/home/dan/projects/node/Mangades/src/pages/[manga]/[chapter]/index.svelte",
"importPath": "../src/pages/[manga]/[chapter]/index.svelte",
"isLayout": false,
"isReset": false,
"isIndex": true,
"isFallback": false,
"isPage": true,
"ownMeta": {},
"meta": {
"recursive": true,
"preload": "proximity",
"prerender": true
},
"path": "/:manga/:chapter/index",
"id": "__manga__chapter_index",
"component": () => import('../src/pages/[manga]/[chapter]/index.svelte').then(m => m.default)
}
],
"isLayout": true,
"isReset": false,
"isIndex": false,
"isFallback": false,
"isPage": false,
"importPath": "../src/pages/[manga]/[chapter]/_layout.svelte",
"ownMeta": {},
"meta": {
"recursive": true,
"preload": "proximity",
"prerender": true
},
"path": "/:manga/:chapter",
"id": "__manga__chapter__layout",
"component": () => import('../src/pages/[manga]/[chapter]/_layout.svelte').then(m => m.default)
},
{ {
"isFile": true, "isFile": true,
"isDir": false, "isDir": false,
@ -69,7 +146,7 @@ export const _tree = {
"name": "index", "name": "index",
"ext": "svelte", "ext": "svelte",
"badExt": false, "badExt": false,
"absolutePath": "/home/dan/Documents/node_projects/mangades/src/pages/[manga]/index.svelte", "absolutePath": "/home/dan/projects/node/Mangades/src/pages/[manga]/index.svelte",
"importPath": "../src/pages/[manga]/index.svelte", "importPath": "../src/pages/[manga]/index.svelte",
"isLayout": false, "isLayout": false,
"isReset": false, "isReset": false,
@ -111,7 +188,7 @@ export const _tree = {
"name": "index", "name": "index",
"ext": "svelte", "ext": "svelte",
"badExt": false, "badExt": false,
"absolutePath": "/home/dan/Documents/node_projects/mangades/src/pages/index.svelte", "absolutePath": "/home/dan/projects/node/Mangades/src/pages/index.svelte",
"importPath": "../src/pages/index.svelte", "importPath": "../src/pages/index.svelte",
"isLayout": false, "isLayout": false,
"isReset": false, "isReset": false,

View file

@ -24,27 +24,27 @@
"routify": "routify" "routify": "routify"
}, },
"devDependencies": { "devDependencies": {
"@rollup/plugin-commonjs": "^19.0.0", "@rollup/plugin-commonjs": "^19.0.2",
"@rollup/plugin-node-resolve": "^13.0.0", "@rollup/plugin-node-resolve": "13.0.0",
"@roxi/routify": "^2.18.1", "@roxi/routify": "^2.18.4",
"@types/streamsaver": "^2.0.0", "@types/streamsaver": "^2.0.1",
"cross-env": "^7.0.3", "cross-env": "^7.0.3",
"fs-extra": "^10.0.0", "fs-extra": "^10.0.0",
"nollup": "^0.16.4", "nollup": "^0.16.5",
"npm-run-all": "^4.1.5", "npm-run-all": "^4.1.5",
"postcss": "^8.2.14", "postcss": "^8.4.5",
"postcss-import": "^14.0.1", "postcss-import": "^14.0.2",
"rollup": "^2.47.0", "rollup": "^2.63.0",
"rollup-plugin-hot": "^0.1.1", "rollup-plugin-hot": "^0.1.1",
"rollup-plugin-livereload": "^2.0.0", "rollup-plugin-livereload": "^2.0.5",
"rollup-plugin-svelte": "^7.1.0", "rollup-plugin-svelte": "^7.1.0",
"rollup-plugin-svelte-hot": "^1.0.0-7", "rollup-plugin-svelte-hot": "^1.0.0-8",
"rollup-plugin-terser": "^7.0.2", "rollup-plugin-terser": "^7.0.2",
"rollup-plugin-workbox": "^5.2.1", "rollup-plugin-workbox": "^5.2.1",
"spank": "^1.7.0", "spank": "^1.9.0",
"spassr": "^2.6.0", "spassr": "^2.6.0",
"svelte": "^3.38.2", "svelte": "^3.45.0",
"svelte-preprocess": "^4.7.3", "svelte-preprocess": "^4.10.1",
"tossr": "^1.4.2" "tossr": "^1.4.2"
}, },
"routify": { "routify": {

View file

@ -53,8 +53,7 @@ export default {
hot: isNollup, hot: isNollup,
preprocess: [ preprocess: [
autoPreprocess({ autoPreprocess({
postcss: { plugins: [postcssImport()] }, postcss: { plugins: [postcssImport()] }
defaults: { style: 'postcss' }
}) })
] ]
}), }),

View file

@ -26,13 +26,13 @@
</script> </script>
<tr on:mouseenter={mouseenter} on:mousedown={click} class:selected={selected} style="background-image: linear-gradient(to right, rgba(0, 255, 0, 0.247) {progress * 100}%, transparent {progress * 100}%)"> <tr on:mouseenter={mouseenter} on:mousedown={click} class:selected={selected} style="background-image: linear-gradient(to right, rgba(0, 255, 0, 0.247) {progress * 100}%, transparent {progress * 100}%)">
<td class="no-wrap">{chapter.data.attributes.volume ? "Vol " + chapter.data.attributes.volume : ""}</td> <td class="no-wrap">{chapter.attributes.volume ? "Vol " + chapter.attributes.volume : ""}</td>
<td class="no-wrap">{chapter.data.attributes.chapter ? "Chapter " + chapter.data.attributes.chapter : ""}</td> <td class="no-wrap">{chapter.attributes.chapter ? "Chapter " + chapter.attributes.chapter : ""}</td>
<td>{chapter.data.attributes.title}</td> <td>{chapter.attributes.title}</td>
<td class="action no-wrap"><a href={$url("./" + chapter.data.id)} on:click|stopPropagation={() => !disabledDownload && dispatch("view")}>View</a></td> <td class="action no-wrap"><a href={$url("./" + chapter.id)} on:click|stopPropagation={() => !disabledDownload && dispatch("view")}>View</a></td>
</tr> </tr>
<style> <style lang="postcss">
tr { tr {
border: 1px solid black; border: 1px solid black;
position: relative; position: relative;

View file

@ -13,6 +13,7 @@
$: manga = scoped.manga; $: manga = scoped.manga;
var atHome = scoped.atHome; var atHome = scoped.atHome;
$: atHome = scoped.atHome; $: atHome = scoped.atHome;
console.log("athome", atHome);
var title = manga.title.en || manga.title.jp || Object.values(manga.title)[0]; var title = manga.title.en || manga.title.jp || Object.values(manga.title)[0];
$: title = manga.title.en || manga.title.jp || Object.values(manga.title)[0]; $: title = manga.title.en || manga.title.jp || Object.values(manga.title)[0];
@ -63,7 +64,7 @@
function next() { function next() {
if(!image.complete) return; if(!image.complete) return;
if(page > (chapter.data.attributes[quality].length - 2)) return; if(page > (atHome.chapter[quality].length - 2)) return;
$goto("./" + (parseInt(page) + 1)); $goto("./" + (parseInt(page) + 1));
document.scrollingElement.scrollTo({ document.scrollingElement.scrollTo({
top: 0 top: 0
@ -180,26 +181,26 @@
<svelte:window on:keydown={keydown} on:keyup={keyup} on:resize={isZooming} /> <svelte:window on:keydown={keydown} on:keyup={keyup} on:resize={isZooming} />
<svelte:head> <svelte:head>
<title>{title} Chapter {chapter.data.attributes.chapter} Page {page}</title> <title>{title} Chapter {chapter.attributes.chapter} Page {page}</title>
<meta name="description" value="Read page {page} of chapter {chapter.data.attributes.chapter} of {title} online. Free of charge and ads." /> <meta name="description" value="Read page {page} of chapter {chapter.attributes.chapter} of {title} online. Free of charge and ads." />
</svelte:head> </svelte:head>
<div class="top"> <div class="top">
<a class="back" href={$url("../..")}>Back to chapter list</a> <a class="back" href={$url("../..")}>Back to chapter list</a>
</div> </div>
<img draggable={false} bind:this={image} style="height: {actualHeight}px" on:load={loaded} on:touchstart={handleTouchStart} on:touchmove={handleTouchMove} on:mousedown={mouseclick} on:mouseup={preventDefault} src={`${atHome}/${quality}/${chapter.data.attributes.hash}/${chapter.data.attributes[quality][page - 1]}`} alt="Page {page} in chapter {chapter.data.attributes.chapter} of {manga.title.en}"> <img draggable={false} bind:this={image} style="height: {actualHeight}px" on:load={loaded} on:touchstart={handleTouchStart} on:touchmove={handleTouchMove} on:mousedown={mouseclick} on:mouseup={preventDefault} src={`${atHome.baseUrl}/${quality}/${atHome.chapter.hash}/${atHome.chapter[quality][page - 1]}`} alt="Page {page} in chapter {chapter.attributes.chapter} of {manga.title.en}">
<div class="bottom"> <div class="bottom">
{#if page > 1} {#if page > 1}
<a href={$url("./" + (page - 1))} class="prev">Previous</a> <a href={$url("./" + (page - 1))} class="prev">Previous</a>
{/if} {/if}
{#if page < chapter.data.attributes[quality].length - 1} {#if page < atHome.chapter[quality].length - 1}
<a href={$url("./" + (parseInt(page) + 1))} class="next">Next</a> <a href={$url("./" + (parseInt(page) + 1))} class="next">Next</a>
{/if} {/if}
</div> </div>
<style> <style lang="postcss">
img { img {
width: calc(100vw - 16px); width: calc(100vw - 16px);
height: calc(100vh - 17px); height: calc(100vh - 17px);

View file

@ -12,8 +12,8 @@
async function getChapter(id) { async function getChapter(id) {
if(chapterData && chapterData.id === id) return chapterData; if(chapterData && chapterData.id === id) return chapterData;
const data = await request("chapter/" + id); const data = await request("chapter/" + id);
console.log(data); console.log(data.data);
return data; return data.data;
} }
var chapterData = getChapter(chapter); var chapterData = getChapter(chapter);
@ -21,8 +21,9 @@
async function getAtHome(id) { async function getAtHome(id) {
if(chapterData && chapterData.id === id) return atHome; if(chapterData && chapterData.id === id) return atHome;
const { baseUrl } = await request("at-home/server/" + id); const data = await request("at-home/server/" + id);
return baseUrl; console.log(data);
return data;
} }
var atHome = getAtHome(chapter); var atHome = getAtHome(chapter);

View file

@ -20,7 +20,8 @@
async function getMangaChapters(id) { async function getMangaChapters(id) {
const data = await request("manga/" + id + "/feed?limit=500&translatedLanguage[]=en"); const data = await request("manga/" + id + "/feed?limit=500&translatedLanguage[]=en");
data.results.sort((a, b) => a.data.attributes.chapter - b.data.attributes.chapter); console.log(data);
data.data.sort((a, b) => a.attributes.chapter - b.attributes.chapter);
return data; return data;
} }
@ -61,9 +62,9 @@
console.log(chapter, link, finished); console.log(chapter, link, finished);
if(chapter === -1 || link === -1) return; if(chapter === -1 || link === -1) return;
var cs = await chapters; var cs = await chapters;
var related = cs.results.filter(t => processing.opts.chapters.find(c => t.data.id === c.id)); var related = cs.data.filter(t => processing.opts.chapters.find(c => t.id === c.id));
var done = processing.opts.chapters.filter(t => parseFloat(t.number) < parseFloat(processing.opts.chapters[chapter].number)); var done = processing.opts.chapters.filter(t => parseFloat(t.number) < parseFloat(processing.opts.chapters[chapter].number));
var linkCount = related.map(t => t.data.attributes[quality].length).reduce((a, b) => a + b); var linkCount = related.map(t => t.attributes.pages).reduce((a, b) => a + b);
console.log(related, done, done.reduce((a, b) => (a.links || []).length + (b.links || []).length, 0), link + 1, linkCount); console.log(related, done, done.reduce((a, b) => (a.links || []).length + (b.links || []).length, 0), link + 1, linkCount);
progress = (done.reduce((a, b) => (a.links || []).length + (b.links || []).length, 0) + link + 1) / linkCount; progress = (done.reduce((a, b) => (a.links || []).length + (b.links || []).length, 0) + link + 1) / linkCount;
progressMap.set(processing.opts.chapters[chapter].id, link + 1); progressMap.set(processing.opts.chapters[chapter].id, link + 1);
@ -81,28 +82,24 @@
epub: EpubGenerator, epub: EpubGenerator,
cbz: CBZGenerator cbz: CBZGenerator
} }
const quality = "data";
async function downloadSingle(chapter) { async function downloadSingle(chapter) {
const file = streamSaver.createWriteStream(`${manga.title.en} ${chapter.data.attributes.chapter}.${format}`, { const file = streamSaver.createWriteStream(`${manga.title.en} ${chapter.attributes.chapter}.${format}`, {
writableStrategy: undefined, // (optional) writableStrategy: undefined, // (optional)
readableStrategy: undefined, // (optional) readableStrategy: undefined, // (optional)
}); });
const generator = new generators[format]({ const generator = new generators[format]({
file, file,
id: chapter.data.id, id: chapter.id,
language: chapter.data.attributes.translatedLanguage, language: chapter.attributes.translatedLanguage,
quality, updatedAt: chapter.attributes.updatedAt,
updatedAt: chapter.data.attributes.updatedAt,
title: manga.title.en, title: manga.title.en,
author: "Unknown", author: "Unknown",
chapters: [{ chapters: [{
hash: chapter.data.attributes.hash, id: chapter.id,
id: chapter.data.id, number: chapter.attributes.chapter,
links: chapter.data.attributes[quality], volume: chapter.attributes.volume
number: chapter.data.attributes.chapter,
volume: chapter.data.attributes.volume
}] }]
}); });
@ -127,7 +124,7 @@
} }
} }
function downloadMulti() { function downloadMulti() {
selected.sort((a, b) => a.data.attributes.chapter - b.data.attributes.chapter); selected.sort((a, b) => a.attributes.chapter - b.attributes.chapter);
if(!selected.length) return; if(!selected.length) return;
if(selected.length === 1) { if(selected.length === 1) {
downloadSingle(selected.shift()); downloadSingle(selected.shift());
@ -140,18 +137,15 @@
}); });
const generator = new generators[format]({ const generator = new generators[format]({
file, file,
quality,
id: window.location.toString(), id: window.location.toString(),
language: selected[0].data.attributes.translatedLanguage, language: selected[0].attributes.translatedLanguage,
updatedAt: new Date, updatedAt: new Date,
title: manga.title.en, title: manga.title.en,
author: "Unknown", author: "Unknown",
chapters: selected.map(chapter => ({ chapters: selected.map(chapter => ({
hash: chapter.data.attributes.hash, id: chapter.id,
id: chapter.data.id, number: chapter.attributes.chapter,
links: chapter.data.attributes[quality], volume: chapter.attributes.volume
number: chapter.data.attributes.chapter,
volume: chapter.data.attributes.volume
})) }))
}); });
@ -252,13 +246,13 @@
{#await chapters} {#await chapters}
Loading chapters... Loading chapters...
{:then chapters} {:then chapters}
{#if chapters.results.length === 0} {#if chapters.data.length === 0}
<p>No chapters found.</p> <p>No chapters found.</p>
{/if} {/if}
<table> <table>
<tbody> <tbody>
{#each chapters.results as chapter, i} {#each chapters.data as chapter, i}
<Chapter progress={(progressMap.get(chapter.data.id) || 0) / chapter.data.attributes[quality].length} {chapter} disabledDownload={!!progress} selected={selected.includes(chapter)} on:select={() => select(chapter)} on:download={() => downloadSingle(chapter)} /> <Chapter progress={(progressMap.get(chapter.id) || 0) / chapter.attributes.pages} {chapter} disabledDownload={!!progress} selected={selected.includes(chapter)} on:select={() => select(chapter)} on:download={() => downloadSingle(chapter)} />
{/each} {/each}
</tbody> </tbody>
</table> </table>
@ -268,7 +262,7 @@
<br> <br>
</main> </main>
<style> <style lang="postcss">
.flex { .flex {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;

View file

@ -2,7 +2,7 @@
import { url } from '@roxi/routify' import { url } from '@roxi/routify'
</script> </script>
<style> <style lang="postcss">
.huge { .huge {
font-size: 12rem; font-size: 12rem;
} }

View file

@ -15,7 +15,7 @@
</div> </div>
{/if} {/if}
<style> <style lang="postcss">
.flow { .flow {
position: fixed; position: fixed;
bottom: 0; bottom: 0;

View file

@ -142,7 +142,7 @@
</p> </p>
</main> </main>
<style> <style lang="postcss">
.filters { .filters {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;

View file

@ -33,18 +33,24 @@ export class BaseGenerator {
*/ */
constructor(opts) { constructor(opts) {
this.opts = opts; this.opts = opts;
this.opts.quality = "data";
} }
async generate() {} async generate() {}
/** /**
* @param {string | Chapter | any} chapter * @param {string | Chapter | any} chapter
* @returns {Promise<string>} * @returns {Promise<{ urls: string[], hashes: string[], hash: string[] }>}
*/ */
async getBaseURL(chapter) { async getURLs(chapter) {
if(typeof chapter === "object") chapter = chapter.data.id; if(typeof chapter === "object") chapter = chapter.id;
const { baseUrl } = await request("at-home/server/" + chapter); const data = await request("at-home/server/" + chapter);
return baseUrl; console.log(data, this.opts);
return {
urls: data.chapter[this.opts.quality].map(t => `${data.baseUrl}/${this.opts.quality}/${data.chapter.hash}/${t}`),
hashes: data.chapter[this.opts.quality],
hash: data.chapter.hash
}
} }
/** /**
@ -55,14 +61,14 @@ export class BaseGenerator {
async fetchImage(url, chapter) { async fetchImage(url, chapter) {
var res; var res;
try { try {
res = await fetch(chapter.baseUrl + "/" + url); res = await fetch(url);
} catch(e) { } catch(e) {
console.error(e); console.error(e);
res = await fetch(proxy + chapter.baseUrl + "/" + url); res = await fetch(proxy + url);
} }
if(Math.floor(res.status / 100) !== 2) { if(Math.floor(res.status / 100) !== 2) {
for(var i = 0; i < RETRY_LIMIT; i++) { for(var i = 0; i < RETRY_LIMIT; i++) {
chapter.baseUrl = await this.getBaseURL(chapter); chapter.baseUrl = await this.getURLs(chapter);
res = await fetch(chapter.baseUrl + "/" + url); res = await fetch(chapter.baseUrl + "/" + url);
if(Math.floor(res.status / 100) === 2) return res; if(Math.floor(res.status / 100) === 2) return res;
} }

View file

@ -25,14 +25,19 @@ export class CBZGenerator extends BaseGenerator {
const chapterCountLength = this.opts.chapters.reduce((a, b) => Math.max(a.number, b.number), 0).toString().length; const chapterCountLength = this.opts.chapters.reduce((a, b) => Math.max(a.number, b.number), 0).toString().length;
for(const chapterI in this.opts.chapters) { for(const chapterI in this.opts.chapters) {
const chapter = this.opts.chapters[chapterI]; const chapter = this.opts.chapters[chapterI];
if(!chapter.baseUrl) chapter.baseUrl = await this.getBaseURL(chapter.id); if(!chapter.links) {
let data = await this.getURLs(chapter);
chapter.links = data.urls;
chapter.hashes = data.hashes;
chapter.hash = data.hash;
}
const imageCountLength = chapter.links.length.toString().length; const imageCountLength = chapter.links.length.toString().length;
for(const i in chapter.links) { for(const i in chapter.links) {
let url = chapter.links[i];
let hash = chapter.hashes[i];
this.callback(chapterI, i, false); this.callback(chapterI, i, false);
const hash = chapter.links[i];
const URL = `${this.opts.quality}/${chapter.hash}/${hash}`;
const start = performance.now(); const start = performance.now();
const res = await this.fetchImage(URL, chapter); const res = await this.fetchImage(url, chapter);
const chapterText = chapter.number.toString().padStart(chapterCountLength, "0"); const chapterText = chapter.number.toString().padStart(chapterCountLength, "0");
const image = new ZipPassThrough(`${this.opts.title} ${chapterText}/${this.opts.title} ${chapterText} page ${i.toString().padStart(imageCountLength, "0")}.${hash.substr(hash.lastIndexOf(".") + 1)}`); const image = new ZipPassThrough(`${this.opts.title} ${chapterText}/${this.opts.title} ${chapterText} page ${i.toString().padStart(imageCountLength, "0")}.${hash.substr(hash.lastIndexOf(".") + 1)}`);
this.zip.add(image); this.zip.add(image);
@ -43,7 +48,7 @@ export class CBZGenerator extends BaseGenerator {
cached: res.headers.get("X-Cache") === "HIT", cached: res.headers.get("X-Cache") === "HIT",
duration: end, duration: end,
success: Math.floor(res.status / 100) === 2, success: Math.floor(res.status / 100) === 2,
url: `${chapter.baseUrl}/${URL}` url
}); });
image.push(data, true); image.push(data, true);
this.callback(chapterI, i, true); this.callback(chapterI, i, true);

View file

@ -25,7 +25,19 @@ export class EpubGenerator extends BaseGenerator {
} }
}; };
this.hashes = this.opts.chapters.map(t => t.links).flat(); this.hashes = [];
for(const chapterI in this.opts.chapters) {
const chapter = this.opts.chapters[chapterI];
if(!chapter.links) {
let data = await this.getURLs(chapter);
chapter.links = data.urls;
chapter.hashes = data.hashes;
chapter.hash = data.hash;
this.hashes.push(...chapter.hashes);
}
}
this.mimetype(); this.mimetype();
this.container(); this.container();
@ -36,13 +48,12 @@ export class EpubGenerator extends BaseGenerator {
for(const chapterI in this.opts.chapters) { for(const chapterI in this.opts.chapters) {
const chapter = this.opts.chapters[chapterI]; const chapter = this.opts.chapters[chapterI];
if(!chapter.baseUrl) chapter.baseUrl = await this.getBaseURL(chapter.id);
for(const i in chapter.links) { for(const i in chapter.links) {
let url = chapter.links[i];
let hash = chapter.hashes[i];
this.callback(chapterI, i, false); this.callback(chapterI, i, false);
const hash = chapter.links[i];
const URL = `${this.opts.quality}/${chapter.hash}/${hash}`;
const start = performance.now(); const start = performance.now();
const res = await this.fetchImage(URL, chapter); const res = await this.fetchImage(url, chapter);
const image = new ZipPassThrough("OEBPS/" + hash); const image = new ZipPassThrough("OEBPS/" + hash);
this.zip.add(image); this.zip.add(image);
const data = new Uint8Array(await res.arrayBuffer()); const data = new Uint8Array(await res.arrayBuffer());
@ -52,7 +63,7 @@ export class EpubGenerator extends BaseGenerator {
cached: res.headers.get("X-Cache") === "HIT", cached: res.headers.get("X-Cache") === "HIT",
duration: end, duration: end,
success: Math.floor(res.status / 100) === 2, success: Math.floor(res.status / 100) === 2,
url: `${chapter.baseUrl}/${URL}` url: url
}); });
image.push(data, true); image.push(data, true);
const textContent = new ZipPassThrough("OEBPS/" + i + ".xhtml"); const textContent = new ZipPassThrough("OEBPS/" + i + ".xhtml");