Merge pull request #299 from xMohnad/add-update-sources

Add update sources
This commit is contained in:
Moustapha Kodjo Amadou
2025-06-26 14:01:02 +01:00
committed by GitHub
4 changed files with 390 additions and 332 deletions

View File

@@ -47,6 +47,7 @@ import 'src/es/gremorymangas/gremorymangas.dart';
import 'src/es/ryujinmanga/ryujinmanga.dart'; import 'src/es/ryujinmanga/ryujinmanga.dart';
import 'src/es/senpaiediciones/senpaiediciones.dart'; import 'src/es/senpaiediciones/senpaiediciones.dart';
import 'src/es/skymangas/skymangas.dart'; import 'src/es/skymangas/skymangas.dart';
import 'src/es/erosscans/erosscans.dart';
import 'src/fr/flamescansfr/flamescansfr.dart'; import 'src/fr/flamescansfr/flamescansfr.dart';
import 'src/fr/mangasscans/mangasscans.dart'; import 'src/fr/mangasscans/mangasscans.dart';
import 'src/fr/rimuscans/rimuscans.dart'; import 'src/fr/rimuscans/rimuscans.dart';
@@ -177,6 +178,8 @@ List<Source> _mangareaderSourcesList =
rizzcomicSource, rizzcomicSource,
//Berserker Scan (ES) //Berserker Scan (ES)
berserkerscanSource, berserkerscanSource,
// Eros Scan (ES)
erosscansSource,
//Cartel de Manhwas (ES) //Cartel de Manhwas (ES)
carteldemanhwasSource, carteldemanhwasSource,
//De Todo Un Poco Scan (ES) //De Todo Un Poco Scan (ES)

View File

@@ -0,0 +1,14 @@
import '../../../../../../../model/source.dart';
Source get erosscansSource => _erosscansSource;
Source _erosscansSource = Source(
name: "Eros Scans",
baseUrl: "https://eros-void.xyz",
lang: "en",
typeSource: "mangareader",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/mangareader/src/en/erosscans/icon.png",
dateFormat: "MMMM dd, yyyy",
dateFormatLocale: "en_us",
);

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View File

@@ -1,9 +1,10 @@
// prettier-ignore
const mangayomiSources = [{ const mangayomiSources = [{
"name": "ManhwaZ", "name": "ManhwaZ",
"lang": "en", "lang": "en",
"baseUrl": "https://manhwaz.com", "baseUrl": "https://manhwaz.com",
"apiUrl": "", "apiUrl": "",
"iconUrl": "https://manhwaz.com/favicon.ico", "iconUrl": "https://manhwaz.com/apple-touch-icon.png",
"typeSource": "single", "typeSource": "single",
"itemType": 0, "itemType": 0,
"version": "0.1.0", "version": "0.1.0",
@@ -14,8 +15,9 @@ const mangayomiSources = [{
class DefaultExtension extends MProvider { class DefaultExtension extends MProvider {
getHeaders(url) { getHeaders(url) {
return { return {
"Referer": this.source.baseUrl, Referer: this.source.baseUrl,
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36" "User-Agent":
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36",
}; };
} }
@@ -63,7 +65,7 @@ class DefaultExtension extends MProvider {
// Check for next page // Check for next page
const hasNextPage = doc.selectFirst("ul.pager a[rel=next]") !== null; const hasNextPage = doc.selectFirst("ul.pager a[rel=next]") !== null;
return { "list": list, hasNextPage }; return { list: list, hasNextPage };
} }
// Helper method to get image URL with fallbacks // Helper method to get image URL with fallbacks
@@ -86,11 +88,17 @@ class DefaultExtension extends MProvider {
const statusLower = status?.toLowerCase() || ""; const statusLower = status?.toLowerCase() || "";
if (statusLower.includes("ongoing") || statusLower.includes("publishing")) { if (statusLower.includes("ongoing") || statusLower.includes("publishing")) {
return 0; return 0;
} else if (statusLower.includes("completed") || statusLower.includes("complete")) { } else if (
statusLower.includes("completed") ||
statusLower.includes("complete")
) {
return 1; return 1;
} else if (statusLower.includes("hiatus")) { } else if (statusLower.includes("hiatus")) {
return 2; return 2;
} else if (statusLower.includes("cancelled") || statusLower.includes("dropped")) { } else if (
statusLower.includes("cancelled") ||
statusLower.includes("dropped")
) {
return 3; return 3;
} else { } else {
return 5; // unknown return 5; // unknown
@@ -106,7 +114,9 @@ class DefaultExtension extends MProvider {
const now = new Date(); const now = new Date();
// Extract number and unit // Extract number and unit
const match = lowerDateStr.match(/(\d+)\s*(second|minute|hour|day|week|month|year)s?\s*ago/); const match = lowerDateStr.match(
/(\d+)\s*(second|minute|hour|day|week|month|year)s?\s*ago/,
);
if (!match) { if (!match) {
// Try to parse as regular date // Try to parse as regular date
const date = new Date(dateStr); const date = new Date(dateStr);
@@ -132,7 +142,7 @@ class DefaultExtension extends MProvider {
calendar.setDate(calendar.getDate() - value); calendar.setDate(calendar.getDate() - value);
break; break;
case "week": case "week":
calendar.setDate(calendar.getDate() - (value * 7)); calendar.setDate(calendar.getDate() - value * 7);
break; break;
case "month": case "month":
calendar.setMonth(calendar.getMonth() - value); calendar.setMonth(calendar.getMonth() - value);
@@ -151,7 +161,7 @@ class DefaultExtension extends MProvider {
} }
async getPopular(page) { async getPopular(page) {
const url = `${this.source.baseUrl}/genre/manhwa?page=${page}&m_orderby=views`; const url = `${this.getBaseUrl()}/genre/manhwa?page=${page}&m_orderby=views`;
const res = await new Client().get(url, this.getHeaders()); const res = await new Client().get(url, this.getHeaders());
return this.mangaListFromPage(res, ".page-item-detail"); return this.mangaListFromPage(res, ".page-item-detail");
} }
@@ -161,7 +171,7 @@ class DefaultExtension extends MProvider {
} }
async getLatestUpdates(page) { async getLatestUpdates(page) {
const url = `${this.source.baseUrl}/?page=${page}`; const url = `${this.getBaseUrl()}/?page=${page}`;
const res = await new Client().get(url, this.getHeaders()); const res = await new Client().get(url, this.getHeaders());
return this.mangaListFromPage(res, ".page-item-detail"); return this.mangaListFromPage(res, ".page-item-detail");
} }
@@ -169,19 +179,23 @@ class DefaultExtension extends MProvider {
async search(query, page, filters) { async search(query, page, filters) {
if (query && query.trim()) { if (query && query.trim()) {
// Search with query // Search with query
const url = `${this.source.baseUrl}/search?s=${encodeURIComponent(query)}&page=${page}`; const url = `${this.getBaseUrl()}/search?s=${encodeURIComponent(query)}&page=${page}`;
const res = await new Client().get(url, this.getHeaders()); const res = await new Client().get(url, this.getHeaders());
return this.mangaListFromPage(res, ".page-item-detail"); return this.mangaListFromPage(res, ".page-item-detail");
} }
// Filter-based search // Filter-based search
let url = this.source.baseUrl; let url = this.getBaseUrl();
let hasGenreFilter = false; let hasGenreFilter = false;
// Process filters // Process filters
if (filters && filters.length > 0) { if (filters && filters.length > 0) {
const genreFilter = filters.find(f => f.type === "select" && f.name === "genre"); const genreFilter = filters.find(
const orderByFilter = filters.find(f => f.type === "select" && f.name === "orderby"); (f) => f.type === "select" && f.name === "genre",
);
const orderByFilter = filters.find(
(f) => f.type === "select" && f.name === "orderby",
);
if (genreFilter && genreFilter.state > 0) { if (genreFilter && genreFilter.state > 0) {
const selectedGenre = genreFilter.values[genreFilter.state]; const selectedGenre = genreFilter.values[genreFilter.state];
@@ -213,7 +227,7 @@ class DefaultExtension extends MProvider {
async getDetail(url) { async getDetail(url) {
// Ensure we have the full URL // Ensure we have the full URL
const fullUrl = url.startsWith("http") ? url : `${this.source.baseUrl}${url}`; const fullUrl = url.startsWith("http") ? url : `${this.getBaseUrl()}${url}`;
const res = await new Client().get(fullUrl, this.getHeaders()); const res = await new Client().get(fullUrl, this.getHeaders());
const doc = new Document(res.body); const doc = new Document(res.body);
@@ -227,11 +241,15 @@ class DefaultExtension extends MProvider {
const imageUrl = imageElement ? this.getImageUrl(imageElement) : ""; const imageUrl = imageElement ? this.getImageUrl(imageElement) : "";
// Extract author // Extract author
const authorElement = doc.selectFirst("div.post-content_item .summary-heading:contains(Author) + .summary-content"); const authorElement = doc.selectFirst(
"div.post-content_item .summary-heading:contains(Author) + .summary-content",
);
const author = authorElement?.text?.trim() || ""; const author = authorElement?.text?.trim() || "";
// Extract status // Extract status
const statusElement = doc.selectFirst("div.summary-heading:contains(status) + div.summary-content"); const statusElement = doc.selectFirst(
"div.summary-heading:contains(status) + div.summary-content",
);
const statusText = statusElement?.text?.toLowerCase() || ""; const statusText = statusElement?.text?.toLowerCase() || "";
const status = this.toStatus(statusText); const status = this.toStatus(statusText);
@@ -264,7 +282,7 @@ class DefaultExtension extends MProvider {
chapters.push({ chapters.push({
name: chapterName, name: chapterName,
url: chapterUrl, url: chapterUrl,
dateUpload dateUpload,
}); });
} }
} }
@@ -276,13 +294,13 @@ class DefaultExtension extends MProvider {
status, status,
author, author,
genre, genre,
chapters chapters,
}; };
} }
async getPageList(url) { async getPageList(url) {
// Ensure we have the full URL // Ensure we have the full URL
const fullUrl = url.startsWith("http") ? url : `${this.source.baseUrl}${url}`; const fullUrl = url.startsWith("http") ? url : `${this.getBaseUrl()}${url}`;
const res = await new Client().get(fullUrl, this.getHeaders()); const res = await new Client().get(fullUrl, this.getHeaders());
const doc = new Document(res.body); const doc = new Document(res.body);
@@ -300,7 +318,7 @@ class DefaultExtension extends MProvider {
if (imageUrl.startsWith("//")) { if (imageUrl.startsWith("//")) {
finalUrl = "https:" + imageUrl; finalUrl = "https:" + imageUrl;
} else if (imageUrl.startsWith("/")) { } else if (imageUrl.startsWith("/")) {
finalUrl = this.source.baseUrl + imageUrl; finalUrl = this.getBaseUrl() + imageUrl;
} }
pages.push(finalUrl); pages.push(finalUrl);
@@ -314,10 +332,10 @@ class DefaultExtension extends MProvider {
return [ return [
{ {
type: "header", type: "header",
name: "Note: Filters only work when search query is empty" name: "Note: Filters only work when search query is empty",
}, },
{ {
type: "separator" type: "separator",
}, },
{ {
type: "select", type: "select",
@@ -354,9 +372,9 @@ class DefaultExtension extends MProvider {
{ name: "Sports", value: "genre/sports" }, { name: "Sports", value: "genre/sports" },
{ name: "Supernatural", value: "genre/supernatural" }, { name: "Supernatural", value: "genre/supernatural" },
{ name: "Tragedy", value: "genre/tragedy" }, { name: "Tragedy", value: "genre/tragedy" },
{ name: "Webtoons", value: "genre/webtoons" } { name: "Webtoons", value: "genre/webtoons" },
], ],
state: 0 state: 0,
}, },
{ {
type: "select", type: "select",
@@ -366,14 +384,37 @@ class DefaultExtension extends MProvider {
{ name: "Latest", value: "latest" }, { name: "Latest", value: "latest" },
{ name: "Rating", value: "rating" }, { name: "Rating", value: "rating" },
{ name: "Most Views", value: "views" }, { name: "Most Views", value: "views" },
{ name: "New", value: "new" } { name: "New", value: "new" },
], ],
state: 0 state: 0,
} },
]; ];
} }
getBaseUrl() {
const preference = new SharedPreferences();
var base_url = preference.get("domain_url");
if (base_url.length == 0) {
return this.source.baseUrl;
}
if (base_url.endsWith("/")) {
return base_url.slice(0, -1);
}
return base_url;
}
getSourcePreferences() { getSourcePreferences() {
return []; return [
{
key: "domain_url",
editTextPreference: {
title: "Edit URL",
summary: "",
value: this.source.baseUrl,
dialogTitle: "URL",
dialogMessage: "",
},
},
];
} }
} }