diff --git a/src/ar/mangastorm/AndroidManifest.xml b/src/ar/mangastorm/AndroidManifest.xml new file mode 100644 index 000000000..8072ee00d --- /dev/null +++ b/src/ar/mangastorm/AndroidManifest.xml @@ -0,0 +1,2 @@ + + diff --git a/src/ar/mangastorm/build.gradle b/src/ar/mangastorm/build.gradle new file mode 100644 index 000000000..4bca18b48 --- /dev/null +++ b/src/ar/mangastorm/build.gradle @@ -0,0 +1,11 @@ +ext { + extName = 'MangaStorm' + extClass = '.MangaStorm' + extVersionCode = 1 +} + +apply from: "$rootDir/common.gradle" + +dependencies { + implementation(project(":lib:randomua")) +} diff --git a/src/ar/mangastorm/res/mipmap-hdpi/ic_launcher.png b/src/ar/mangastorm/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 000000000..e53f36188 Binary files /dev/null and b/src/ar/mangastorm/res/mipmap-hdpi/ic_launcher.png differ diff --git a/src/ar/mangastorm/res/mipmap-mdpi/ic_launcher.png b/src/ar/mangastorm/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 000000000..b40aa4858 Binary files /dev/null and b/src/ar/mangastorm/res/mipmap-mdpi/ic_launcher.png differ diff --git a/src/ar/mangastorm/res/mipmap-xhdpi/ic_launcher.png b/src/ar/mangastorm/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 000000000..f4a56bc00 Binary files /dev/null and b/src/ar/mangastorm/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/src/ar/mangastorm/res/mipmap-xxhdpi/ic_launcher.png b/src/ar/mangastorm/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 000000000..b24b899be Binary files /dev/null and b/src/ar/mangastorm/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/src/ar/mangastorm/res/mipmap-xxxhdpi/ic_launcher.png b/src/ar/mangastorm/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 000000000..9204e5e4d Binary files /dev/null and b/src/ar/mangastorm/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/src/ar/mangastorm/src/eu/kanade/tachiyomi/extension/ar/mangastorm/MangaStorm.kt b/src/ar/mangastorm/src/eu/kanade/tachiyomi/extension/ar/mangastorm/MangaStorm.kt new file mode 100644 index 000000000..6348218de --- /dev/null +++ b/src/ar/mangastorm/src/eu/kanade/tachiyomi/extension/ar/mangastorm/MangaStorm.kt @@ -0,0 +1,105 @@ +package eu.kanade.tachiyomi.extension.ar.mangastorm + +import eu.kanade.tachiyomi.lib.randomua.UserAgentType +import eu.kanade.tachiyomi.lib.randomua.setRandomUserAgent +import eu.kanade.tachiyomi.network.GET +import eu.kanade.tachiyomi.source.model.FilterList +import eu.kanade.tachiyomi.source.model.Page +import eu.kanade.tachiyomi.source.model.SChapter +import eu.kanade.tachiyomi.source.model.SManga +import eu.kanade.tachiyomi.source.online.ParsedHttpSource +import okhttp3.HttpUrl.Companion.toHttpUrl +import okhttp3.Request +import org.jsoup.nodes.Document +import org.jsoup.nodes.Element +import java.lang.UnsupportedOperationException + +class MangaStorm : ParsedHttpSource() { + + override val name = "MangaStorm" + + override val lang = "ar" + + override val baseUrl = "https://mangastorm.org" + + override val supportsLatest = true + + override val client = network.cloudflareClient.newBuilder() + .setRandomUserAgent( + UserAgentType.DESKTOP, + filterInclude = listOf("chrome"), + ) + .build() + + override fun headersBuilder() = super.headersBuilder() + .set("Referer", "$baseUrl/") + + override fun popularMangaRequest(page: Int): Request { + return GET("$baseUrl/mangas?page=$page", headers) + } + + override fun popularMangaSelector() = "div.row div.col" + override fun popularMangaNextPageSelector() = ".page-link[rel=next]" + + override fun popularMangaFromElement(element: Element) = SManga.create().apply { + setUrlWithoutDomain(element.selectFirst("a")!!.absUrl("href")) + title = element.select(".manga-ct-title").text() + thumbnail_url = element.selectFirst("img")?.imgAttr() + } + + override fun latestUpdatesRequest(page: Int): Request { + return GET(baseUrl, headers) + } + + override fun latestUpdatesSelector() = popularMangaSelector() + override fun latestUpdatesNextPageSelector() = null + override fun latestUpdatesFromElement(element: Element) = popularMangaFromElement(element) + + override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { + val url = "$baseUrl/mangas".toHttpUrl().newBuilder() + .addQueryParameter("page", page.toString()) + .addQueryParameter("query", query.trim()) + .build() + + return GET(url, headers) + } + + override fun searchMangaSelector() = popularMangaSelector() + override fun searchMangaNextPageSelector() = popularMangaNextPageSelector() + override fun searchMangaFromElement(element: Element) = popularMangaFromElement(element) + + override fun mangaDetailsParse(document: Document): SManga { + val root = document.selectFirst(".card-body .col-lg-9")!! + + return SManga.create().apply { + title = document.select(".card-header").text() + thumbnail_url = document.selectFirst("img.card-img-right")?.imgAttr() + genre = root.select(".flex-wrap a").eachText().joinToString() + description = root.selectFirst(".card-text")?.text() + } + } + + override fun chapterListSelector() = ".card-body a.btn-fixed-width" + + override fun chapterFromElement(element: Element) = SChapter.create().apply { + setUrlWithoutDomain(element.absUrl("href")) + name = element.text() + } + + override fun pageListParse(document: Document): List { + return document.select("div.text-center .img-fluid") + .mapIndexed { idx, img -> + Page(idx, "", img.imgAttr()) + } + } + + override fun imageUrlParse(document: Document) = throw UnsupportedOperationException() + + private fun Element.imgAttr() = when { + hasAttr("data-cfsrc") -> attr("abs:data-cfsrc") + hasAttr("data-src") -> attr("abs:data-src") + hasAttr("data-lazy-src") -> attr("abs:data-lazy-src") + hasAttr("srcset") -> attr("abs:srcset").substringBefore(" ") + else -> attr("abs:src") + } +}