Skip to content

Commit

Permalink
- added deep linking for urls!
Browse files Browse the repository at this point in the history
  • Loading branch information
jakepurple13 committed Apr 28, 2021
1 parent 4ff12be commit b103250
Show file tree
Hide file tree
Showing 14 changed files with 271 additions and 46 deletions.
3 changes: 3 additions & 0 deletions Models/src/main/java/com/programmersbox/models/Models.kt
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,11 @@ interface ApiService: Serializable {
fun getItemInfo(model: ItemModel): Single<InfoModel>
fun searchList(searchText: CharSequence, page: Int = 1, list: List<ItemModel>): Single<List<ItemModel>> =
Single.create { it.onSuccess(list.filter { it.title.contains(searchText, true) }) }

fun getChapterInfo(chapterModel: ChapterModel): Single<List<Storage>>

suspend fun getSourceByUrl(url: String): ItemModel? = ItemModel("", "", "", "", this)

val serviceName: String get() = this::class.java.name
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.programmersbox.uiviews

import android.os.Bundle
import android.webkit.URLUtil
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.LiveData
import androidx.navigation.NavController
Expand Down Expand Up @@ -37,6 +38,19 @@ abstract class BaseMainActivity : AppCompatActivity(), GenericInfo {
}

onCreate()

intent.data?.let {
if (URLUtil.isValidUrl(it.toString())) {
currentService?.let { it1 ->
GlobalScope.launch {
genericInfo.toSource(it1)?.getSourceByUrl(it.toString())?.let { it2 ->
runOnUiThread { currentNavController?.value?.navigate(RecentFragmentDirections.actionRecentFragment2ToDetailsFragment2(it2)) }
}
}
}
}
}

}

override fun onRestoreInstanceState(savedInstanceState: Bundle) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,30 @@ abstract class AnimeToon(allPath: String, recentPath: String) : ShowApi(
source = this
)

override suspend fun getSourceByUrl(url: String): ItemModel? = try {
val doc = Jsoup.connect(url).get()
ItemModel(
source = this,
url = url,
title = doc.select("div.right_col h1").text(),
description = doc.allElements.select("div#series_details").let { element ->
if (element.select("span#full_notes").hasText())
element.select("span#full_notes").text().removeSuffix("less")
else
element.select("div:contains(Description:)").select("div").text().let {
try {
it.substring(it.indexOf("Description: ") + 13, it.indexOf("Category: "))
} catch (e: StringIndexOutOfBoundsException) {
it
}
}
},
imageUrl = doc.select("div.left_col").select("img[src^=http]#series_image")?.attr("abs:src").orEmpty(),
)
} catch (e: Exception) {
null
}

override fun getList(doc: Document): Single<List<ItemModel>> = Single.create {
try {
it.onSuccess(doc.allElements.select("td").select("a[href^=http]").map(this::toShowInfo))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import com.programmersbox.models.ItemModel
import com.programmersbox.models.Storage
import com.programmersbox.rxutils.invoke
import io.reactivex.Single
import org.jsoup.Jsoup
import org.jsoup.nodes.Document
import java.net.URI

Expand Down Expand Up @@ -110,23 +111,36 @@ object GogoAnimeApi : ShowApi(
}
}

override suspend fun getSourceByUrl(url: String): ItemModel? = try {
val doc = Jsoup.connect(url).get()
ItemModel(
source = this,
title = doc.select("div.anime-title").text(),
url = url,
description = doc.select("p.anime-details").text(),
imageUrl = doc.select("div.animeDetail-image").select("img[src^=http]")?.attr("abs:src").orEmpty(),
)
} catch (e: Exception) {
null
}

override fun searchList(text: CharSequence, page: Int, list: List<ItemModel>): Single<List<ItemModel>> {
return Single.create { emitter ->
try {
if (text.isNotEmpty()) {
emitter.onSuccess(
getJsonApi<Base>("https://www.gogoanime1.com/search/topSearch?q=$text")
?.data
.orEmpty()
.map {
ItemModel(
title = it.name.orEmpty(),
description = "",
imageUrl = "",
url = "https://www.gogoanime1.com/watch/${it.seo_name}",
source = this
)
}
getJsonApi<Base>("https://www.gogoanime1.com/search/topSearch?q=$text")
?.data
.orEmpty()
.map {
ItemModel(
title = it.name.orEmpty(),
description = "",
imageUrl = "",
url = "https://www.gogoanime1.com/watch/${it.seo_name}",
source = this
)
}
)
} else {
emitter.onSuccess(searchListNonSingle(text, page, list))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
package com.programmersbox.anime_sources.anime

import androidx.core.text.isDigitsOnly
import com.programmersbox.gsonutils.fromJson
import com.programmersbox.gsonutils.toJson
import com.programmersbox.models.*
import com.programmersbox.thirdpartyutils.gsonConverter
import com.programmersbox.thirdpartyutils.rx2FactoryAsync
import io.reactivex.Single
import kotlinx.coroutines.suspendCancellableCoroutine
import okhttp3.*
import org.jsoup.Jsoup
import retrofit2.Retrofit
import retrofit2.create
import retrofit2.http.GET
import retrofit2.http.Query
import retrofit2.http.QueryMap
import java.io.IOException
import kotlin.coroutines.resumeWithException

object Yts : ApiService {

Expand All @@ -30,6 +36,91 @@ object Yts : ApiService {
).apply { extras["info"] = it.toJson() }
}

private suspend fun Call.await(): Response {
return suspendCancellableCoroutine { continuation ->
enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
if (continuation.isCancelled) return
continuation.resumeWithException(e)
}

override fun onResponse(call: Call, response: Response) {
continuation.resume(response) {}
}
})
continuation.invokeOnCancellation {
try {
cancel()
} catch (ex: Throwable) {
}
}
}
}

override suspend fun getSourceByUrl(url: String): ItemModel? {
try {
val subResponse = OkHttpClient().newCall((Request.Builder().url(url).build())).await()
if (!subResponse.isSuccessful) return null
val subDoc = Jsoup.parse(subResponse.body?.string())

subResponse.close() // Always close the response when not needed

val movieId = subDoc.getElementById("movie-info").attr("data-movie-id").toString().toInt()
var imdbCode = ""
var rating = 0.0
subDoc.getElementsByClass("rating-row").forEach { row ->
if (row.hasAttr("itemscope")) {
imdbCode = row.getElementsByClass("icon")[0].attr("href").toString().split("/")[4]
row.allElements.forEach { element ->
if (element.hasAttr("itemprop") && element.attr("itemprop").toString() == "ratingValue") {
rating = element.ownText().toDouble()
}
}
}
}

var title = ""
var year = 0
var bannerUrl = ""
var runtime = 0

subDoc.getElementById("mobile-movie-info").allElements.forEach {
if (it.hasAttr("itemprop"))
title = it.ownText()
else
if (it.ownText().isNotBlank() && it.ownText().isDigitsOnly())
year = it.ownText().toInt()
}

subDoc.getElementById("movie-poster").allElements.forEach {
if (it.hasAttr("itemprop"))
bannerUrl = it.attr("src").toString()
}

subDoc.getElementsByClass("icon-clock")[0]?.let {
val runtimeString = it.parent().ownText().trim()
if (runtimeString.contains("hr")) {
runtime = runtimeString.split("hr")[0].trim().toInt() * 60
if (runtimeString.contains("min"))
runtime += runtimeString.split(" ")[2].trim().toInt()
return@let
}
if (runtimeString.contains("min"))
runtime += runtimeString.split("min")[0].trim().toInt()
}

return ItemModel(
source = this,
imageUrl = bannerUrl,
url = url,
title = title,
description = ""
).apply { extras["info"] = service.getMovie(YTSQuery.MovieBuilder().setMovieId(movieId).build()).blockingGet()?.data?.movie.toJson() }
} catch (e: Exception) {
return null
}
}

override fun getRecent(page: Int): Single<List<ItemModel>> =
service.listMovies(YTSQuery.ListMoviesBuilder.getDefault().setPage(page).build())
.map { it.data?.movies?.map(movieToModel) }
Expand Down Expand Up @@ -118,8 +209,7 @@ class YTSQuery {
}

class MovieBuilder {
var vals: MutableMap<String, String> =
HashMap()
var vals: MutableMap<String, String> = HashMap()

/**
* The ID of the movie.
Expand Down Expand Up @@ -292,7 +382,7 @@ class YTSQuery {

data class Base(val status: String?, val status_message: String?, val data: Data?, val meta: String)

data class Data(val movie_count: Number?, val limit: Number?, val page_number: Number?, val movies: List<Movies>?)
data class Data(val movie_count: Number?, val limit: Number?, val page_number: Number?, val movies: List<Movies>?, val movie: Movies?)

data class Movies(
val id: Number?,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ package com.programmersbox.anime_sources

import com.programmersbox.anime_sources.anime.AnimeToonDubbed
import com.programmersbox.anime_sources.anime.WcoDubbed
import com.programmersbox.anime_sources.anime.YTSQuery
import com.programmersbox.anime_sources.anime.YtsService
import com.programmersbox.anime_sources.anime.Yts
import com.programmersbox.gsonutils.getApi
import com.programmersbox.models.ChapterModel
import com.programmersbox.models.InfoModel
Expand Down Expand Up @@ -41,7 +40,7 @@ class ExampleUnitTest {

@Test
fun addition_isCorrect() = runBlocking {
val f = YtsService.build()//getJsonApi<Base>("https://yts.mx/api/v2/list_movies.json")
/*val f = YtsService.build()//getJsonApi<Base>("https://yts.mx/api/v2/list_movies.json")
val f1 = f.listMovies(YTSQuery.ListMoviesBuilder.getDefault().setQuery("big bang").build())
val movies = f1?.blockingGet()?.data?.movies
println(movies?.joinToString("\n"))
Expand All @@ -50,7 +49,10 @@ class ExampleUnitTest {
YTSQuery.MovieBuilder().setMovieId(movies?.first()?.id?.toInt() ?: 30478).build()
)
println(m1.blockingGet())
println(m1.blockingGet())*/

val f = Yts.getSourceByUrl("https://yts.mx/movies/doing-time-1979")
println(f)

}

Expand Down
30 changes: 30 additions & 0 deletions animeworld/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,36 @@

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter android:label="View Anime">
<action android:name="android.intent.action.VIEW" />

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

<data android:scheme="http" />
<data android:scheme="https" />
<data
android:host="gogoanime1.com"
android:pathPrefix="/watch" />
<data
android:host="www.gogoanime1.com"
android:pathPrefix="/watch" />

<data
android:host="animetoon.org"
android:pathPrefix="/" />
<data
android:host="www.animetoon.org"
android:pathPrefix="/" />

<data
android:host="yts.mx"
android:pathPrefix="/movies" />
<data
android:host="www.yts.mx"
android:pathPrefix="/movies" />

</intent-filter>
</activity>

<receiver
Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
buildscript {
ext.kotlin_version = "1.5.0"
ext.jakepurple13 = "10.6.3"
ext.otakuVersionName = "9.5"
ext.otakuVersionName = "10.0"
ext.latestAboutLibsRelease = "+"
repositories {
google()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,18 +119,18 @@ object MangaFourLife : ApiService {
)
}

/*override fun getMangaModelByUrl(url: String): MangaModel {
override suspend fun getSourceByUrl(url: String): ItemModel {
val doc = Jsoup.connect(url).get()
val title = doc.select("li.list-group-item, li.d-none, li.d-sm-block").select("h1").text()
val description = doc.select("div.BoxBody > div.row").select("div.Content").text()
return MangaModel(
return ItemModel(
title = title,
description = description,
mangaUrl = url,
url = url,
imageUrl = doc.select("img.img-fluid, img.bottom-5").attr("abs:src"),
source = this
)
}*/
}

private fun chapterURLEncode(e: String): String {
var index = ""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,16 +139,18 @@ object MangaHere : ApiService {
}
}

/*override fun getMangaModelByUrl(url: String): MangaModel {
override suspend fun getSourceByUrl(url: String): ItemModel? = try {
val doc = Jsoup.connect(url).get()
return MangaModel(
ItemModel(
title = doc.select("span.detail-info-right-title-font").text(),
description = doc.select("p.fullcontent").text(),
mangaUrl = url,
url = url,
imageUrl = doc.select("img.detail-info-cover-img").select("img[src^=http]").attr("abs:src"),
source = this
)
}*/
} catch (e: Exception) {
null
}

override fun getChapterInfo(chapterModel: ChapterModel): Single<List<Storage>> = Single.create {
it.onSuccess(
Expand Down
Loading

0 comments on commit b103250

Please sign in to comment.