subdub toggle | regex fix (yomiroll) | idk I forgot

This commit is contained in:
rebelonion 2024-01-26 00:17:33 -06:00
parent 4a5eab13c9
commit 49b3c33fbc
8 changed files with 134 additions and 17 deletions

View file

@ -10,8 +10,8 @@ class AnimeNameAdapter {
"(episode|ep|e)[\\s:.\\-]*([\\d]+\\.?[\\d]*)[\\s:.\\-]*\\(?\\s*(sub|subbed|dub|dubbed)*\\s*\\)?\\s*"
const val failedEpisodeNumberRegex =
"(?<!part\\s)\\b(\\d+)\\b"
const val seasonRegex = "\\s+(season|s)[\\s:.\\-]*(\\d+)[\\s:.\\-]*"
const val subdubRegex = "^(soft)?[\\s-]*(sub|dub|mixed)(bed)?\\s*$"
const val seasonRegex = "(season|s)[\\s:.\\-]*(\\d+)[\\s:.\\-]*"
const val subdubRegex = "^(soft)?[\\s-]*(sub|dub|mixed)(bed|s)?\\s*$"
fun setSubDub(text: String, typeToSetTo: SubDubType): String? {
val subdubPattern: Pattern = Pattern.compile(subdubRegex, Pattern.CASE_INSENSITIVE)
@ -25,6 +25,7 @@ class AnimeNameAdapter {
val toggled = when (typeToSetTo) {
SubDubType.SUB -> "sub"
SubDubType.DUB -> "dub"
SubDubType.NULL -> ""
}
val toggledCasePreserved =
if (subdub?.get(0)?.isUpperCase() == true || soft?.get(0)
@ -41,8 +42,24 @@ class AnimeNameAdapter {
}
}
fun getSubDub(text: String): SubDubType {
val subdubPattern: Pattern = Pattern.compile(subdubRegex, Pattern.CASE_INSENSITIVE)
val subdubMatcher: Matcher = subdubPattern.matcher(text)
return if (subdubMatcher.find()) {
val subdub = subdubMatcher.group(2)?.lowercase(Locale.ROOT)
when (subdub) {
"sub" -> SubDubType.SUB
"dub" -> SubDubType.DUB
else -> SubDubType.NULL
}
} else {
SubDubType.NULL
}
}
enum class SubDubType {
SUB, DUB
SUB, DUB, NULL
}
fun findSeasonNumber(text: String): Int? {

View file

@ -113,7 +113,7 @@ class AnimeWatchAdapter(
binding.animeSourceTitle.text = showUserText
showUserTextListener = { MainScope().launch { binding.animeSourceTitle.text = it } }
binding.animeSourceDubbedCont.visibility =
if (isDubAvailableSeparately) View.VISIBLE else View.GONE
if (isDubAvailableSeparately()) View.VISIBLE else View.GONE
}
}
@ -133,7 +133,7 @@ class AnimeWatchAdapter(
binding.animeSourceDubbed.isChecked = selectDub
changing = false
binding.animeSourceDubbedCont.visibility =
if (isDubAvailableSeparately) View.VISIBLE else View.GONE
if (isDubAvailableSeparately()) View.VISIBLE else View.GONE
source = i
setLanguageList(0, i)
}
@ -154,7 +154,7 @@ class AnimeWatchAdapter(
binding.animeSourceDubbed.isChecked = selectDub
changing = false
binding.animeSourceDubbedCont.visibility =
if (isDubAvailableSeparately) View.VISIBLE else View.GONE
if (isDubAvailableSeparately()) View.VISIBLE else View.GONE
setLanguageList(i, source)
}
subscribeButton(false)

View file

@ -840,7 +840,7 @@ class ExoplayerView : AppCompatActivity(), Player.Listener, SessionAvailabilityL
isFastForwarding = true
exoPlayer.setPlaybackSpeed(exoPlayer.playbackParameters.speed * 2)
fastForward.visibility = View.VISIBLE
fastForward.text = ("${exoPlayer.playbackParameters.speed}x")
fastForward.text = "${exoPlayer.playbackParameters.speed}x"
}
fun stopFastForward() {
@ -1286,7 +1286,7 @@ class ExoplayerView : AppCompatActivity(), Player.Listener, SessionAvailabilityL
}
println("sub: $sub")
} else {
val subUri = Uri.parse((subtitle!!.file.url))
val subUri = Uri.parse(subtitle!!.file.url)
sub = MediaItem.SubtitleConfiguration
.Builder(subUri)
.setSelectionFlags(C.SELECTION_FLAG_FORCED)

View file

@ -716,7 +716,7 @@ class MangaReaderActivity : AppCompatActivity() {
val y = event.rawY.toInt()
val screenWidth = Resources.getSystem().displayMetrics.widthPixels
//if in the 1st 1/5th of the screen width, left and lower than 1/5th of the screen height, left
if (screenWidth / 5 in (x + 1)..<y) {
if (screenWidth / 5 in x + 1..<y) {
pressLocation = if (settings.default.direction == RIGHT_TO_LEFT) {
pressPos.RIGHT
} else {

View file

@ -163,7 +163,7 @@ abstract class AnimeParser : BaseParser() {
*
* **NOTE : do not forget to override `search` if the site does not support only dub search**
* **/
open val isDubAvailableSeparately by Delegates.notNull<Boolean>()
open fun isDubAvailableSeparately(sourceLang: Int? = null): Boolean = false
/**
* The app changes this, depending on user's choice.
@ -182,7 +182,7 @@ abstract class AnimeParser : BaseParser() {
* **/
override suspend fun loadSavedShowResponse(mediaId: Int): ShowResponse? {
checkIfVariablesAreEmpty()
val dub = if (isDubAvailableSeparately) "_${if (selectDub) "dub" else "sub"}" else ""
val dub = if (isDubAvailableSeparately()) "_${if (selectDub) "dub" else "sub"}" else ""
var loaded = loadData<ShowResponse>("${saveName}${dub}_$mediaId")
if (loaded == null && malSyncBackupName.isNotEmpty())
loaded = MalSyncBackup.get(mediaId, malSyncBackupName, selectDub)
@ -200,7 +200,7 @@ abstract class AnimeParser : BaseParser() {
)
} : ${response.name}"
)
val dub = if (isDubAvailableSeparately) "_${if (selectDub) "dub" else "sub"}" else ""
val dub = if (isDubAvailableSeparately()) "_${if (selectDub) "dub" else "sub"}" else ""
saveData("${saveName}${dub}_$mediaId", response)
}
}
@ -209,8 +209,6 @@ abstract class AnimeParser : BaseParser() {
class EmptyAnimeParser : AnimeParser() {
override val name: String = "None"
override val saveName: String = "None"
override val isDubAvailableSeparately: Boolean = false
override suspend fun loadEpisodes(
animeLink: String,
extra: Map<String, String>?,

View file

@ -10,12 +10,14 @@ import android.os.Build
import android.os.Environment
import android.provider.MediaStore
import ani.dantotsu.FileUrl
import ani.dantotsu.currContext
import ani.dantotsu.logger
import ani.dantotsu.media.anime.AnimeNameAdapter
import ani.dantotsu.media.manga.ImageData
import ani.dantotsu.media.manga.MangaCache
import ani.dantotsu.snackString
import eu.kanade.tachiyomi.animesource.AnimeCatalogueSource
import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource
import eu.kanade.tachiyomi.animesource.model.AnimesPage
import eu.kanade.tachiyomi.animesource.model.SAnime
import eu.kanade.tachiyomi.animesource.model.SEpisode
@ -26,6 +28,7 @@ import eu.kanade.tachiyomi.extension.anime.model.AnimeExtension
import eu.kanade.tachiyomi.extension.manga.model.MangaExtension
import eu.kanade.tachiyomi.network.NetworkHelper
import eu.kanade.tachiyomi.network.interceptor.CloudflareBypassException
import eu.kanade.tachiyomi.source.anime.getPreferenceKey
import eu.kanade.tachiyomi.source.model.MangasPage
import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter
@ -71,8 +74,63 @@ class DynamicAnimeParser(extension: AnimeExtension.Installed) : AnimeParser() {
override val name = extension.name
override val saveName = extension.name
override val hostUrl = extension.sources.first().name
override val isDubAvailableSeparately = false
override val isNSFW = extension.isNsfw
override var selectDub: Boolean
get() = getDub()
set(value) {
setDub(value)
}
private fun getDub(): Boolean {
val configurableSource = extension.sources[sourceLanguage] as? ConfigurableAnimeSource
?: return false
currContext()?.let { context ->
val sharedPreferences =
context.getSharedPreferences(configurableSource.getPreferenceKey(), Context.MODE_PRIVATE)
sharedPreferences.all.filterValues { AnimeNameAdapter.getSubDub(it.toString()) != AnimeNameAdapter.Companion.SubDubType.NULL }
.forEach { value ->
return when (AnimeNameAdapter.getSubDub(value.value.toString())) {
AnimeNameAdapter.Companion.SubDubType.SUB -> false
AnimeNameAdapter.Companion.SubDubType.DUB -> true
AnimeNameAdapter.Companion.SubDubType.NULL -> false
}
}
}
return false
}
fun setDub(setDub: Boolean) {
val configurableSource = extension.sources[sourceLanguage] as? ConfigurableAnimeSource
?: return
val type = when (setDub) {
true -> AnimeNameAdapter.Companion.SubDubType.DUB
false -> AnimeNameAdapter.Companion.SubDubType.SUB
}
currContext()?.let { context ->
val sharedPreferences =
context.getSharedPreferences(configurableSource.getPreferenceKey(), Context.MODE_PRIVATE)
sharedPreferences.all.filterValues { AnimeNameAdapter.getSubDub(it.toString()) != AnimeNameAdapter.Companion.SubDubType.NULL }
.forEach { value ->
val setValue = AnimeNameAdapter.setSubDub(value.value.toString(), type)
if (setValue != null) {
sharedPreferences.edit().putString(value.key, setValue).apply()
}
}
}
}
override fun isDubAvailableSeparately(sourceLang: Int?): Boolean {
val configurableSource = extension.sources[sourceLanguage] as? ConfigurableAnimeSource
?: return false
currContext()?.let { context ->
logger("isDubAvailableSeparately: ${configurableSource.getPreferenceKey()}")
val sharedPreferences =
context.getSharedPreferences(configurableSource.getPreferenceKey(), Context.MODE_PRIVATE)
sharedPreferences.all.filterValues { AnimeNameAdapter.setSubDub(it.toString(), AnimeNameAdapter.Companion.SubDubType.NULL) != null }
.forEach { _ -> return true }
}
return false
}
override suspend fun loadEpisodes(
animeLink: String,
extra: Map<String, String>?,
@ -106,6 +164,8 @@ class DynamicAnimeParser(extension: AnimeExtension.Installed) : AnimeParser() {
}
it
}
} else if (episodesAreIncrementing(res)) {
res.sortedBy { it.episode_number }
} else {
var episodeCounter = 1f
// Group by season, sort within each season, and then renumber while keeping episode number 0 as is
@ -135,6 +195,19 @@ class DynamicAnimeParser(extension: AnimeExtension.Installed) : AnimeParser() {
return emptyList()
}
private fun episodesAreIncrementing(episodes: List<SEpisode>): Boolean {
val sortedEpisodes = episodes.sortedBy { it.episode_number }
val takenNumbers = mutableListOf<Float>()
sortedEpisodes.forEach {
if (it.episode_number !in takenNumbers) {
takenNumbers.add(it.episode_number)
} else {
return false
}
}
return true
}
override suspend fun loadVideoServers(
episodeLink: String,
extra: Map<String, String>?,

View file

@ -21,7 +21,6 @@ class OfflineAnimeParser : AnimeParser() {
override val name = "Offline"
override val saveName = "Offline"
override val hostUrl = "Offline"
override val isDubAvailableSeparately = false
override val isNSFW = false
override suspend fun loadEpisodes(

View file

@ -1,6 +1,7 @@
package ani.dantotsu.settings.extensionprefs
import android.content.Context
import android.content.SharedPreferences
import android.os.Bundle
import android.util.TypedValue
import androidx.core.os.bundleOf
@ -8,6 +9,7 @@ import androidx.lifecycle.lifecycleScope
import androidx.preference.DialogPreference
import androidx.preference.EditTextPreference
import androidx.preference.PreferenceFragmentCompat
import androidx.preference.PreferenceManager
import androidx.preference.forEach
import androidx.preference.getOnBindEditTextListener
import ani.dantotsu.snackString
@ -46,7 +48,7 @@ class AnimeSourcePreferencesFragment : PreferenceFragmentCompat() {
onCloseAction?.invoke()
}
private fun populateAnimePreferenceScreen(): PreferenceScreen {
fun populateAnimePreferenceScreen(): PreferenceScreen {
val sourceId = requireArguments().getLong(SOURCE_ID)
val source = Injekt.get<AnimeSourceManager>().get(sourceId) as? ConfigurableAnimeSource
?: error("Source with id: $sourceId not found!")
@ -93,3 +95,31 @@ class AnimeSourcePreferencesFragment : PreferenceFragmentCompat() {
private const val SOURCE_ID = "source_id"
}
}
class InitialAnimeSourcePreferencesFragment(val sharedPreferences: SharedPreferences, val source: ConfigurableAnimeSource, val currContext: Context) : PreferenceFragmentCompat() {
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
preferenceScreen = try {
populateAnimePreferenceScreen()
} catch (e: Exception) {
snackString(e.message ?: "Unknown error")
preferenceManager.createPreferenceScreen(requireContext())
}
//set background color
val color = TypedValue()
requireContext().theme.resolveAttribute(
com.google.android.material.R.attr.backgroundColor,
color,
true
)
view?.setBackgroundColor(color.data)
}
fun populateAnimePreferenceScreen(): PreferenceScreen {
val dataStore = SharedPreferencesDataStore(sharedPreferences)
preferenceManager.preferenceDataStore = dataStore
val sourceScreen = preferenceManager.createPreferenceScreen(requireContext())
source.setupPreferenceScreen(sourceScreen)
return sourceScreen
}
}