update libraries
* kotlinx-coroutines-android 1.5.1 -> 1.5.2 * exoplayer 2.14.2 -> 2.15.0 * jsoup 1.13.1 -> 1.14.2 * gradle agp 7.0.1 -> 7.0.2
This commit is contained in:
parent
39e740cd92
commit
3935f37267
|
@ -11,7 +11,7 @@ android {
|
||||||
minSdkVersion 23
|
minSdkVersion 23
|
||||||
targetSdkVersion 30
|
targetSdkVersion 30
|
||||||
versionCode 4200 //00.04.200
|
versionCode 4200 //00.04.200
|
||||||
versionName "0.5.0-alpha1"
|
versionName "0.5.0-alpha2"
|
||||||
|
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
resValue "string", "build_time", buildTime()
|
resValue "string", "build_time", buildTime()
|
||||||
|
@ -41,8 +41,8 @@ android {
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation fileTree(dir: "libs", include: ["*.jar"])
|
implementation fileTree(dir: "libs", include: ["*.jar"])
|
||||||
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
|
||||||
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.1'
|
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.2'
|
||||||
|
|
||||||
implementation 'androidx.core:core-ktx:1.6.0'
|
implementation 'androidx.core:core-ktx:1.6.0'
|
||||||
implementation 'androidx.appcompat:appcompat:1.3.1'
|
implementation 'androidx.appcompat:appcompat:1.3.1'
|
||||||
|
@ -55,14 +55,14 @@ dependencies {
|
||||||
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1'
|
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1'
|
||||||
|
|
||||||
implementation 'com.google.android.material:material:1.4.0'
|
implementation 'com.google.android.material:material:1.4.0'
|
||||||
implementation 'com.google.code.gson:gson:2.8.7'
|
implementation 'com.google.code.gson:gson:2.8.8'
|
||||||
implementation 'com.google.android.exoplayer:exoplayer-core:2.14.2'
|
implementation 'com.google.android.exoplayer:exoplayer-core:2.15.0'
|
||||||
implementation 'com.google.android.exoplayer:exoplayer-hls:2.14.2'
|
implementation 'com.google.android.exoplayer:exoplayer-hls:2.15.0'
|
||||||
implementation 'com.google.android.exoplayer:exoplayer-dash:2.14.2'
|
implementation 'com.google.android.exoplayer:exoplayer-dash:2.15.0'
|
||||||
implementation 'com.google.android.exoplayer:exoplayer-ui:2.14.2'
|
implementation 'com.google.android.exoplayer:exoplayer-ui:2.15.0'
|
||||||
implementation 'com.google.android.exoplayer:extension-mediasession:2.14.2'
|
implementation 'com.google.android.exoplayer:extension-mediasession:2.15.0'
|
||||||
|
|
||||||
implementation 'org.jsoup:jsoup:1.13.1'
|
implementation 'org.jsoup:jsoup:1.14.2'
|
||||||
implementation 'com.github.bumptech.glide:glide:4.12.0'
|
implementation 'com.github.bumptech.glide:glide:4.12.0'
|
||||||
implementation 'jp.wasabeef:glide-transformations:4.3.0'
|
implementation 'jp.wasabeef:glide-transformations:4.3.0'
|
||||||
implementation 'com.afollestad.material-dialogs:core:3.3.0'
|
implementation 'com.afollestad.material-dialogs:core:3.3.0'
|
||||||
|
|
|
@ -31,8 +31,10 @@ import org.mosad.teapod.preferences.EncryptedPreferences
|
||||||
import org.mosad.teapod.util.*
|
import org.mosad.teapod.util.*
|
||||||
import org.mosad.teapod.util.DataTypes.MediaType
|
import org.mosad.teapod.util.DataTypes.MediaType
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
|
import java.net.CookieStore
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.random.Random
|
import kotlin.random.Random
|
||||||
|
import kotlin.reflect.jvm.jvmName
|
||||||
|
|
||||||
object AoDParser {
|
object AoDParser {
|
||||||
|
|
||||||
|
@ -43,7 +45,7 @@ object AoDParser {
|
||||||
|
|
||||||
private const val userAgent = "Mozilla/5.0 (X11; Linux x86_64; rv:84.0) Gecko/20100101 Firefox/84.0"
|
private const val userAgent = "Mozilla/5.0 (X11; Linux x86_64; rv:84.0) Gecko/20100101 Firefox/84.0"
|
||||||
|
|
||||||
private var sessionCookies = mutableMapOf<String, String>()
|
private lateinit var cookieStore: CookieStore
|
||||||
private var csrfToken: String = ""
|
private var csrfToken: String = ""
|
||||||
private var loginSuccess = false
|
private var loginSuccess = false
|
||||||
|
|
||||||
|
@ -60,23 +62,22 @@ object AoDParser {
|
||||||
fun login(): Boolean = runBlocking {
|
fun login(): Boolean = runBlocking {
|
||||||
|
|
||||||
withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) {
|
||||||
// get the authenticity token
|
// get the authenticity token and cookies
|
||||||
val resAuth = Jsoup.connect(baseUrl + loginPath)
|
val conAuth = Jsoup.connect(baseUrl + loginPath)
|
||||||
.header("User-Agent", userAgent)
|
.header("User-Agent", userAgent)
|
||||||
.execute()
|
|
||||||
|
|
||||||
val authenticityToken = resAuth.parse().select("meta[name=csrf-token]").attr("content")
|
cookieStore = conAuth.cookieStore()
|
||||||
val authCookies = resAuth.cookies()
|
csrfToken = conAuth.execute().parse().select("meta[name=csrf-token]").attr("content")
|
||||||
|
|
||||||
//Log.d(javaClass.name, "Received authenticity token: $authenticityToken")
|
Log.d(AoDParser::class.jvmName, "Received authenticity token: $csrfToken")
|
||||||
//Log.d(javaClass.name, "Received authenticity cookies: $authCookies")
|
Log.d(AoDParser::class.jvmName, "Received authenticity cookies: $cookieStore")
|
||||||
|
|
||||||
val data = mapOf(
|
val data = mapOf(
|
||||||
Pair("user[login]", EncryptedPreferences.login),
|
Pair("user[login]", EncryptedPreferences.login),
|
||||||
Pair("user[password]", EncryptedPreferences.password),
|
Pair("user[password]", EncryptedPreferences.password),
|
||||||
Pair("user[remember_me]", "1"),
|
Pair("user[remember_me]", "1"),
|
||||||
Pair("commit", "Einloggen"),
|
Pair("commit", "Einloggen"),
|
||||||
Pair("authenticity_token", authenticityToken)
|
Pair("authenticity_token", csrfToken)
|
||||||
)
|
)
|
||||||
|
|
||||||
val resLogin = Jsoup.connect(baseUrl + loginPath)
|
val resLogin = Jsoup.connect(baseUrl + loginPath)
|
||||||
|
@ -84,14 +85,12 @@ object AoDParser {
|
||||||
.timeout(60000) // login can take some time default is 60000 (60 sec)
|
.timeout(60000) // login can take some time default is 60000 (60 sec)
|
||||||
.data(data)
|
.data(data)
|
||||||
.postDataCharset("UTF-8")
|
.postDataCharset("UTF-8")
|
||||||
.cookies(authCookies)
|
.cookieStore(cookieStore)
|
||||||
.execute()
|
.execute()
|
||||||
|
|
||||||
//println(resLogin.body())
|
//println(resLogin.body())
|
||||||
|
|
||||||
sessionCookies = resLogin.cookies()
|
|
||||||
loginSuccess = resLogin.body().contains("Hallo, du bist jetzt angemeldet.")
|
loginSuccess = resLogin.body().contains("Hallo, du bist jetzt angemeldet.")
|
||||||
Log.i(javaClass.name, "Status: ${resLogin.statusCode()} (${resLogin.statusMessage()}), login successful: $loginSuccess")
|
Log.i(AoDParser::class.jvmName, "Status: ${resLogin.statusCode()} (${resLogin.statusMessage()}), login successful: $loginSuccess")
|
||||||
|
|
||||||
loginSuccess
|
loginSuccess
|
||||||
}
|
}
|
||||||
|
@ -119,7 +118,7 @@ object AoDParser {
|
||||||
aodMediaList.add(this)
|
aodMediaList.add(this)
|
||||||
}
|
}
|
||||||
} catch (exn:NullPointerException) {
|
} catch (exn:NullPointerException) {
|
||||||
Log.e(javaClass.name, "Error while loading media $aodId", exn)
|
Log.e(AoDParser::class.jvmName, "Error while loading media $aodId", exn)
|
||||||
AoDMediaNone
|
AoDMediaNone
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -131,7 +130,7 @@ object AoDParser {
|
||||||
return coroutineScope {
|
return coroutineScope {
|
||||||
async(Dispatchers.IO) {
|
async(Dispatchers.IO) {
|
||||||
val res = Jsoup.connect(baseUrl + subscriptionPath)
|
val res = Jsoup.connect(baseUrl + subscriptionPath)
|
||||||
.cookies(sessionCookies)
|
.cookieStore(cookieStore)
|
||||||
.get()
|
.get()
|
||||||
|
|
||||||
return@async res.select("a:contains(Anime-Abo)").text()
|
return@async res.select("a:contains(Anime-Abo)").text()
|
||||||
|
@ -149,7 +148,7 @@ object AoDParser {
|
||||||
episode.watched = true
|
episode.watched = true
|
||||||
sendCallback(episode.watchedCallback)
|
sendCallback(episode.watchedCallback)
|
||||||
|
|
||||||
Log.d(javaClass.name, "Marked episode ${episode.mediaId} as watched")
|
Log.d(AoDParser::class.jvmName, "Marked episode ${episode.mediaId} as watched")
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO don't use jsoup here
|
// TODO don't use jsoup here
|
||||||
|
@ -166,11 +165,11 @@ object AoDParser {
|
||||||
try {
|
try {
|
||||||
Jsoup.connect(baseUrl + callbackPath)
|
Jsoup.connect(baseUrl + callbackPath)
|
||||||
.ignoreContentType(true)
|
.ignoreContentType(true)
|
||||||
.cookies(sessionCookies)
|
.cookieStore(cookieStore)
|
||||||
.headers(headers)
|
.headers(headers)
|
||||||
.execute()
|
.execute()
|
||||||
} catch (ex: IOException) {
|
} catch (ex: IOException) {
|
||||||
Log.e(javaClass.name, "Callback for $callbackPath failed.", ex)
|
Log.e(AoDParser::class.jvmName, "Callback for $callbackPath failed.", ex)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -199,7 +198,7 @@ object AoDParser {
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
Log.i(javaClass.name, "Total library size is: ${guiMediaList.size}")
|
Log.i(AoDParser::class.jvmName, "Total library size is: ${guiMediaList.size}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -284,7 +283,7 @@ object AoDParser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.i(javaClass.name, "loaded home")
|
Log.i(AoDParser::class.jvmName, "loaded home")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -295,27 +294,27 @@ object AoDParser {
|
||||||
*/
|
*/
|
||||||
private suspend fun loadMediaAsync(aodId: Int): Deferred<AoDMedia> = coroutineScope {
|
private suspend fun loadMediaAsync(aodId: Int): Deferred<AoDMedia> = coroutineScope {
|
||||||
return@coroutineScope async (Dispatchers.IO) {
|
return@coroutineScope async (Dispatchers.IO) {
|
||||||
if (sessionCookies.isEmpty()) login() // TODO is this needed?
|
if (cookieStore.cookies.isEmpty()) login() // TODO is this needed?
|
||||||
|
|
||||||
// return none object, if login wasn't successful
|
// return none object, if login wasn't successful
|
||||||
if (!loginSuccess) {
|
if (!loginSuccess) {
|
||||||
Log.w(javaClass.name, "Login was not successful")
|
Log.w(AoDParser::class.jvmName, "Login was not successful")
|
||||||
return@async AoDMediaNone
|
return@async AoDMediaNone
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the media page
|
// get the media page
|
||||||
val res = Jsoup.connect("$baseUrl/anime/$aodId")
|
val res = Jsoup.connect("$baseUrl/anime/$aodId")
|
||||||
.cookies(sessionCookies)
|
.cookieStore(cookieStore)
|
||||||
.get()
|
.get()
|
||||||
// println(res)
|
// println(res)
|
||||||
|
|
||||||
if (csrfToken.isEmpty()) {
|
if (csrfToken.isEmpty()) {
|
||||||
csrfToken = res.select("meta[name=csrf-token]").attr("content")
|
csrfToken = res.select("meta[name=csrf-token]").attr("content")
|
||||||
Log.d(javaClass.name, "New csrf token is $csrfToken")
|
Log.d(AoDParser::class.jvmName, "New csrf token is $csrfToken")
|
||||||
}
|
}
|
||||||
|
|
||||||
// playlist parsing TODO can this be async to the general info parsing?
|
// playlist parsing TODO can this be async to the general info parsing?
|
||||||
val besides = res.select("div.besides").first()
|
val besides = res.select("div.besides").first()!!
|
||||||
val aodPlaylists = besides.select("input.streamstarter_html5").map { streamstarter ->
|
val aodPlaylists = besides.select("input.streamstarter_html5").map { streamstarter ->
|
||||||
parsePlaylistAsync(
|
parsePlaylistAsync(
|
||||||
streamstarter.attr("data-playlist"),
|
streamstarter.attr("data-playlist"),
|
||||||
|
@ -354,7 +353,7 @@ object AoDParser {
|
||||||
if (mediaId != null) {
|
if (mediaId != null) {
|
||||||
ItemMedia(mediaId, mediaTitle, mediaImage)
|
ItemMedia(mediaId, mediaTitle, mediaImage)
|
||||||
} else {
|
} else {
|
||||||
Log.i(javaClass.name, "MediaId for similar to $aodId was null")
|
Log.i(AoDParser::class.jvmName, "MediaId for similar to $aodId was null")
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -376,7 +375,7 @@ object AoDParser {
|
||||||
|
|
||||||
AoDEpisodeInfo(mediaId, episodeShortDesc, episodeWatched, episodeWatchedCallback)
|
AoDEpisodeInfo(mediaId, episodeShortDesc, episodeWatched, episodeWatchedCallback)
|
||||||
} else {
|
} else {
|
||||||
Log.i(javaClass.name, "Episode info for $aodId has empty streamstarter_html5 ")
|
Log.i(AoDParser::class.jvmName, "Episode info for $aodId has empty streamstarter_html5 ")
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
}.associateBy { it.aodMediaId }
|
}.associateBy { it.aodMediaId }
|
||||||
|
@ -441,7 +440,7 @@ object AoDParser {
|
||||||
|
|
||||||
val res = Jsoup.connect(baseUrl + playlistPath)
|
val res = Jsoup.connect(baseUrl + playlistPath)
|
||||||
.ignoreContentType(true)
|
.ignoreContentType(true)
|
||||||
.cookies(sessionCookies)
|
.cookieStore(cookieStore)
|
||||||
.headers(headers)
|
.headers(headers)
|
||||||
.timeout(120000) // loading the playlist can take some time
|
.timeout(120000) // loading the playlist can take some time
|
||||||
.execute()
|
.execute()
|
||||||
|
|
|
@ -16,9 +16,7 @@
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="center"
|
||||||
android:animateLayoutChanges="true"
|
android:animateLayoutChanges="true"
|
||||||
android:foreground="@drawable/ripple_background"
|
android:foreground="@drawable/ripple_background"
|
||||||
app:controller_layout_id="@layout/player_controls"
|
app:controller_layout_id="@layout/player_controls" />
|
||||||
app:fastforward_increment="10000"
|
|
||||||
app:rewind_increment="10000" />
|
|
||||||
|
|
||||||
<com.google.android.material.progressindicator.CircularProgressIndicator
|
<com.google.android.material.progressindicator.CircularProgressIndicator
|
||||||
android:id="@+id/loading"
|
android:id="@+id/loading"
|
||||||
|
|
|
@ -6,7 +6,7 @@ buildscript {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:7.0.1'
|
classpath 'com.android.tools.build:gradle:7.0.2'
|
||||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||||
|
|
||||||
// NOTE: Do not place your application dependencies here; they belong
|
// NOTE: Do not place your application dependencies here; they belong
|
||||||
|
|
Loading…
Reference in New Issue