Introduce SubtitleUtils for more shared code to reduce duplication

This commit is contained in:
Luna712 2024-07-11 19:56:37 -06:00 committed by GitHub
parent 145482a32f
commit a93163ff88
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 62 additions and 71 deletions

View file

@ -19,7 +19,6 @@ import android.widget.TextView
import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.StringRes
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.isGone
import androidx.core.view.isVisible
import androidx.core.widget.doOnTextChanged
@ -45,7 +44,7 @@ import com.lagradost.cloudstream3.utils.AppContextUtils.loadResult
import com.lagradost.cloudstream3.utils.BackPressedCallbackHelper.attachBackPressedCallback
import com.lagradost.cloudstream3.utils.BackPressedCallbackHelper.detachBackPressedCallback
import com.lagradost.cloudstream3.utils.DOWNLOAD_EPISODE_CACHE
import com.lagradost.cloudstream3.utils.DataStore
import com.lagradost.cloudstream3.utils.DataStore.getFolderName
import com.lagradost.cloudstream3.utils.UIHelper.dismissSafe
import com.lagradost.cloudstream3.utils.UIHelper.fixPaddingStatusbar
import com.lagradost.cloudstream3.utils.UIHelper.hideKeyboard
@ -224,7 +223,7 @@ class DownloadFragment : Fragment() {
DOWNLOAD_ACTION_GO_TO_CHILD -> {
if (!click.data.type.isMovieType()) {
val folder =
DataStore.getFolderName(DOWNLOAD_EPISODE_CACHE, click.data.id.toString())
getFolderName(DOWNLOAD_EPISODE_CACHE, click.data.id.toString())
activity?.navigate(
R.id.action_navigation_downloads_to_navigation_download_child,
DownloadChildFragment.newInstance(click.data.name, folder)
@ -233,7 +232,7 @@ class DownloadFragment : Fragment() {
}
DOWNLOAD_ACTION_LOAD_RESULT -> {
(activity as AppCompatActivity?)?.loadResult(click.data.url, click.data.apiName)
activity?.loadResult(click.data.url, click.data.apiName)
}
}
}

View file

@ -4,8 +4,9 @@ import com.lagradost.cloudstream3.AcraApplication.Companion.context
import com.lagradost.cloudstream3.R
import com.lagradost.cloudstream3.ui.player.PlayerSubtitleHelper.Companion.toSubtitleMimeType
import com.lagradost.cloudstream3.utils.ExtractorLink
import com.lagradost.cloudstream3.utils.VideoDownloadManager
import com.lagradost.cloudstream3.utils.VideoDownloadManager.cleanDisplayName
import com.lagradost.cloudstream3.utils.SubtitleUtils.cleanDisplayName
import com.lagradost.cloudstream3.utils.SubtitleUtils.isMatchingSubtitle
import com.lagradost.cloudstream3.utils.VideoDownloadManager.getFolder
import kotlin.math.max
import kotlin.math.min
@ -66,28 +67,9 @@ class DownloadFileGenerator(
val cleanDisplay = cleanDisplayName(display)
VideoDownloadManager.getFolder(ctx, relative, meta.basePath)
?.forEach { (name, uri) ->
// only these files are allowed, so no videos as subtitles
if (listOf(
".vtt",
".srt",
".txt",
".ass",
".ttml",
".sbv",
".dfxp"
).none { name.contains(it, true) }
) return@forEach
// cant have the exact same file as a subtitle
if (name.equals(display, true)) return@forEach
getFolder(ctx, relative, meta.basePath)?.forEach { (name, uri) ->
if (isMatchingSubtitle(name, display, cleanDisplay)) {
val cleanName = cleanDisplayName(name)
// we only want files with the approx same name
if (!cleanName.startsWith(cleanDisplay, true)) return@forEach
val realName = cleanName.removePrefix(cleanDisplay)
subtitleCallback(
@ -101,6 +83,7 @@ class DownloadFileGenerator(
)
)
}
}
return true
}

View file

@ -0,0 +1,51 @@
package com.lagradost.cloudstream3.utils
import android.content.Context
import com.lagradost.api.Log
import com.lagradost.cloudstream3.utils.VideoDownloadManager.getFolder
import com.lagradost.safefile.SafeFile
object SubtitleUtils {
// Only these files are allowed, so no videos as subtitles
private val allowedExtensions = listOf(
".vtt", ".srt", ".txt", ".ass",
".ttml", ".sbv", ".dfxp"
)
fun deleteMatchingSubtitles(context: Context, info: VideoDownloadManager.DownloadedFileInfo) {
val relative = info.relativePath
val display = info.displayName
val cleanDisplay = cleanDisplayName(display)
getFolder(context, relative, info.basePath)?.forEach { (name, uri) ->
if (isMatchingSubtitle(name, display, cleanDisplay)) {
val subtitleFile = SafeFile.fromUri(context, uri)
if (subtitleFile == null || !subtitleFile.delete()) {
Log.e("SubtitleDeletion", "Failed to delete subtitle file: ${subtitleFile?.name()}")
}
}
}
}
fun isMatchingSubtitle(
name: String,
display: String,
cleanDisplay: String
): Boolean {
// Check if the file has a valid subtitle extension
val hasValidExtension = allowedExtensions.any { name.contains(it, ignoreCase = true) }
// Ensure the file name is not exactly the same as the display name
val isNotDisplayName = !name.equals(display, ignoreCase = true)
// Check if the file name starts with a cleaned version of the display name
val startsWithCleanDisplay = cleanDisplayName(name).startsWith(cleanDisplay, ignoreCase = true)
return hasValidExtension && isNotDisplayName && startsWithCleanDisplay
}
fun cleanDisplayName(name: String): String {
return name.substringBeforeLast('.').trim()
}
}

View file

@ -37,6 +37,7 @@ import com.lagradost.cloudstream3.utils.Coroutines.ioSafe
import com.lagradost.cloudstream3.utils.Coroutines.main
import com.lagradost.cloudstream3.utils.DataStore.getKey
import com.lagradost.cloudstream3.utils.DataStore.removeKey
import com.lagradost.cloudstream3.utils.SubtitleUtils.deleteMatchingSubtitles
import com.lagradost.cloudstream3.utils.UIHelper.colorFromAttribute
import com.lagradost.safefile.MediaFileContentType
import com.lagradost.safefile.SafeFile
@ -1762,54 +1763,11 @@ object VideoDownloadManager {
downloadDeleteEvent.invoke(id)
val isFileDeleted = info.toFile(context)?.delete() ?: false
if (isFileDeleted) deleteSubtitles(context, info)
if (isFileDeleted) deleteMatchingSubtitles(context, info)
return isFileDeleted
}
private fun deleteSubtitles(context: Context, info: DownloadedFileInfo): Boolean {
val relative = info.relativePath
val display = info.displayName
val cleanDisplay = cleanDisplayName(display)
val subtitleFiles = getFolder(context, relative, info.basePath)
?.mapNotNull { (name, uri) ->
if (listOf(
".vtt",
".srt",
".txt",
".ass",
".ttml",
".sbv",
".dfxp"
).none { name.contains(it, true) }
) return@mapNotNull null
if (name.equals(display, true)) return@mapNotNull null
val cleanName = cleanDisplayName(name)
if (!cleanName.startsWith(cleanDisplay, true)) return@mapNotNull null
SafeFile.fromUri(context, uri)
} ?: return false
var allDeleted = true
subtitleFiles.forEach { subtitleFile ->
if (!subtitleFile.delete()) {
Log.e("SubtitleDeletion", "Failed to delete subtitle file: ${subtitleFile.name()}")
allDeleted = false
}
}
return allDeleted
}
fun cleanDisplayName(name: String): String {
return name.substringBeforeLast('.').trim()
}
fun getDownloadResumePackage(context: Context, id: Int): DownloadResumePackage? {
return context.getKey(KEY_RESUME_PACKAGES, id.toString())
}