diff --git a/package.json b/package.json index f1e7cdf..b15d1be 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "NovelScraper", - "version": "2.0.4", + "version": "2.0.5", "description": "App for downloading novels from pirate sites.", "homepage": "https://github.com/HanaDigital/NovelScraper", "author": { diff --git a/src/app/services/novel-factory.service.ts b/src/app/services/novel-factory.service.ts index fa747a1..b04b376 100644 --- a/src/app/services/novel-factory.service.ts +++ b/src/app/services/novel-factory.service.ts @@ -20,7 +20,7 @@ export class NovelFactoryService { "NovelScraper-Library" ); - constructor(public database: DatabaseService) {} + constructor(public database: DatabaseService) { } async generateEpub( novel: novelObj, @@ -33,7 +33,7 @@ export class NovelFactoryService { await shellJS.mkdir("-p", novelFolder); // Save chapters in a json file and set the novel as download - await this.saveChapters(novel, chapters, novelFolder); + await this.saveChapters(novel, chapters); // Download the cover and get its path const coverPath = await this.downloadCover(novel.cover, novelFolder); @@ -72,9 +72,12 @@ export class NovelFactoryService { // Save chapters to a json file so we don't re-download when updating async saveChapters( novel: novelObj, - chapters: chapterObj[], - novelFolder: string + chapters: chapterObj[] ): Promise { + // Create the folder for storing the novel files + const novelFolder = novel.folderPath; + await shellJS.mkdir("-p", novelFolder); + const chaptersFile = path.join(novelFolder, "chapters.json"); const json = JSON.stringify(chapters, null, 4); writeFile(chaptersFile, json, (err) => { diff --git a/src/app/services/sources/boxnovel.service.ts b/src/app/services/sources/boxnovel.service.ts index aa39592..1f5757b 100644 --- a/src/app/services/sources/boxnovel.service.ts +++ b/src/app/services/sources/boxnovel.service.ts @@ -272,50 +272,62 @@ export class BoxnovelService extends sourceService { chapterNames = chapterNames.slice(update.startIndex); } - // Download each chapter at a time - for (let i = 0; i < chapterLinks.length; i++) { - if (this.database.isCanceled(downloadID)) { - this.database.updateDownloading(novel.link, false); - console.log("Download canceled!"); - return; - } + const totalLength = downloadedChapters.length + chapterLinks.length; + let canceled = false; - const html = await this.getHtml(chapterLinks[i]); - const chapterHtml = html.getElementsByClassName( - "entry-content" - )[0]; - try { - chapterHtml.getElementsByClassName("cha-tit")[0].remove(); // Remove h3 tag from chapter - } catch (error) { - console.log( - "Missing 'cha-tit' class at chapter index " + + try { + // Download each chapter at a time + for (let i = 0; i < chapterLinks.length; i++) { + if (this.database.isCanceled(downloadID)) { + this.database.updateDownloading(novel.link, false); + console.log("Download canceled!"); + canceled = true; + return; + } + + const html = await this.getHtml(chapterLinks[i]); + const chapterHtml = html.getElementsByClassName( + "entry-content" + )[0]; + try { + chapterHtml.getElementsByClassName("cha-tit")[0].remove(); // Remove h3 tag from chapter + } catch (error) { + console.log( + "Missing 'cha-tit' class at chapter index " + i + "and chapter name " + chapterNames[i] - ); - } + ); + } - const chapterTitle = chapterNames[i]; + const chapterTitle = chapterNames[i]; - let chapterBody = "

" + chapterTitle + "

"; - chapterBody += chapterHtml.outerHTML; + let chapterBody = "

" + chapterTitle + "

"; + chapterBody += chapterHtml.outerHTML; - const chapter = this.prepChapter( + const chapter = this.prepChapter(novel, downloadID, chapterTitle, chapterBody, downloadedChapters.length, totalLength); + downloadedChapters.push(chapter); + } + + if (!canceled) this.novelFactory.generateEpub(novel, downloadedChapters, downloadID); + } catch (error) { + canceled = true; + console.error("Error downloading the complete novel. Retry."); + console.error(error); + } + + if (canceled) { + this.novelFactory.saveChapters( novel, - downloadID, - chapterTitle, - chapterBody, - i, - chapterLinks.length + downloadedChapters ); - downloadedChapters.push(chapter); + this.database.cancelDownload(downloadID); + this.database.updateDownloading(novel.link, false); + this.database.updateDownloadedChapters(novel.link, downloadedChapters.length); + this.database.updateDownloaded(novel.link, true); + this.database.updateIsUpdated(novel.link, false); } - this.novelFactory.generateEpub( - novel, - downloadedChapters, - downloadID - ); } catch (error) { this.database.cancelDownload(downloadID); this.database.updateDownloading(novel.link, false); diff --git a/src/app/services/sources/novelfull.service.ts b/src/app/services/sources/novelfull.service.ts index 61cd7b1..b6a8951 100644 --- a/src/app/services/sources/novelfull.service.ts +++ b/src/app/services/sources/novelfull.service.ts @@ -257,9 +257,9 @@ export class NovelfullService extends sourceService { for (let x = 0; x < chapters.length; x++) { chapterLinks.push( "https://novelfull.com" + - chapters[x] - .getElementsByTagName("a")[0] - .getAttribute("href") + chapters[x] + .getElementsByTagName("a")[0] + .getAttribute("href") ); chapterNames.push( chapters[x].getElementsByTagName("a")[0].title @@ -280,53 +280,65 @@ export class NovelfullService extends sourceService { chapterNames = chapterNames.slice(update.startIndex); } - // Download each chapter at a time - for (let i = 0; i < chapterLinks.length; i++) { - if (this.database.isCanceled(downloadID)) { - this.database.updateDownloading(novel.link, false); - console.log("Download canceled!"); - return; - } + const totalLength = downloadedChapters.length + chapterLinks.length; + let canceled = false; - const html = await this.getHtml(chapterLinks[i]); + try { + // Download each chapter at a time + for (let i = 0; i < chapterLinks.length; i++) { + if (this.database.isCanceled(downloadID)) { + this.database.updateDownloading(novel.link, false); + console.log("Download canceled!"); + canceled = true; + return; + } - //////////////////////// [2] YOUR CODE STARTS HERE /////////////////////////////// + const html = await this.getHtml(chapterLinks[i]); - // FIXME: you have the html of the chapter page - // Get the element that wraps all the paragraphs of the chapter - const chapterHtml = html.getElementsByClassName("chapter-c")[0]; + //////////////////////// [2] YOUR CODE STARTS HERE /////////////////////////////// - //////////////////////// YOUR CODE ENDS HERE ///////////////////////////////// + // FIXME: you have the html of the chapter page + // Get the element that wraps all the paragraphs of the chapter + const chapterHtml = html.getElementsByClassName("chapter-c")[0]; - const chapterTitle = chapterNames[i]; + //////////////////////// YOUR CODE ENDS HERE ///////////////////////////////// - let chapterBody = "

" + chapterTitle + "

"; - chapterBody += chapterHtml.outerHTML; + const chapterTitle = chapterNames[i]; - chapterBody = chapterBody.replace( - /\(adsbygoogle = window.adsbygoogle \|\| \[\]\).push\({}\);/g, - "" - ); - chapterBody = chapterBody.replace(/<\/script>/g, ""); - chapterBody = chapterBody.replace(//g, ""); - console.log(chapterBody); + let chapterBody = "

" + chapterTitle + "

"; + chapterBody += chapterHtml.outerHTML; + + chapterBody = chapterBody.replace( + /\(adsbygoogle = window.adsbygoogle \|\| \[\]\).push\({}\);/g, + "" + ); + chapterBody = chapterBody.replace(/<\/script>/g, ""); + chapterBody = chapterBody.replace(//g, ""); + console.log(chapterBody); + + const chapter = this.prepChapter(novel, downloadID, chapterTitle, chapterBody, downloadedChapters.length, totalLength); + downloadedChapters.push(chapter); + } + + if (!canceled) this.novelFactory.generateEpub(novel, downloadedChapters, downloadID); + } catch (error) { + canceled = true; + console.error("Error downloading the complete novel. Retry."); + console.error(error); + } - const chapter = this.prepChapter( + if (canceled) { + this.novelFactory.saveChapters( novel, - downloadID, - chapterTitle, - chapterBody, - i, - chapterLinks.length + downloadedChapters ); - downloadedChapters.push(chapter); + this.database.cancelDownload(downloadID); + this.database.updateDownloading(novel.link, false); + this.database.updateDownloadedChapters(novel.link, downloadedChapters.length); + this.database.updateDownloaded(novel.link, true); + this.database.updateIsUpdated(novel.link, false); } - this.novelFactory.generateEpub( - novel, - downloadedChapters, - downloadID - ); } catch (error) { this.database.cancelDownload(downloadID); this.database.updateDownloading(novel.link, false); diff --git a/src/app/services/sources/readlightnovel-service.service.ts b/src/app/services/sources/readlightnovel-service.service.ts index f896396..005948f 100644 --- a/src/app/services/sources/readlightnovel-service.service.ts +++ b/src/app/services/sources/readlightnovel-service.service.ts @@ -163,35 +163,57 @@ export class ReadlightnovelService extends sourceService { chapterNames = chapterNames.slice(update.startIndex); } - // Download each chapter at a time - for (let i = 0; i < chapterLinks.length; i++) { - if (this.database.isCanceled(downloadID)) { - this.database.updateDownloading(novel.link, false); - console.log('Download canceled!') - return; - } + const totalLength = downloadedChapters.length + chapterLinks.length; + let canceled = false; + + try { + // Download each chapter at a time + for (let i = 0; i < chapterLinks.length; i++) { + if (this.database.isCanceled(downloadID)) { + this.database.updateDownloading(novel.link, false); + console.log('Download canceled!'); + canceled = true; + break; + } + + const html = await this.getHtml(chapterLinks[i]); - const html = await this.getHtml(chapterLinks[i]); + //////////////////////// YOUR CODE STARTS HERE /////////////////////////////// - //////////////////////// YOUR CODE STARTS HERE /////////////////////////////// + // You have the html of the chapter page + // Get the element that wraps all the paragraphs of the chapter + const chapterHtml = html.getElementsByClassName('desc')[0].getElementsByClassName("hidden")[0]; - // You have the html of the chapter page - // Get the element that wraps all the paragraphs of the chapter - const chapterHtml = html.getElementsByClassName('desc')[0].getElementsByClassName("hidden")[0]; + //////////////////////// YOUR CODE ENDS HERE ///////////////////////////////// - //////////////////////// YOUR CODE ENDS HERE ///////////////////////////////// + const chapterTitle = chapterNames[i]; - const chapterTitle = chapterNames[i]; + let chapterBody = "

" + chapterTitle + "

"; + chapterBody += chapterHtml.outerHTML; - let chapterBody = "

" + chapterTitle + "

"; - chapterBody += chapterHtml.outerHTML; + const chapter = this.prepChapter(novel, downloadID, chapterTitle, chapterBody, downloadedChapters.length, totalLength); + downloadedChapters.push(chapter); + } - const chapter = this.prepChapter(novel, downloadID, chapterTitle, chapterBody, i, chapterLinks.length); - downloadedChapters.push(chapter); + if (!canceled) this.novelFactory.generateEpub(novel, downloadedChapters, downloadID); + } catch (error) { + canceled = true; + console.error("Error downloading the complete novel. Retry."); + console.error(error); } - this.novelFactory.generateEpub(novel, downloadedChapters, downloadID); + if (canceled) { + this.novelFactory.saveChapters( + novel, + downloadedChapters + ); + this.database.cancelDownload(downloadID); + this.database.updateDownloading(novel.link, false); + this.database.updateDownloadedChapters(novel.link, downloadedChapters.length); + this.database.updateDownloaded(novel.link, true); + this.database.updateIsUpdated(novel.link, false); + } } catch (error) { this.database.cancelDownload(downloadID); diff --git a/src/app/services/sources/sourceService.ts b/src/app/services/sources/sourceService.ts index 4b50bce..7b57404 100644 --- a/src/app/services/sources/sourceService.ts +++ b/src/app/services/sources/sourceService.ts @@ -13,7 +13,7 @@ export class sourceService { scrollPos: number; - constructor(public database: DatabaseService) {} + constructor(public database: DatabaseService) { } async searchWIthLink( link: string, @@ -23,9 +23,9 @@ export class sourceService { return {}; } - async searchWithName(name: string, source: string): Promise {} + async searchWithName(name: string, source: string): Promise { } - async download(novel: novelObj, downloadID: number): Promise {} + async download(novel: novelObj, downloadID: number): Promise { } update(novel: novelObj, numOfChapters: number): update { if (numOfChapters > novel.totalChapters) { @@ -90,7 +90,8 @@ export class sourceService { const percentage = ((currentPos / destPos) * 100).toFixed(2); this.database.updateDownloadTracker(downloadID, percentage); - console.log(percentage); + + console.log(`Downloaded chapter ${currentPos}`) return { title: title,