Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add site ReaperScan #1649

Open
wants to merge 1 commit into
base: ExperimentalTabMode
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@
{ "name": "LucasFreitaslpf1"},
{ "name": "Jemeni11"},
{ "name": "maforn"},
{ "name": "phazei"}
{ "name": "phazei"},
{ "name": "jeremie8"}
],
"license": "GPL-3.0-only",
"bugs": {
Expand Down
106 changes: 106 additions & 0 deletions plugin/js/parsers/ReaperscansParser.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
"use strict";

parserFactory.register("reaperscans.com", () => new ReaperscansParser());

class ReaperscansParser extends Parser{
constructor() {
super();
this.seriesInfo = null;
}

async getChapterUrls(dom) {
if(this.seriesInfo === null) {
await this.extractSeriesInfo(dom)
}
const chaptersApiUrl = new URL('https://api.reaperscans.com/chapter/query');
chaptersApiUrl.searchParams.set('page', 1);
chaptersApiUrl.searchParams.set('perPage', this.seriesInfo.chaptersCount);
chaptersApiUrl.searchParams.set('query', '');
chaptersApiUrl.searchParams.set('order', 'asc');
chaptersApiUrl.searchParams.set('series_id', this.seriesInfo.seriesId);
const chaptersJson = (await HttpClient.fetchJson(chaptersApiUrl)).json;
const chapterUrls = chaptersJson.data.map(chapter => {
return {
sourceUrl: `https://reaperscans.com/series/${this.seriesInfo.seriesSlug}/${chapter.chapter_slug}`,
title: `${chapter.chapter_name} - ${chapter.chapter_title}`
};
});
return chapterUrls;
}

async extractSeriesInfo(dom) {
const baseUrl= this.getBaseUrl(dom);
const match = baseUrl.match(/reaperscans\.com\/series\/[^/]+/);
const apiUrl = `https://api.${match[0]}`;
const seriesJson = (await HttpClient.fetchJson(apiUrl)).json
this.seriesInfo = {
seriesId: seriesJson.id,
seriesName: seriesJson.title,
seriesSlug: seriesJson.series_slug,
chaptersCount: seriesJson.meta.chapters_count
}
}

findScriptContent(dom) {
const scripts = dom.querySelectorAll("script");
for (const script of scripts) {
if (script.firstChild && script.firstChild.nodeName === "#text"
&& script.textContent.includes("\\u003cp") //contains paragraph tags
&& script.textContent.includes("series_id") === false //ignore other series info
) {
return script.textContent;
}
}
return null;
}

findContent(dom) {
const scriptContent = this.findScriptContent(dom);
const content = scriptContent.substring(scriptContent.indexOf('\\u003cp'), scriptContent.lastIndexOf('\\u003e') + 6)
const decoded = this.decodeString(content);
const html = this.cleanHTML(decoded);
return html;
}

decodeString(input) {
// Decode Unicode escapes
const unicodeDecoded = JSON.parse(`"${input}"`);
// Decode HTML entities
const textarea = document.createElement("textarea");
textarea.innerHTML = unicodeDecoded;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Google and Mozilla may refuse to accept an extension that assigns text to innerHTML. You should use DOMParser's parseFromString() to convert string to HTML. https://developer.mozilla.org/en-US/docs/Web/API/DOMParser/parseFromString

return textarea.value;
}

cleanHTML(inputHTML) {
let html = inputHTML.replace(/\n\n/g, "<br>");
html = html.replace(/\n/g, "");
html = html.replace(/style=\"line-height: 2;\"/g, "");
const doc = new DOMParser().parseFromString(html, "text/html");

const unwantedPatterns = [
"Reaper Scans", // Site name
"Chapter ", // Chapter title
"[TL:", "[PR:",
"Translator:", "Editor:", // Translator/Proofreader notes
"discord", "Discord:" // Discord link
];

const paragraphs = doc.querySelectorAll("p");
paragraphs.forEach(p => {
if (unwantedPatterns.some(pattern => p.textContent.includes(pattern))) {
p.remove();
}
});

return doc.body;
}

extractTitleImpl(dom) {
const title = dom.querySelector("h1");
if(title.textContent.includes("Chapter")) {
return dom.querySelector("h2"); //h2 on chapter pages and h1 on series pages
}
return title;
}

}
1 change: 1 addition & 0 deletions plugin/popup.html
Original file line number Diff line number Diff line change
Expand Up @@ -739,6 +739,7 @@ <h3>Instructions</h3>
<script src="js/parsers/ReadnovelfullorgParser.js"></script>
<script src="js/parsers/ReadNovelFullParser.js"></script>
<script src="js/parsers/ReadwnParser.js"></script>
<script src="js/parsers/ReaperscansParser.js"></script>
<script src="js/parsers/RebirthOnline.js"></script>
<script src="js/parsers/RedditParser.js"></script>
<script src="js/parsers/RoyalRoadParser.js"></script>
Expand Down
Loading