diff --git a/multisrc/overrides/wpmangastream/default/AndroidManifest.xml b/multisrc/overrides/wpmangastream/default/AndroidManifest.xml
new file mode 100644
index 000000000..3642d357f
--- /dev/null
+++ b/multisrc/overrides/wpmangastream/default/AndroidManifest.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
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 4af6e3051..07df47824 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
@@ -4,9 +4,11 @@ import android.app.Application
import android.content.SharedPreferences
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.POST
+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.FilterList
+import eu.kanade.tachiyomi.source.model.MangasPage
import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga
@@ -17,6 +19,7 @@ import kotlinx.serialization.json.jsonArray
import kotlinx.serialization.json.jsonPrimitive
import okhttp3.FormBody
import okhttp3.Headers
+import okhttp3.HttpUrl
import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.OkHttpClient
@@ -25,6 +28,8 @@ import okhttp3.Response
import org.jsoup.nodes.Document
import org.jsoup.nodes.Element
import org.jsoup.select.Elements
+import rx.Observable
+import rx.Single
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import uy.kohesive.injekt.injectLazy
@@ -82,6 +87,60 @@ abstract class WPMangaStream(
return GET("$baseUrl/manga/?page=$page&order=update", headers)
}
+ /**
+ * Given some string which represents an http url, returns the URI path to the corresponding series
+ * if the original pointed to either a series or a chapter
+ *
+ * @param s: String - url
+ *
+ * @returns URI path or null
+ */
+ protected open fun mangaPathFromUrl(s: String): Single {
+ val baseMangaUrl = baseUrl.toHttpUrlOrNull()!!
+ // Would be dope if wpmangastream had a mangaUrlDirectory like wpmangareader
+ val mangaDirectories = listOf("manga", "comics", "komik")
+ return s.toHttpUrlOrNull()?.let { url ->
+ fun pathLengthIs(url: HttpUrl, n: Int, strict: Boolean = false) = url.pathSegments.size == n && url.pathSegments[n - 1].isNotEmpty() || (!strict && url.pathSegments.size == n + 1 && url.pathSegments[n].isEmpty())
+ val potentiallyChapterUrl = pathLengthIs(url, 1)
+ val isMangaUrl = listOf(
+ baseMangaUrl.topPrivateDomain() == url.topPrivateDomain(),
+ pathLengthIs(url, 2),
+ url.pathSegments[0] in mangaDirectories
+ ).all { it }
+ if (isMangaUrl)
+ Single.just(url.encodedPath)
+ else if (potentiallyChapterUrl)
+ client.newCall(GET(s, headers)).asObservableSuccess().map {
+ val links = it.asJsoup().select("a[itemprop=item]")
+ if (links.size == 3) // near the top of page: home > manga > current chapter
+ links[1].attr("href").toHttpUrlOrNull()?.encodedPath
+ else
+ null
+ }.toSingle()
+ else
+ Single.just(null)
+ } ?: Single.just(null)
+ }
+
+ override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable {
+ if (!query.startsWith(URL_SEARCH_PREFIX))
+ return super.fetchSearchManga(page, query, filters)
+
+ return mangaPathFromUrl(query.substringAfter(URL_SEARCH_PREFIX))
+ .toObservable()
+ .concatMap { path ->
+ if (path == null)
+ Observable.just(MangasPage(emptyList(), false))
+ else
+ fetchMangaDetails(SManga.create().apply { this.url = path })
+ .map {
+ it.url = path // isn't set in returned manga
+ MangasPage(listOf(it), false)
+ }
+ }
+ }
+
+
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
var url = "$baseUrl/manga/".toHttpUrlOrNull()!!.newBuilder()
url.addQueryParameter("title", query)
@@ -218,7 +277,8 @@ abstract class WPMangaStream(
val chapter = SChapter.create()
chapter.setUrlWithoutDomain(urlElement.attr("href"))
chapter.name = if (urlElement.select("span.chapternum").isNotEmpty()) urlElement.select("span.chapternum").text() else urlElement.text()
- chapter.date_upload = element.select("span.rightoff, time, span.chapterdate").firstOrNull()?.text()?.let { parseChapterDate(it) } ?: 0
+ chapter.date_upload = element.select("span.rightoff, time, span.chapterdate").firstOrNull()?.text()?.let { parseChapterDate(it) }
+ ?: 0
return chapter
}
@@ -524,6 +584,8 @@ abstract class WPMangaStream(
private const val SHOW_THUMBNAIL_PREF_Title = "Default thumbnail quality"
private const val SHOW_THUMBNAIL_PREF = "showThumbnailDefault"
+ const val URL_SEARCH_PREFIX = "url:"
+
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 646ef6579..a796f4afe 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
@@ -10,7 +10,7 @@ class WPMangaStreamGenerator : ThemeSourceGenerator {
override val themeClass = "WPMangaStream"
- override val baseVersionCode: Int = 11
+ override val baseVersionCode: Int = 12
override val sources = listOf(
MultiLang("Asura Scans", "https://www.asurascans.com", listOf("en", "tr"), className = "AsuraScansFactory", pkgName = "asurascans", overrideVersionCode = 6),
diff --git a/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/wpmangastream/WPMangaStreamUrlActivity.kt b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/wpmangastream/WPMangaStreamUrlActivity.kt
new file mode 100644
index 000000000..2e145cf09
--- /dev/null
+++ b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/wpmangastream/WPMangaStreamUrlActivity.kt
@@ -0,0 +1,35 @@
+package eu.kanade.tachiyomi.multisrc.wpmangastream
+
+import android.app.Activity
+import android.content.ActivityNotFoundException
+import android.content.Intent
+import android.os.Bundle
+import android.util.Log
+import kotlin.system.exitProcess
+
+class WPMangaStreamUrlActivity : Activity() {
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ val pathSegments = intent?.data?.pathSegments
+
+ if (pathSegments != null && pathSegments.size >= 1) {
+
+ val mainIntent = Intent().apply {
+ action = "eu.kanade.tachiyomi.SEARCH"
+ putExtra("query", "${WPMangaStream.URL_SEARCH_PREFIX}${intent?.data?.toString()}")
+ putExtra("filter", packageName)
+ }
+ try {
+ startActivity(mainIntent)
+ } catch (e: ActivityNotFoundException) {
+ Log.e("WPMangaStreamUrl", e.toString())
+ }
+ } else {
+ Log.e("WPMangaStreamUrl", "could not parse uri from intent $intent")
+ }
+
+ finish()
+ exitProcess(0)
+ }
+}