mirror of
https://github.com/videolan/vlc-android
synced 2024-11-23 09:56:36 +08:00
Save and display API limits
This commit is contained in:
parent
c263543970
commit
c49b081984
@ -1,7 +1,7 @@
|
|||||||
package org.videolan.resources.opensubtitles
|
package org.videolan.resources.opensubtitles
|
||||||
|
|
||||||
import com.squareup.moshi.Json
|
import com.squareup.moshi.Json
|
||||||
import com.squareup.moshi.JsonClass
|
import java.util.Date
|
||||||
|
|
||||||
data class OpenSubV1(
|
data class OpenSubV1(
|
||||||
@field:Json(name = "data")
|
@field:Json(name = "data")
|
||||||
@ -156,7 +156,7 @@ data class DownloadLink(
|
|||||||
@field:Json(name = "reset_time")
|
@field:Json(name = "reset_time")
|
||||||
val resetTime: String,
|
val resetTime: String,
|
||||||
@field:Json(name = "reset_time_utc")
|
@field:Json(name = "reset_time_utc")
|
||||||
val resetTimeUtc: String
|
val resetTimeUtc: Date
|
||||||
)
|
)
|
||||||
|
|
||||||
data class OpenSubtitleAccount(
|
data class OpenSubtitleAccount(
|
||||||
|
@ -3,6 +3,8 @@ package org.videolan.resources.opensubtitles
|
|||||||
import android.util.Log
|
import android.util.Log
|
||||||
import com.moczul.ok2curl.CurlInterceptor
|
import com.moczul.ok2curl.CurlInterceptor
|
||||||
import com.moczul.ok2curl.logger.Logger
|
import com.moczul.ok2curl.logger.Logger
|
||||||
|
import com.squareup.moshi.Moshi
|
||||||
|
import com.squareup.moshi.adapters.Rfc3339DateJsonAdapter
|
||||||
import okhttp3.Interceptor
|
import okhttp3.Interceptor
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
@ -13,6 +15,7 @@ import org.videolan.resources.BuildConfig
|
|||||||
import org.videolan.resources.util.ConnectivityInterceptor
|
import org.videolan.resources.util.ConnectivityInterceptor
|
||||||
import retrofit2.Retrofit
|
import retrofit2.Retrofit
|
||||||
import retrofit2.converter.moshi.MoshiConverterFactory
|
import retrofit2.converter.moshi.MoshiConverterFactory
|
||||||
|
import java.util.Date
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
|
|
||||||
@ -35,7 +38,11 @@ private fun buildClient() = Retrofit.Builder()
|
|||||||
.readTimeout(10, TimeUnit.SECONDS)
|
.readTimeout(10, TimeUnit.SECONDS)
|
||||||
.connectTimeout(5, TimeUnit.SECONDS)
|
.connectTimeout(5, TimeUnit.SECONDS)
|
||||||
.build())
|
.build())
|
||||||
.addConverterFactory(MoshiConverterFactory.create())
|
.addConverterFactory(MoshiConverterFactory.create(
|
||||||
|
Moshi.Builder()
|
||||||
|
.add(Date::class.java, Rfc3339DateJsonAdapter().nullSafe())
|
||||||
|
.build()
|
||||||
|
))
|
||||||
.build()
|
.build()
|
||||||
.create(IOpenSubtitleService::class.java)
|
.create(IOpenSubtitleService::class.java)
|
||||||
|
|
||||||
|
@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* ************************************************************************
|
||||||
|
* OpenSubtitlesLimit.kt
|
||||||
|
* *************************************************************************
|
||||||
|
* Copyright © 2024 VLC authors and VideoLAN
|
||||||
|
* Author: Nicolas POMEPUY
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
|
||||||
|
* **************************************************************************
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package main.java.org.videolan.resources.opensubtitles
|
||||||
|
|
||||||
|
import java.util.Date
|
||||||
|
|
||||||
|
data class OpenSubtitlesLimit (
|
||||||
|
val requests: Int = 0,
|
||||||
|
val max: Int = 5,
|
||||||
|
val resetTime: Date? = null
|
||||||
|
) {
|
||||||
|
private fun getRemaining(): Int {
|
||||||
|
if (resetTime != null && Date().after(resetTime)) return max
|
||||||
|
return max - requests
|
||||||
|
}
|
||||||
|
fun getRemainingText(): String {
|
||||||
|
val remaining = getRemaining()
|
||||||
|
return "$remaining/$max"
|
||||||
|
}
|
||||||
|
}
|
@ -39,26 +39,4 @@ data class OpenSubtitlesUser(
|
|||||||
val errorMessage: String? = null
|
val errorMessage: String? = null
|
||||||
) {
|
) {
|
||||||
fun isVip() = account?.user?.vip ?: false
|
fun isVip() = account?.user?.vip ?: false
|
||||||
}
|
|
||||||
|
|
||||||
object OpenSubtitlesUserUtil {
|
|
||||||
fun get(settings: SharedPreferences): OpenSubtitlesUser {
|
|
||||||
settings.getString(KEY_OPEN_SUBTITLES_USER, "")?.let { userString ->
|
|
||||||
val moshi = Moshi.Builder().build()
|
|
||||||
val type = Types.newParameterizedType(OpenSubtitlesUser::class.java)
|
|
||||||
val jsonAdapter: JsonAdapter<OpenSubtitlesUser> = moshi.adapter(type)
|
|
||||||
return try {
|
|
||||||
jsonAdapter.fromJson(userString) ?: OpenSubtitlesUser()
|
|
||||||
} catch (e: Exception) {
|
|
||||||
OpenSubtitlesUser()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return OpenSubtitlesUser()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun save(settings: SharedPreferences, user: OpenSubtitlesUser) {
|
|
||||||
val moshi = Moshi.Builder().build()
|
|
||||||
val jsonAdapter = moshi.adapter(OpenSubtitlesUser::class.java)
|
|
||||||
settings.putSingle(KEY_OPEN_SUBTITLES_USER, jsonAdapter.toJson(user))
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -0,0 +1,83 @@
|
|||||||
|
/*
|
||||||
|
* ************************************************************************
|
||||||
|
* OpenSubtitlesUtils.kt
|
||||||
|
* *************************************************************************
|
||||||
|
* Copyright © 2024 VLC authors and VideoLAN
|
||||||
|
* Author: Nicolas POMEPUY
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
|
||||||
|
* **************************************************************************
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package main.java.org.videolan.resources.opensubtitles
|
||||||
|
|
||||||
|
import android.content.SharedPreferences
|
||||||
|
import com.squareup.moshi.JsonAdapter
|
||||||
|
import com.squareup.moshi.Moshi
|
||||||
|
import com.squareup.moshi.adapters.Rfc3339DateJsonAdapter
|
||||||
|
import org.videolan.tools.KEY_OPEN_SUBTITLES_LIMIT
|
||||||
|
import org.videolan.tools.KEY_OPEN_SUBTITLES_USER
|
||||||
|
import org.videolan.tools.putSingle
|
||||||
|
import java.util.Date
|
||||||
|
|
||||||
|
object OpenSubtitlesUtils {
|
||||||
|
fun getUser(settings: SharedPreferences): OpenSubtitlesUser {
|
||||||
|
settings.getString(KEY_OPEN_SUBTITLES_USER, "")?.let { userString ->
|
||||||
|
val jsonAdapter = getUserAdapter()
|
||||||
|
return try {
|
||||||
|
jsonAdapter.fromJson(userString) ?: OpenSubtitlesUser()
|
||||||
|
} catch (e: Exception) {
|
||||||
|
OpenSubtitlesUser()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return OpenSubtitlesUser()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getLimit(settings: SharedPreferences): OpenSubtitlesLimit {
|
||||||
|
settings.getString(KEY_OPEN_SUBTITLES_LIMIT, "")?.let { limitString ->
|
||||||
|
val jsonAdapter = getLimitAdapter()
|
||||||
|
return try {
|
||||||
|
jsonAdapter.fromJson(limitString) ?: OpenSubtitlesLimit()
|
||||||
|
} catch (e: Exception) {
|
||||||
|
OpenSubtitlesLimit()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return OpenSubtitlesLimit()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun saveUser(settings: SharedPreferences, user: OpenSubtitlesUser) {
|
||||||
|
val jsonAdapter = getUserAdapter()
|
||||||
|
settings.putSingle(KEY_OPEN_SUBTITLES_USER, jsonAdapter.toJson(user))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getUserAdapter(): JsonAdapter<OpenSubtitlesUser> {
|
||||||
|
val moshi = Moshi.Builder().build()
|
||||||
|
val jsonAdapter = moshi.adapter(OpenSubtitlesUser::class.java)
|
||||||
|
return jsonAdapter
|
||||||
|
}
|
||||||
|
|
||||||
|
fun saveLimit(settings: SharedPreferences, limit: OpenSubtitlesLimit) {
|
||||||
|
val jsonAdapter = getLimitAdapter()
|
||||||
|
settings.putSingle(KEY_OPEN_SUBTITLES_LIMIT, jsonAdapter.toJson(limit))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getLimitAdapter(): JsonAdapter<OpenSubtitlesLimit> {
|
||||||
|
val moshi =
|
||||||
|
Moshi.Builder().add(Date::class.java, Rfc3339DateJsonAdapter().nullSafe()).build()
|
||||||
|
val jsonAdapter = moshi.adapter(OpenSubtitlesLimit::class.java)
|
||||||
|
return jsonAdapter
|
||||||
|
}
|
||||||
|
}
|
@ -248,6 +248,7 @@ const val WIDGETS_PREVIEW_PLAYING = "widgets_preview_playing"
|
|||||||
|
|
||||||
//OpenSubtitles
|
//OpenSubtitles
|
||||||
const val KEY_OPEN_SUBTITLES_USER = "open_subtitles_user"
|
const val KEY_OPEN_SUBTITLES_USER = "open_subtitles_user"
|
||||||
|
const val KEY_OPEN_SUBTITLES_LIMIT = "open_subtitles_limit"
|
||||||
|
|
||||||
|
|
||||||
const val KEY_SAFE_MODE_PIN = "safe_mode_pin"
|
const val KEY_SAFE_MODE_PIN = "safe_mode_pin"
|
||||||
|
@ -49,6 +49,14 @@
|
|||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
tools:text="Game of Thrones - S01e01" />
|
tools:text="Game of Thrones - S01e01" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/limit"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@{viewmodel.observableLimit.get().getRemainingText()}"
|
||||||
|
app:layout_constraintStart_toStartOf="@+id/movieName"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/movieName" />
|
||||||
|
|
||||||
<org.videolan.vlc.gui.view.LanguageSelector
|
<org.videolan.vlc.gui.view.LanguageSelector
|
||||||
android:id="@+id/language_list_spinner"
|
android:id="@+id/language_list_spinner"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
|
@ -24,8 +24,9 @@ import kotlinx.coroutines.ObsoleteCoroutinesApi
|
|||||||
import kotlinx.coroutines.channels.actor
|
import kotlinx.coroutines.channels.actor
|
||||||
import kotlinx.coroutines.isActive
|
import kotlinx.coroutines.isActive
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
|
import main.java.org.videolan.resources.opensubtitles.OpenSubtitlesLimit
|
||||||
import main.java.org.videolan.resources.opensubtitles.OpenSubtitlesUser
|
import main.java.org.videolan.resources.opensubtitles.OpenSubtitlesUser
|
||||||
import main.java.org.videolan.resources.opensubtitles.OpenSubtitlesUserUtil
|
import main.java.org.videolan.resources.opensubtitles.OpenSubtitlesUtils
|
||||||
import org.videolan.resources.opensubtitles.OpenSubtitleRepository
|
import org.videolan.resources.opensubtitles.OpenSubtitleRepository
|
||||||
import org.videolan.resources.util.parcelable
|
import org.videolan.resources.util.parcelable
|
||||||
import org.videolan.tools.Settings
|
import org.videolan.tools.Settings
|
||||||
@ -71,6 +72,13 @@ class SubtitleDownloaderDialogFragment : VLCBottomSheetDialogFragment() {
|
|||||||
withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) {
|
||||||
val downloadLink = OpenSubtitleRepository.getInstance()
|
val downloadLink = OpenSubtitleRepository.getInstance()
|
||||||
.getDownloadLink(subtitleEvent.item.fileId)
|
.getDownloadLink(subtitleEvent.item.fileId)
|
||||||
|
val openSubtitlesLimit = OpenSubtitlesLimit(
|
||||||
|
downloadLink.requests,
|
||||||
|
downloadLink.requests + downloadLink.remaining,
|
||||||
|
downloadLink.resetTimeUtc
|
||||||
|
)
|
||||||
|
OpenSubtitlesUtils.saveLimit(settings, openSubtitlesLimit)
|
||||||
|
viewModel.observableLimit.set(openSubtitlesLimit)
|
||||||
subtitleEvent.item.zipDownloadLink = downloadLink.link
|
subtitleEvent.item.zipDownloadLink = downloadLink.link
|
||||||
subtitleEvent.item.fileName = downloadLink.fileName
|
subtitleEvent.item.fileName = downloadLink.fileName
|
||||||
}
|
}
|
||||||
@ -126,7 +134,7 @@ class SubtitleDownloaderDialogFragment : VLCBottomSheetDialogFragment() {
|
|||||||
binding.loginButton.setOnClickListener {
|
binding.loginButton.setOnClickListener {
|
||||||
if (viewModel.observableUser.get()?.logged == true) {
|
if (viewModel.observableUser.get()?.logged == true) {
|
||||||
val user = OpenSubtitlesUser()
|
val user = OpenSubtitlesUser()
|
||||||
OpenSubtitlesUserUtil.save(settings, user)
|
OpenSubtitlesUtils.saveUser(settings, user)
|
||||||
viewModel.observableUser.set(user)
|
viewModel.observableUser.set(user)
|
||||||
}else {
|
}else {
|
||||||
viewModel.login(
|
viewModel.login(
|
||||||
@ -181,7 +189,8 @@ class SubtitleDownloaderDialogFragment : VLCBottomSheetDialogFragment() {
|
|||||||
})
|
})
|
||||||
//todo
|
//todo
|
||||||
viewModel.observableSearchHearingImpaired.set(false)
|
viewModel.observableSearchHearingImpaired.set(false)
|
||||||
viewModel.observableUser.set(OpenSubtitlesUserUtil.get(settings))
|
viewModel.observableUser.set(OpenSubtitlesUtils.getUser(settings))
|
||||||
|
viewModel.observableLimit.set(OpenSubtitlesUtils.getLimit(settings))
|
||||||
|
|
||||||
binding.retryButton.setOnClickListener {
|
binding.retryButton.setOnClickListener {
|
||||||
viewModel.onRefresh()
|
viewModel.onRefresh()
|
||||||
|
@ -21,8 +21,9 @@ import kotlinx.coroutines.Job
|
|||||||
import kotlinx.coroutines.isActive
|
import kotlinx.coroutines.isActive
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
|
import main.java.org.videolan.resources.opensubtitles.OpenSubtitlesLimit
|
||||||
import main.java.org.videolan.resources.opensubtitles.OpenSubtitlesUser
|
import main.java.org.videolan.resources.opensubtitles.OpenSubtitlesUser
|
||||||
import main.java.org.videolan.resources.opensubtitles.OpenSubtitlesUserUtil
|
import main.java.org.videolan.resources.opensubtitles.OpenSubtitlesUtils
|
||||||
import org.videolan.resources.opensubtitles.Data
|
import org.videolan.resources.opensubtitles.Data
|
||||||
import org.videolan.resources.opensubtitles.OpenSubV1
|
import org.videolan.resources.opensubtitles.OpenSubV1
|
||||||
import org.videolan.resources.opensubtitles.OpenSubtitleRepository
|
import org.videolan.resources.opensubtitles.OpenSubtitleRepository
|
||||||
@ -70,6 +71,7 @@ class SubtitlesModel(private val context: Context, private val mediaUri: Uri, pr
|
|||||||
val observableSearchLanguage = ObservableField<List<String>>()
|
val observableSearchLanguage = ObservableField<List<String>>()
|
||||||
val observableSearchHearingImpaired = ObservableField<Boolean>()
|
val observableSearchHearingImpaired = ObservableField<Boolean>()
|
||||||
val observableUser = ObservableField<OpenSubtitlesUser>()
|
val observableUser = ObservableField<OpenSubtitlesUser>()
|
||||||
|
val observableLimit = ObservableField<OpenSubtitlesLimit>()
|
||||||
private var previousSearchLanguage: List<String>? = null
|
private var previousSearchLanguage: List<String>? = null
|
||||||
val manualSearchEnabled = ObservableBoolean(false)
|
val manualSearchEnabled = ObservableBoolean(false)
|
||||||
|
|
||||||
@ -272,7 +274,7 @@ class SubtitlesModel(private val context: Context, private val mediaUri: Uri, pr
|
|||||||
val userResult = call.body()
|
val userResult = call.body()
|
||||||
if (userResult != null) {
|
if (userResult != null) {
|
||||||
val openSubtitlesUser = OpenSubtitlesUser(true, userResult, username = username)
|
val openSubtitlesUser = OpenSubtitlesUser(true, userResult, username = username)
|
||||||
OpenSubtitlesUserUtil.save(settings, openSubtitlesUser)
|
OpenSubtitlesUtils.saveUser(settings, openSubtitlesUser)
|
||||||
observableUser.set(openSubtitlesUser)
|
observableUser.set(openSubtitlesUser)
|
||||||
return@withContext
|
return@withContext
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user