Skip to content

Commit

Permalink
Add site ReaperScan
Browse files Browse the repository at this point in the history
  • Loading branch information
jeremie8 committed Jan 24, 2025
1 parent e11449b commit 268f67e
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 1 deletion.
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;
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

0 comments on commit 268f67e

Please sign in to comment.