diff --git a/src/pages/[manga]/index.svelte b/src/pages/[manga]/index.svelte index 1c2cd03..d6580b7 100644 --- a/src/pages/[manga]/index.svelte +++ b/src/pages/[manga]/index.svelte @@ -59,10 +59,11 @@ if(chapter === -1 || link === -1) return; var cs = await chapters; var related = cs.results.filter(t => processing.opts.chapters.find(c => t.data.id === c.id)); - var done = processing.opts.chapters.filter(t => t.number < chapter); + 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); + 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; - progressMap.set(processing.opts.chapters[chapter].number, link + 1); + progressMap.set(processing.opts.chapters[chapter].id, link + 1); progressMap = progressMap; }; await processing.generate(); @@ -220,7 +221,7 @@ {#each chapters.results as chapter, i} - select(chapter)} on:download={() => downloadSingle(chapter)} /> + select(chapter)} on:download={() => downloadSingle(chapter)} /> {/each}
diff --git a/src/util/baseGenerator.js b/src/util/baseGenerator.js index 168d635..dd3702c 100644 --- a/src/util/baseGenerator.js +++ b/src/util/baseGenerator.js @@ -6,10 +6,13 @@ * @property {number?} volume * @property {string[]} links * @property {string} hash + * @property {string} baseUrl */ import request, { proxy } from "./request"; +const RETRY_LIMIT = 10; + /** * Base generator, to be extended */ @@ -17,7 +20,6 @@ export class BaseGenerator { /** * * @param {object} opts - * @param {string} opts.baseUrl * @param {string} opts.quality * @param {WritableStream} opts.file * @param {string} opts.title @@ -47,15 +49,24 @@ export class BaseGenerator { /** * @param {string} url + * @param {Chapter} chapter * @returns {Promise} */ - async fetchImage(url) { + async fetchImage(url, chapter) { var res; try { - res = await fetch(url); + res = await fetch(chapter.baseUrl + "/" + url); } catch(e) { console.error(e); - res = await fetch(proxy + url); + res = await fetch(proxy + chapter.baseUrl + "/" + url); + } + if(Math.floor(res.status / 100) !== 2) { + for(var i = 0; i < RETRY_LIMIT; i++) { + chapter.baseUrl = await this.getBaseURL(chapter); + res = await fetch(chapter.baseUrl + "/" + url); + if(Math.floor(res.status / 100) === 2) return res; + } + throw new Error("Retry limit reached"); } return res; } diff --git a/src/util/bookName.test.js b/src/util/bookName.test.js new file mode 100644 index 0000000..1e5c6aa --- /dev/null +++ b/src/util/bookName.test.js @@ -0,0 +1,60 @@ +import { bookName } from "./bookName"; + +function assert(isTrue, success, failure = "Failed") { + if(isTrue) { + console.log("✅ " + success); + } else { + console.log("❌ " + failure + " (" + success + ")"); + } + return isTrue; +} + +assert( + bookName([1, 2, 3]) === "Chapters 1 - 3", + "Basic chapter shortening" +); + +assert( + bookName([1, 2, 3, 4, 5], [{ vol: 1, chapters: 5}]) === "Vol 1", + "Basic shortening to volumes" +); + +assert( + bookName([1,2,3,4,5], [{vol: 1, chapters: 3}]) === "Vol 1, Chapters 4, 5", + "Mixed volume and chapter shortening" +); + +assert( + bookName([1, 2], [{vol: 1, chapters: 3}, {vol: 2, chapters: 5}]) === "Chapters 1, 2", + "List of chapters without shortening with volume definitions" +); + +assert( + bookName([1,2,3,5,6]) === "Chapters 1 - 3, 5, 6", + "Mixed shortening and list of chapters" +); + +assert( + bookName([1,2,3,4,5], [{vol: "First", chapters: 5}]) === "Vol First", + "String volume" +); + +assert( + bookName([1,2,3.5,3]) === "Chapters 1 - 3, 3.5", + "Float chapters" +); + +assert( + bookName([1,2,"3.5.1", 3]) === "Chapters 1 - 3, 3.5.1", + "String chapters" +); + +assert( + bookName([1,3,5,2,4]) === "Chapters 1 - 5", + "Out of order input" +); + +assert( + bookName([1,2,3,4,5,"5.1"], [{ vol: 1, chapters: 5 }]) === "Vol 1, Chapters 5.1", + "String/float chapters and volume definitions" +) \ No newline at end of file diff --git a/src/util/generateCbz.js b/src/util/generateCbz.js index 8ff0525..bfd209c 100644 --- a/src/util/generateCbz.js +++ b/src/util/generateCbz.js @@ -25,16 +25,16 @@ export class CBZGenerator extends BaseGenerator { const chapterCountLength = this.opts.chapters.reduce((a, b) => Math.max(a.number, b.number), 0).toString().length; for(const chapterI in this.opts.chapters) { const chapter = this.opts.chapters[chapterI]; - const baseUrl = await this.getBaseURL(chapter.id); + if(!chapter.baseUrl) chapter.baseUrl = await this.getBaseURL(chapter.id); const imageCountLength = chapter.links.length.toString().length; for(const i in chapter.links) { this.callback(chapterI, i, false); const hash = chapter.links[i]; - const URL = `${baseUrl}/${this.opts.quality}/${chapter.hash}/${hash}`; + const URL = `${this.opts.quality}/${chapter.hash}/${hash}`; const start = performance.now(); - const res = await this.fetchImage(URL); + const res = await this.fetchImage(URL, chapter); const chapterText = chapter.number.toString().padStart(chapterCountLength, "0"); - const image = new ZipPassThrough(`${this.opts.title} ${chapterText}/${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); const data = new Uint8Array(await res.arrayBuffer()); const end = performance.now() - start; @@ -43,7 +43,7 @@ export class CBZGenerator extends BaseGenerator { cached: res.headers.get("X-Cache") === "HIT", duration: end, success: Math.floor(res.status / 100) === 2, - url: URL + url: `${chapter.baseUrl}/${URL}` }); image.push(data, true); this.callback(chapterI, i, true); diff --git a/src/util/generateEpub.js b/src/util/generateEpub.js index 2660f3a..05aaebc 100644 --- a/src/util/generateEpub.js +++ b/src/util/generateEpub.js @@ -36,13 +36,13 @@ export class EpubGenerator extends BaseGenerator { for(const chapterI in this.opts.chapters) { const chapter = this.opts.chapters[chapterI]; - const baseUrl = await this.getBaseURL(chapter.id); + if(!chapter.baseUrl) chapter.baseUrl = await this.getBaseURL(chapter.id); for(const i in chapter.links) { this.callback(chapterI, i, false); const hash = chapter.links[i]; - const URL = `${baseUrl}/${this.opts.quality}/${chapter.hash}/${hash}`; + const URL = `${this.opts.quality}/${chapter.hash}/${hash}`; const start = performance.now(); - const res = await this.fetchImage(URL); + const res = await this.fetchImage(URL, chapter); const image = new ZipPassThrough("OEBPS/" + hash); this.zip.add(image); const data = new Uint8Array(await res.arrayBuffer()); @@ -52,7 +52,7 @@ export class EpubGenerator extends BaseGenerator { cached: res.headers.get("X-Cache") === "HIT", duration: end, success: Math.floor(res.status / 100) === 2, - url: URL + url: `${chapter.baseUrl}/${URL}` }); image.push(data, true); const textContent = new ZipPassThrough("OEBPS/" + i + ".xhtml");