Skip to content

Commit

Permalink
Merge branch 'master' into merge-keiyoushi
Browse files Browse the repository at this point in the history
  • Loading branch information
cuong-tran committed Nov 3, 2024
2 parents d38b074 + 6e00aec commit fc19c2e
Show file tree
Hide file tree
Showing 49 changed files with 978 additions and 176 deletions.
1 change: 1 addition & 0 deletions lib-multisrc/mangaesp/assets/i18n/messages_en.properties
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ sort_by_filter_views=Views
sort_by_filter_updated=Updated
sort_by_filter_added=Added
status_filter_title=Status
status_filter_all=All
status_filter_ongoing=Ongoing
status_filter_hiatus=Hiatus
status_filter_dropped=Dropped
Expand Down
1 change: 1 addition & 0 deletions lib-multisrc/mangaesp/assets/i18n/messages_es.properties
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ sort_by_filter_views=Vistas
sort_by_filter_updated=Actualización
sort_by_filter_added=Agregado
status_filter_title=Estado
status_filter_all=Todos
status_filter_ongoing=En curso
status_filter_hiatus=En pausa
status_filter_dropped=Abandonado
Expand Down
2 changes: 1 addition & 1 deletion lib-multisrc/mangaesp/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ plugins {
id("lib-multisrc")
}

baseVersionCode = 2
baseVersionCode = 3

dependencies {
api(project(":lib:i18n"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,9 @@ abstract class MangaEsp(
val statusFilter = filterList.firstInstanceOrNull<StatusFilter>()

if (statusFilter != null) {
filteredList = filteredList.filter { it.status == statusFilter.toUriPart() }.toMutableList()
if (statusFilter.toUriPart() != 0) {
filteredList = filteredList.filter { it.status == statusFilter.toUriPart() }.toMutableList()
}
}

val sortByFilter = filterList.firstInstanceOrNull<SortByFilter>()
Expand Down Expand Up @@ -216,6 +218,7 @@ abstract class MangaEsp(
)

protected open fun getStatusList() = arrayOf(
Pair(intl["status_filter_all"], 0),
Pair(intl["status_filter_ongoing"], 1),
Pair(intl["status_filter_hiatus"], 2),
Pair(intl["status_filter_dropped"], 3),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ abstract class MangaThemesia(
listOf("canceled", "cancelled", "cancelado", "cancellato", "cancelados", "dropped", "discontinued", "abandonné")
.any { this.contains(it, ignoreCase = true) } -> SManga.CANCELLED

listOf("hiatus", "on hold", "pausado", "en espera", "en pause", "en attente")
listOf("hiatus", "on hold", "pausado", "en espera", "en pause", "en attente", "hiato")
.any { this.contains(it, ignoreCase = true) } -> SManga.ON_HIATUS

else -> SManga.UNKNOWN
Expand Down
2 changes: 1 addition & 1 deletion src/all/ehentai/build.gradle
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
ext {
extName = 'E-Hentai'
extClass = '.EHFactory'
extVersionCode = 21
extVersionCode = 22
isNsfw = true
}

Expand Down
124 changes: 102 additions & 22 deletions src/all/ehentai/src/eu/kanade/tachiyomi/extension/all/ehentai/EHentai.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@ import android.annotation.SuppressLint
import android.app.Application
import android.content.SharedPreferences
import android.net.Uri
import android.webkit.CookieManager
import androidx.preference.CheckBoxPreference
import androidx.preference.EditTextPreference
import androidx.preference.PreferenceScreen
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.asObservableSuccess
import eu.kanade.tachiyomi.source.ConfigurableSource
import eu.kanade.tachiyomi.source.model.Filter
import eu.kanade.tachiyomi.source.model.Filter.CheckBox
import eu.kanade.tachiyomi.source.model.Filter.Group
import eu.kanade.tachiyomi.source.model.Filter.Select
import eu.kanade.tachiyomi.source.model.Filter.Text
import eu.kanade.tachiyomi.source.model.Filter.TriState
import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.MangasPage
import eu.kanade.tachiyomi.source.model.Page
Expand All @@ -39,13 +39,22 @@ abstract class EHentai(
private val ehLang: String,
) : ConfigurableSource, HttpSource() {

override val name = "E-Hentai"

private val preferences: SharedPreferences by lazy {
Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000)
}

override val name = "E-Hentai"
private val webViewCookieManager: CookieManager by lazy { CookieManager.getInstance() }
private val memberId: String = getMemberIdPref()
private val passHash: String = getPassHashPref()

override val baseUrl = "https://e-hentai.org"
override val baseUrl: String
get() = if (memberId.isNotEmpty() && passHash.isNotEmpty()) {
"https://exhentai.org"
} else {
"https://e-hentai.org"
}

override val supportsLatest = true

Expand Down Expand Up @@ -161,10 +170,23 @@ abstract class EHentai(
query.isBlank() -> languageTag(enforceLanguageFilter)
else -> languageTag(enforceLanguageFilter).let { if (it.isNotEmpty()) "$query,$it" else query }
}
modifiedQuery += filters.filterIsInstance<TagFilter>()
.flatMap { it.markedTags() }
.joinToString(",")
.let { if (it.isNotEmpty()) ",$it" else it }
filters.filterIsInstance<TextFilter>().forEach { it ->
if (it.state.isNotEmpty()) {
val splitted = it.state.split(",").filter(String::isNotBlank)
if (splitted.size < 2 && it.type != "tags") {
modifiedQuery += " ${it.type}:\"${it.state.replace(" ", "+")}\""
} else {
splitted.forEach { tag ->
val trimmed = tag.trim().lowercase()
if (trimmed.startsWith('-')) {
modifiedQuery += " -${it.type}:\"${trimmed.removePrefix("-").replace(" ", "+")}\""
} else {
modifiedQuery += " ${it.type}:\"${trimmed.replace(" ", "+")}\""
}
}
}
}
}
uri.appendQueryParameter("f_search", modifiedQuery)
// when attempting to search with no genres selected, will auto select all genres
filters.filterIsInstance<GenreGroup>().firstOrNull()?.state?.let {
Expand Down Expand Up @@ -352,6 +374,12 @@ abstract class EHentai(
// Bypass "Offensive For Everyone" content warning
cookies["nw"] = "1"

cookies["ipb_member_id"] = memberId

cookies["ipb_pass_hash"] = passHash

cookies["igneous"] = ""

buildCookies(cookies)
}

Expand Down Expand Up @@ -388,12 +416,17 @@ abstract class EHentai(
EnforceLanguageFilter(getEnforceLanguagePref()),
Watched(),
GenreGroup(),
TagFilter("Misc Tags", triStateBoxesFrom(miscTags), "other"),
TagFilter("Female Tags", triStateBoxesFrom(femaleTags), "female"),
TagFilter("Male Tags", triStateBoxesFrom(maleTags), "male"),
Filter.Header("Separate tags with commas (,)"),
Filter.Header("Prepend with dash (-) to exclude"),
Filter.Header("Use 'Female Tags' or 'Male Tags' for specific categories. 'Tags' searches all categories."),
TextFilter("Tags", "tag"),
TextFilter("Female Tags", "female"),
TextFilter("Male Tags", "male"),
AdvancedGroup(),
)

internal open class TextFilter(name: String, val type: String, val specific: String = "") : Filter.Text(name)

class Watched : CheckBox("Watched List"), UriFilter {
override fun addToUri(builder: Uri.Builder) {
if (state) {
Expand Down Expand Up @@ -487,17 +520,6 @@ abstract class EHentai(

private class EnforceLanguageFilter(default: Boolean) : CheckBox("Enforce language", default)

private val miscTags = "3d, already uploaded, anaglyph, animal on animal, animated, anthology, arisa mizuhara, artbook, ashiya noriko, bailey jay, body swap, caption, chouzuki maryou, christian godard, comic, compilation, dakimakura, fe galvao, ffm threesome, figure, forbidden content, full censorship, full color, game sprite, goudoushi, group, gunyou mikan, harada shigemitsu, hardcore, helly von valentine, higurashi rin, hololive, honey select, how to, incest, incomplete, ishiba yoshikazu, jessica nigri, kalinka fox, kanda midori, kira kira, kitami eri, kuroi hiroki, lenfried, lincy leaw, marie claude bourbonnais, matsunaga ayaka, me me me, missing cover, mmf threesome, mmt threesome, mosaic censorship, mtf threesome, multi-work series, no penetration, non-nude, novel, nudity only, oakazaki joe, out of order, paperchild, pm02 colon 20, poor grammar, radio comix, realporn, redraw, replaced, sakaki kasa, sample, saotome love, scanmark, screenshots, sinful goddesses, sketch lines, stereoscopic, story arc, takeuti ken, tankoubon, themeless, tikuma jukou, time stop, tsubaki zakuro, ttm threesome, twins, uncensored, vandych alex, variant set, watermarked, webtoon, western cg, western imageset, western non-h, yamato nadeshiko club, yui okada, yukkuri, zappa go"
private val femaleTags = "ahegao, anal, angel, apron, bandages, bbw, bdsm, beauty mark, big areolae, big ass, big breasts, big clit, big lips, big nipples, bikini, blackmail, bloomers, blowjob, bodysuit, bondage, breast expansion, bukkake, bunny girl, business suit, catgirl, centaur, cheating, chinese dress, christmas, collar, corset, cosplaying, cowgirl, crossdressing, cunnilingus, dark skin, daughter, deepthroat, defloration, demon girl, double penetration, dougi, dragon, drunk, elf, exhibitionism, farting, females only, femdom, filming, fingering, fishnets, footjob, fox girl, furry, futanari, garter belt, ghost, giantess, glasses, gloves, goblin, gothic lolita, growth, guro, gyaru, hair buns, hairy, hairy armpits, handjob, harem, hidden sex, horns, huge breasts, humiliation, impregnation, incest, inverted nipples, kemonomimi, kimono, kissing, lactation, latex, leg lock, leotard, lingerie, lizard girl, maid, masked face, masturbation, midget, miko, milf, mind break, mind control, monster girl, mother, muscle, nakadashi, netorare, nose hook, nun, nurse, oil, paizuri, panda girl, pantyhose, piercing, pixie cut, policewoman, ponytail, pregnant, rape, rimjob, robot, scat, schoolgirl uniform, sex toys, shemale, sister, small breasts, smell, sole dickgirl, sole female, squirting, stockings, sundress, sweating, swimsuit, swinging, tail, tall girl, teacher, tentacles, thigh high boots, tomboy, transformation, twins, twintails, unusual pupils, urination, vore, vtuber, widow, wings, witch, wolf girl, x-ray, yuri, zombie"
private val maleTags = "anal, bbm, big ass, big penis, bikini, blood, blowjob, bondage, catboy, cheating, chikan, condom, crab, crossdressing, dark skin, deepthroat, demon, dickgirl on male, dilf, dog boy, double anal, double penetration, dragon, drunk, exhibitionism, facial hair, feminization, footjob, fox boy, furry, glasses, group, guro, hairy, handjob, hidden sex, horns, huge penis, human on furry, kimono, lingerie, lizard guy, machine, maid, males only, masturbation, mmm threesome, monster, muscle, nakadashi, ninja, octopus, oni, pillory, policeman, possession, prostate massage, public use, schoolboy uniform, schoolgirl uniform, sex toys, shotacon, sleeping, snuff, sole male, stockings, sunglasses, swimsuit, tall man, tentacles, tomgirl, unusual pupils, virginity, waiter, x-ray, yaoi, zombie"

private fun triStateBoxesFrom(tagString: String): List<TagTriState> = tagString.split(", ").map { TagTriState(it) }

class TagTriState(tag: String) : TriState(tag)
class TagFilter(name: String, private val triStateBoxes: List<TagTriState>, private val nameSpace: String) : Group<TagTriState>(name, triStateBoxes) {
fun markedTags() = triStateBoxes.filter { it.isIncluded() }.map { "$nameSpace:${it.name}" } + triStateBoxes.filter { it.isExcluded() }.map { "-$nameSpace:${it.name}" }
}

// map languages to their internal ids
private val languageMappings = listOf(
Pair("japanese", listOf("0", "1024", "2048")),
Expand Down Expand Up @@ -529,6 +551,16 @@ abstract class EHentai(
private const val ENFORCE_LANGUAGE_PREF_TITLE = "Enforce Language"
private const val ENFORCE_LANGUAGE_PREF_SUMMARY = "If checked, forces browsing of manga matching a language tag"
private const val ENFORCE_LANGUAGE_PREF_DEFAULT_VALUE = false

private const val MEMBER_ID_PREF_KEY = "MEMBER_ID"
private const val MEMBER_ID_PREF_TITLE = "ipb_member_id"
private const val MEMBER_ID_PREF_SUMMARY = "ipb_member_id value"
private const val MEMBER_ID_PREF_DEFAULT_VALUE = ""

private const val PASS_HASH_PREF_KEY = "PASS_HASH"
private const val PASS_HASH_PREF_TITLE = "ipb_pass_hash"
private const val PASS_HASH_PREF_SUMMARY = "ipb_pass_hash value"
private const val PASS_HASH_PREF_DEFAULT_VALUE = ""
}

// Preferences
Expand All @@ -545,8 +577,56 @@ abstract class EHentai(
preferences.edit().putBoolean("${ENFORCE_LANGUAGE_PREF_KEY}_$lang", checkValue).commit()
}
}

val memberIdPref = EditTextPreference(screen.context).apply {
key = MEMBER_ID_PREF_KEY
title = MEMBER_ID_PREF_TITLE
summary = MEMBER_ID_PREF_SUMMARY

setDefaultValue(MEMBER_ID_PREF_DEFAULT_VALUE)
}

val passHashPref = EditTextPreference(screen.context).apply {
key = PASS_HASH_PREF_KEY
title = PASS_HASH_PREF_TITLE
summary = PASS_HASH_PREF_SUMMARY

setDefaultValue(PASS_HASH_PREF_DEFAULT_VALUE)
}
screen.addPreference(memberIdPref)
screen.addPreference(passHashPref)
screen.addPreference(enforceLanguagePref)
}

private fun getEnforceLanguagePref(): Boolean = preferences.getBoolean("${ENFORCE_LANGUAGE_PREF_KEY}_$lang", ENFORCE_LANGUAGE_PREF_DEFAULT_VALUE)

private fun getCookieValue(cookieTitle: String, defaultValue: String, prefKey: String): String {
val cookies = webViewCookieManager.getCookie("https://forums.e-hentai.org")
var value: String? = null

if (cookies != null) {
val cookieArray = cookies.split("; ")
for (cookie in cookieArray) {
if (cookie.startsWith("$cookieTitle=")) {
value = cookie.split("=")[1]

break
}
}
}

if (value == null) {
value = preferences.getString(prefKey, defaultValue) ?: defaultValue
}

return value
}

private fun getPassHashPref(): String {
return getCookieValue(PASS_HASH_PREF_TITLE, PASS_HASH_PREF_DEFAULT_VALUE, PASS_HASH_PREF_KEY)
}

private fun getMemberIdPref(): String {
return getCookieValue(MEMBER_ID_PREF_TITLE, MEMBER_ID_PREF_DEFAULT_VALUE, MEMBER_ID_PREF_KEY)
}
}
2 changes: 1 addition & 1 deletion src/en/mangago/build.gradle
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
ext {
extName = 'Mangago'
extClass = '.Mangago'
extVersionCode = 20
extVersionCode = 21
isNsfw = true
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ class Mangago : ParsedHttpSource(), ConfigurableSource {
override fun searchMangaNextPageSelector() = genreListingNextPageSelector

private var titleRegex: Regex =
Regex("(?:\\([^()]*\\)|\\{[^{}]*\\}|\\[(?:(?!]).)*]|«[^»]*»|〘[^〙]*〙|「[^」]*」|『[^』]*』|≪[^≫]*≫|﹛[^﹜]*﹜|〖[^〖〗]*〗|𖤍.+?𖤍|/.+?)\\s*|([|/~].*)|-.*-")
Regex("(?:\\([^()]*\\)|\\{[^{}]*\\}|\\[(?:(?!]).)*]|«[^»]*»|〘[^〙]*〙|「[^」]*」|『[^』]*』|≪[^≫]*≫|﹛[^﹜]*﹜|〖[^〖〗]*〗|𖤍.+?𖤍|/.+?|⌜.+?⌝)\\s*")

override fun mangaDetailsParse(document: Document) = SManga.create().apply {
title = document.selectFirst(".w-title h1")!!.text()
Expand Down
2 changes: 1 addition & 1 deletion src/es/manhwalatino/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ ext {
extClass = '.ManhwaLatino'
themePkg = 'madara'
baseUrl = 'https://manhwa-latino.com'
overrideVersionCode = 7
overrideVersionCode = 8
isNsfw = true
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
package eu.kanade.tachiyomi.extension.es.manhwalatino

import eu.kanade.tachiyomi.multisrc.madara.Madara
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.interceptor.rateLimitHost
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.OkHttpClient
import okhttp3.Response
import okhttp3.ResponseBody.Companion.toResponseBody
import org.jsoup.nodes.Element
import java.text.SimpleDateFormat
Expand All @@ -17,6 +22,7 @@ class ManhwaLatino : Madara(
) {

override val client: OkHttpClient = super.client.newBuilder()
.rateLimitHost(baseUrl.toHttpUrl(), 1, 1)
.addInterceptor { chain ->
val request = chain.request()
val headers = request.headers.newBuilder()
Expand All @@ -43,6 +49,30 @@ class ManhwaLatino : Madara(
override val mangaDetailsSelectorDescription = "div.post-content_item:contains(Resumen) div.summary-container"
override val pageListParseSelector = "div.page-break img.wp-manga-chapter-img"

private val chapterListNextPageSelector = "div.pagination > span.current + span"
override fun chapterListParse(response: Response): List<SChapter> {
val mangaUrl = response.request.url
var document = response.asJsoup()
launchIO { countViews(document) }

val chapterList = mutableListOf<SChapter>()
var page = 1

do {
val chapterElements = document.select(chapterListSelector())
if (chapterElements.isEmpty()) break
chapterList.addAll(chapterElements.map { chapterFromElement(it) })
val hasNextPage = document.select(chapterListNextPageSelector).isNotEmpty()
if (hasNextPage) {
page++
val nextPageUrl = mangaUrl.newBuilder().setQueryParameter("t", page.toString()).build()
document = client.newCall(GET(nextPageUrl, headers)).execute().asJsoup()
} else { break }
} while (true)

return chapterList
}

override fun chapterFromElement(element: Element): SChapter {
val chapter = SChapter.create()

Expand Down
9 changes: 9 additions & 0 deletions src/pt/arcticscan/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
ext {
extName = 'Arctic Scan'
extClass = '.ArcticScan'
themePkg = 'madara'
baseUrl = 'https://arcticscan.top'
overrideVersionCode = 0
}

apply from: "$rootDir/common.gradle"
Binary file added src/pt/arcticscan/res/mipmap-hdpi/ic_launcher.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/pt/arcticscan/res/mipmap-mdpi/ic_launcher.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package eu.kanade.tachiyomi.extension.pt.arcticscan

import eu.kanade.tachiyomi.multisrc.madara.Madara
import java.text.SimpleDateFormat
import java.util.Locale

class ArcticScan : Madara(
"Arctic Scan",
"https://arcticscan.top",
"pt-BR",
dateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.ROOT),
) {
override val useNewChapterEndpoint = true
}
22 changes: 22 additions & 0 deletions src/pt/blackscans/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application>
<activity
android:name=".pt.blackscans.BlackScansUrlActivity"
android:excludeFromRecents="true"
android:exported="true"
android:theme="@android:style/Theme.NoDisplay">
<intent-filter>
<action android:name="android.intent.action.VIEW" />

<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />

<data
android:host="blackscans.site"
android:pathPattern="/series/..*"
android:scheme="https" />
</intent-filter>
</activity>
</application>
</manifest>
7 changes: 7 additions & 0 deletions src/pt/blackscans/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
ext {
extName = 'Black Scans'
extClass = '.BlackScans'
extVersionCode = 1
}

apply from: "$rootDir/common.gradle"
Binary file added src/pt/blackscans/res/mipmap-hdpi/ic_launcher.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit fc19c2e

Please sign in to comment.