From 1d9923156ffd6d0960bd7b5fec272b9c9be386db Mon Sep 17 00:00:00 2001 From: Alessandro Jean <alessandrojean@gmail.com> Date: Sat, 21 Aug 2021 14:32:56 -0300 Subject: [PATCH] Add view count reporting to WpMangaStream and WpMangaReader. (#8711) --- .../multisrc/wpmangareader/WPMangaReader.kt | 67 ++++++++++++++++--- .../wpmangareader/WPMangaReaderGenerator.kt | 2 +- .../multisrc/wpmangastream/WPMangaStream.kt | 67 ++++++++++++++++--- .../wpmangastream/WPMangaStreamGenerator.kt | 2 +- 4 files changed, 119 insertions(+), 19 deletions(-) diff --git a/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/wpmangareader/WPMangaReader.kt b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/wpmangareader/WPMangaReader.kt index 19659431b..84f1767fe 100644 --- a/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/wpmangareader/WPMangaReader.kt +++ b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/wpmangareader/WPMangaReader.kt @@ -1,6 +1,7 @@ package eu.kanade.tachiyomi.multisrc.wpmangareader import eu.kanade.tachiyomi.network.GET +import eu.kanade.tachiyomi.network.POST import eu.kanade.tachiyomi.network.asObservableSuccess import eu.kanade.tachiyomi.source.model.Filter import eu.kanade.tachiyomi.source.model.FilterList @@ -13,6 +14,7 @@ import eu.kanade.tachiyomi.util.asJsoup import kotlinx.serialization.json.Json import kotlinx.serialization.json.jsonArray import kotlinx.serialization.json.jsonPrimitive +import okhttp3.FormBody import okhttp3.HttpUrl import okhttp3.HttpUrl.Companion.toHttpUrlOrNull import okhttp3.OkHttpClient @@ -59,7 +61,6 @@ abstract class WPMangaReader( // search override fun searchMangaSelector() = ".utao .uta .imgu, .listupd .bs .bsx, .listo .bs .bsx" - /** * Given some string which represents an http url, returns a identifier (id) for a manga * which can be used to fetch its details at "$baseUrl$mangaUrlDirectory/$id" @@ -75,7 +76,8 @@ abstract class WPMangaReader( val isMangaUrl = listOf( baseMangaUrl.host == url.host, pathLengthIs(url, 2), - url.pathSegments[0] == baseMangaUrl.pathSegments[0]).all { it } + url.pathSegments[0] == baseMangaUrl.pathSegments[0] + ).all { it } val potentiallyChapterUrl = pathLengthIs(url, 1) if (isMangaUrl) Single.just(url.pathSegments[1]) @@ -104,14 +106,12 @@ abstract class WPMangaReader( else fetchMangaDetails(SManga.create().apply { this.url = "$mangaUrlDirectory/$id" }) .map { - it.url = "$mangaUrlDirectory/$id"// isn't set in returned manga + it.url = "$mangaUrlDirectory/$id" // isn't set in returned manga MangasPage(listOf(it), false) } } - } - override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { var url = "$baseUrl".toHttpUrlOrNull()!!.newBuilder() if (query.isNotEmpty()) { @@ -182,10 +182,10 @@ abstract class WPMangaReader( // add alternative name to manga description document.select(altNameSelector).firstOrNull()?.ownText()?.let { - if (it.isBlank().not()) { - description = when { - description.isNullOrBlank() -> altName + it - else -> description + "\n\n$altName" + it + if (it.isEmpty().not()) { + description += when { + description!!.isEmpty() -> altName + it + else -> "\n\n$altName" + it } } } @@ -213,6 +213,8 @@ abstract class WPMangaReader( val checkChapter = document.select(chapterListSelector()).firstOrNull() if (date != "" && checkChapter != null) chapters[0].date_upload = parseDate(date) + countViews(document) + return chapters } @@ -243,6 +245,8 @@ abstract class WPMangaReader( .filterNot { it.attr("abs:src").isNullOrEmpty() } .mapIndexed { i, img -> pages.add(Page(i, "", img.attr("abs:src"))) } + countViews(document) + // Some sites like mangakita now load pages via javascript if (pages.isNotEmpty()) { return pages } @@ -261,6 +265,48 @@ abstract class WPMangaReader( override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException("Not Used") + /** + * Set it to false if you want to disable the extension reporting the view count + * back to the source website through admin-ajax.php. + */ + protected open val sendViewCount: Boolean = true + + protected open fun countViewsRequest(document: Document): Request? { + val wpMangaData = document.select("script:containsData(dynamic_view_ajax)").firstOrNull() + ?.data() ?: return null + + val postId = CHAPTER_PAGE_ID_REGEX.find(wpMangaData)?.groupValues?.get(1) + ?: MANGA_PAGE_ID_REGEX.find(wpMangaData)?.groupValues?.get(1) + ?: return null + + val formBody = FormBody.Builder() + .add("action", "dynamic_view_ajax") + .add("post_id", postId) + .build() + + val newHeaders = headersBuilder() + .set("Content-Length", formBody.contentLength().toString()) + .set("Content-Type", formBody.contentType().toString()) + .set("Referer", document.location()) + .build() + + return POST("$baseUrl/wp-admin/admin-ajax.php", newHeaders, formBody) + } + + /** + * Send the view count request to the Madara endpoint. + * + * @param document The response document with the wp-manga data + */ + protected open fun countViews(document: Document) { + if (!sendViewCount) { + return + } + + val request = countViewsRequest(document) ?: return + runCatching { client.newCall(request).execute().close() } + } + private interface UrlEncoded { fun encode(url: HttpUrl.Builder) } @@ -379,5 +425,8 @@ abstract class WPMangaReader( companion object { const val URL_SEARCH_PREFIX = "url:" + + private val MANGA_PAGE_ID_REGEX = "post_id\\s*:\\s*(\\d+)\\}".toRegex() + private val CHAPTER_PAGE_ID_REGEX = "post_id\\s*=\\s*(\\d+);?".toRegex() } } diff --git a/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/wpmangareader/WPMangaReaderGenerator.kt b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/wpmangareader/WPMangaReaderGenerator.kt index 768014ca1..645666a33 100644 --- a/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/wpmangareader/WPMangaReaderGenerator.kt +++ b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/wpmangareader/WPMangaReaderGenerator.kt @@ -9,7 +9,7 @@ class WPMangaReaderGenerator : ThemeSourceGenerator { override val themeClass = "WPMangaReader" - override val baseVersionCode: Int = 9 + override val baseVersionCode: Int = 10 override val sources = listOf( SingleLang("Anitation Arts", "https://anitationarts.org", "en", overrideVersionCode = 1), diff --git a/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/wpmangastream/WPMangaStream.kt b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/wpmangastream/WPMangaStream.kt index 54abe6cc6..4af6e3051 100644 --- a/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/wpmangastream/WPMangaStream.kt +++ b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/wpmangastream/WPMangaStream.kt @@ -3,6 +3,7 @@ package eu.kanade.tachiyomi.multisrc.wpmangastream import android.app.Application import android.content.SharedPreferences import eu.kanade.tachiyomi.network.GET +import eu.kanade.tachiyomi.network.POST import eu.kanade.tachiyomi.source.ConfigurableSource import eu.kanade.tachiyomi.source.model.Filter import eu.kanade.tachiyomi.source.model.FilterList @@ -14,6 +15,7 @@ import eu.kanade.tachiyomi.util.asJsoup import kotlinx.serialization.json.Json import kotlinx.serialization.json.jsonArray import kotlinx.serialization.json.jsonPrimitive +import okhttp3.FormBody import okhttp3.Headers import okhttp3.HttpUrl.Companion.toHttpUrl import okhttp3.HttpUrl.Companion.toHttpUrlOrNull @@ -39,14 +41,6 @@ abstract class WPMangaStream( ) : ConfigurableSource, ParsedHttpSource() { override val supportsLatest = true - companion object { - private const val MID_QUALITY = 1 - private const val LOW_QUALITY = 2 - - private const val SHOW_THUMBNAIL_PREF_Title = "Default thumbnail quality" - private const val SHOW_THUMBNAIL_PREF = "showThumbnailDefault" - } - private val preferences: SharedPreferences by lazy { Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000) } @@ -210,6 +204,8 @@ abstract class WPMangaStream( val checkChapter = document.select(chapterListSelector()).firstOrNull() if (date != "" && checkChapter != null) chapters[0].date_upload = parseDate(date) + countViews(document) + return chapters } @@ -296,6 +292,8 @@ abstract class WPMangaStream( htmlPages += scriptPages } + countViews(document) + return htmlPages.distinctBy { it.imageUrl } } @@ -327,6 +325,48 @@ abstract class WPMangaStream( } } + /** + * Set it to false if you want to disable the extension reporting the view count + * back to the source website through admin-ajax.php. + */ + protected open val sendViewCount: Boolean = true + + protected open fun countViewsRequest(document: Document): Request? { + val wpMangaData = document.select("script:containsData(dynamic_view_ajax)").firstOrNull() + ?.data() ?: return null + + val postId = CHAPTER_PAGE_ID_REGEX.find(wpMangaData)?.groupValues?.get(1) + ?: MANGA_PAGE_ID_REGEX.find(wpMangaData)?.groupValues?.get(1) + ?: return null + + val formBody = FormBody.Builder() + .add("action", "dynamic_view_ajax") + .add("post_id", postId) + .build() + + val newHeaders = headersBuilder() + .set("Content-Length", formBody.contentLength().toString()) + .set("Content-Type", formBody.contentType().toString()) + .set("Referer", document.location()) + .build() + + return POST("$baseUrl/wp-admin/admin-ajax.php", newHeaders, formBody) + } + + /** + * Send the view count request to the Madara endpoint. + * + * @param document The response document with the wp-manga data + */ + protected open fun countViews(document: Document) { + if (!sendViewCount) { + return + } + + val request = countViewsRequest(document) ?: return + runCatching { client.newCall(request).execute().close() } + } + private class AuthorFilter : Filter.Text("Author") private class YearFilter : Filter.Text("Year") @@ -476,4 +516,15 @@ abstract class WPMangaStream( Filter.Select<String>(displayName, vals.map { it.first }.toTypedArray()) { fun toUriPart() = vals[state].second } + + companion object { + private const val MID_QUALITY = 1 + private const val LOW_QUALITY = 2 + + private const val SHOW_THUMBNAIL_PREF_Title = "Default thumbnail quality" + private const val SHOW_THUMBNAIL_PREF = "showThumbnailDefault" + + private val MANGA_PAGE_ID_REGEX = "post_id\\s*:\\s*(\\d+)\\}".toRegex() + private val CHAPTER_PAGE_ID_REGEX = "chapter_id\\s*=\\s*(\\d+);?".toRegex() + } } diff --git a/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/wpmangastream/WPMangaStreamGenerator.kt b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/wpmangastream/WPMangaStreamGenerator.kt index aa737a1f6..df299cc54 100644 --- a/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/wpmangastream/WPMangaStreamGenerator.kt +++ b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/wpmangastream/WPMangaStreamGenerator.kt @@ -9,7 +9,7 @@ class WPMangaStreamGenerator : ThemeSourceGenerator { override val themeClass = "WPMangaStream" - override val baseVersionCode: Int = 10 + override val baseVersionCode: Int = 11 override val sources = listOf( SingleLang("Asura Scans", "https://www.asurascans.com", "en", overrideVersionCode = 5),