mirror of
				https://github.com/recloudstream/cloudstream.git
				synced 2024-08-15 01:53:11 +00:00 
			
		
		
		
	added download subtitles option and fixed subtitle download
This commit is contained in:
		
							parent
							
								
									d5a4a65ced
								
							
						
					
					
						commit
						10c945f497
					
				
					 6 changed files with 257 additions and 139 deletions
				
			
		| 
						 | 
				
			
			@ -71,6 +71,9 @@ class DownloadFileGenerator(
 | 
			
		|||
                            .removeSuffix(".vtt")
 | 
			
		||||
                            .removeSuffix(".srt")
 | 
			
		||||
                            .removeSuffix(".txt")
 | 
			
		||||
                            .trim()
 | 
			
		||||
                            .removePrefix("(")
 | 
			
		||||
                            .removeSuffix(")")
 | 
			
		||||
 | 
			
		||||
                        subtitleCallback(
 | 
			
		||||
                            SubtitleData(
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -48,6 +48,9 @@ const val ACTION_SHOW_OPTIONS = 10
 | 
			
		|||
const val ACTION_CLICK_DEFAULT = 11
 | 
			
		||||
const val ACTION_SHOW_TOAST = 12
 | 
			
		||||
 | 
			
		||||
const val ACTION_DOWNLOAD_EPISODE_SUBTITLE = 13
 | 
			
		||||
const val ACTION_DOWNLOAD_EPISODE_SUBTITLE_MIRROR = 14
 | 
			
		||||
 | 
			
		||||
data class EpisodeClickEvent(val action: Int, val data: ResultEpisode)
 | 
			
		||||
 | 
			
		||||
class EpisodeAdapter(
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,6 +4,7 @@ import android.annotation.SuppressLint
 | 
			
		|||
import android.app.Activity
 | 
			
		||||
import android.content.ClipData
 | 
			
		||||
import android.content.ClipboardManager
 | 
			
		||||
import android.content.Context
 | 
			
		||||
import android.content.Context.CLIPBOARD_SERVICE
 | 
			
		||||
import android.content.Intent
 | 
			
		||||
import android.content.Intent.*
 | 
			
		||||
| 
						 | 
				
			
			@ -43,7 +44,6 @@ import com.lagradost.cloudstream3.*
 | 
			
		|||
import com.lagradost.cloudstream3.APIHolder.getApiDubstatusSettings
 | 
			
		||||
import com.lagradost.cloudstream3.APIHolder.getApiFromName
 | 
			
		||||
import com.lagradost.cloudstream3.APIHolder.getId
 | 
			
		||||
import com.lagradost.cloudstream3.AcraApplication.Companion.context
 | 
			
		||||
import com.lagradost.cloudstream3.AcraApplication.Companion.setKey
 | 
			
		||||
import com.lagradost.cloudstream3.CommonActivity.getCastSession
 | 
			
		||||
import com.lagradost.cloudstream3.CommonActivity.showToast
 | 
			
		||||
| 
						 | 
				
			
			@ -70,6 +70,7 @@ import com.lagradost.cloudstream3.utils.AppUtils.isConnectedToChromecast
 | 
			
		|||
import com.lagradost.cloudstream3.utils.AppUtils.loadCache
 | 
			
		||||
import com.lagradost.cloudstream3.utils.AppUtils.openBrowser
 | 
			
		||||
import com.lagradost.cloudstream3.utils.CastHelper.startCast
 | 
			
		||||
import com.lagradost.cloudstream3.utils.Coroutines.ioSafe
 | 
			
		||||
import com.lagradost.cloudstream3.utils.Coroutines.main
 | 
			
		||||
import com.lagradost.cloudstream3.utils.DataStore.getFolderName
 | 
			
		||||
import com.lagradost.cloudstream3.utils.DataStore.setKey
 | 
			
		||||
| 
						 | 
				
			
			@ -88,6 +89,7 @@ import com.lagradost.cloudstream3.utils.UIHelper.popupMenuNoIconsAndNoStringRes
 | 
			
		|||
import com.lagradost.cloudstream3.utils.UIHelper.requestRW
 | 
			
		||||
import com.lagradost.cloudstream3.utils.UIHelper.setImage
 | 
			
		||||
import com.lagradost.cloudstream3.utils.UIHelper.setImageBlur
 | 
			
		||||
import com.lagradost.cloudstream3.utils.VideoDownloadManager.getFileName
 | 
			
		||||
import com.lagradost.cloudstream3.utils.VideoDownloadManager.sanitizeFilename
 | 
			
		||||
import kotlinx.android.synthetic.main.fragment_result.*
 | 
			
		||||
import kotlinx.android.synthetic.main.fragment_result_swipe.*
 | 
			
		||||
| 
						 | 
				
			
			@ -205,7 +207,80 @@ class ResultFragment : Fragment(), PanelsChildGestureRegionObserver.GestureRegio
 | 
			
		|||
 | 
			
		||||
        private var updateUIListener: (() -> Unit)? = null
 | 
			
		||||
 | 
			
		||||
        suspend fun startDownload(
 | 
			
		||||
        private fun downloadSubtitle(
 | 
			
		||||
            context: Context?,
 | 
			
		||||
            link: SubtitleData,
 | 
			
		||||
            meta: VideoDownloadManager.DownloadEpisodeMetadata,
 | 
			
		||||
        ) {
 | 
			
		||||
            context?.let { ctx ->
 | 
			
		||||
                val fileName = getFileName(ctx, meta)
 | 
			
		||||
                val folder = getFolder(meta.type ?: return, meta.mainName)
 | 
			
		||||
                downloadSubtitle(
 | 
			
		||||
                    ctx,
 | 
			
		||||
                    ExtractorSubtitleLink(link.name, link.url, ""),
 | 
			
		||||
                    fileName,
 | 
			
		||||
                    folder
 | 
			
		||||
                )
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private fun downloadSubtitle(
 | 
			
		||||
            context: Context?,
 | 
			
		||||
            link: ExtractorSubtitleLink,
 | 
			
		||||
            fileName: String,
 | 
			
		||||
            folder: String
 | 
			
		||||
        ) {
 | 
			
		||||
            ioSafe {
 | 
			
		||||
                VideoDownloadManager.downloadThing(
 | 
			
		||||
                    context ?: return@ioSafe,
 | 
			
		||||
                    link,
 | 
			
		||||
                    "$fileName ${link.name}",
 | 
			
		||||
                    folder,
 | 
			
		||||
                    if (link.url.contains(".srt")) ".srt" else "vtt",
 | 
			
		||||
                    false,
 | 
			
		||||
                    null
 | 
			
		||||
                ) {
 | 
			
		||||
                    // no notification
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private fun getMeta(
 | 
			
		||||
            episode: ResultEpisode,
 | 
			
		||||
            titleName: String,
 | 
			
		||||
            apiName: String,
 | 
			
		||||
            currentPoster: String,
 | 
			
		||||
            currentIsMovie: Boolean,
 | 
			
		||||
            tvType: TvType,
 | 
			
		||||
        ): VideoDownloadManager.DownloadEpisodeMetadata {
 | 
			
		||||
            return VideoDownloadManager.DownloadEpisodeMetadata(
 | 
			
		||||
                episode.id,
 | 
			
		||||
                sanitizeFilename(titleName),
 | 
			
		||||
                apiName,
 | 
			
		||||
                episode.poster ?: currentPoster,
 | 
			
		||||
                episode.name,
 | 
			
		||||
                if (currentIsMovie) null else episode.season,
 | 
			
		||||
                if (currentIsMovie) null else episode.episode,
 | 
			
		||||
                tvType,
 | 
			
		||||
            )
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private fun getFolder(currentType: TvType, titleName: String): String {
 | 
			
		||||
            return when (currentType) {
 | 
			
		||||
                TvType.Anime -> "Anime/$titleName"
 | 
			
		||||
                TvType.Movie -> "Movies"
 | 
			
		||||
                TvType.AnimeMovie -> "Movies"
 | 
			
		||||
                TvType.TvSeries -> "TVSeries/$titleName"
 | 
			
		||||
                TvType.OVA -> "OVA"
 | 
			
		||||
                TvType.Cartoon -> "Cartoons/$titleName"
 | 
			
		||||
                TvType.Torrent -> "Torrent"
 | 
			
		||||
                TvType.Documentary -> "Documentaries"
 | 
			
		||||
                TvType.AsianDrama -> "AsianDrama"
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        fun startDownload(
 | 
			
		||||
            context: Context?,
 | 
			
		||||
            episode: ResultEpisode,
 | 
			
		||||
            currentIsMovie: Boolean,
 | 
			
		||||
            currentHeaderName: String,
 | 
			
		||||
| 
						 | 
				
			
			@ -217,110 +292,87 @@ class ResultFragment : Fragment(), PanelsChildGestureRegionObserver.GestureRegio
 | 
			
		|||
            links: List<ExtractorLink>,
 | 
			
		||||
            subs: List<SubtitleData>?
 | 
			
		||||
        ) {
 | 
			
		||||
            val titleName = sanitizeFilename(currentHeaderName)
 | 
			
		||||
            try {
 | 
			
		||||
                if (context == null) return
 | 
			
		||||
 | 
			
		||||
            val meta = VideoDownloadManager.DownloadEpisodeMetadata(
 | 
			
		||||
                episode.id,
 | 
			
		||||
                titleName,
 | 
			
		||||
                apiName,
 | 
			
		||||
                episode.poster ?: currentPoster,
 | 
			
		||||
                episode.name,
 | 
			
		||||
                if (currentIsMovie) null else episode.season,
 | 
			
		||||
                if (currentIsMovie) null else episode.episode
 | 
			
		||||
            )
 | 
			
		||||
 | 
			
		||||
            val folder = when (currentType) {
 | 
			
		||||
                TvType.Anime -> "Anime/$titleName"
 | 
			
		||||
                TvType.Movie -> "Movies"
 | 
			
		||||
                TvType.AnimeMovie -> "Movies"
 | 
			
		||||
                TvType.TvSeries -> "TVSeries/$titleName"
 | 
			
		||||
                TvType.OVA -> "OVA"
 | 
			
		||||
                TvType.Cartoon -> "Cartoons/$titleName"
 | 
			
		||||
                TvType.Torrent -> "Torrent"
 | 
			
		||||
                TvType.Documentary -> "Documentaries"
 | 
			
		||||
                TvType.AsianDrama -> "AsianDrama"
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            val src = "$DOWNLOAD_NAVIGATE_TO/$parentId" // url ?: return@let
 | 
			
		||||
 | 
			
		||||
            // SET VISUAL KEYS
 | 
			
		||||
            setKey(
 | 
			
		||||
                DOWNLOAD_HEADER_CACHE,
 | 
			
		||||
                parentId.toString(),
 | 
			
		||||
                VideoDownloadHelper.DownloadHeaderCached(
 | 
			
		||||
                    apiName,
 | 
			
		||||
                    url,
 | 
			
		||||
                    currentType,
 | 
			
		||||
                    currentHeaderName,
 | 
			
		||||
                    currentPoster,
 | 
			
		||||
                    parentId,
 | 
			
		||||
                    System.currentTimeMillis(),
 | 
			
		||||
                )
 | 
			
		||||
            )
 | 
			
		||||
 | 
			
		||||
            setKey(
 | 
			
		||||
                getFolderName(
 | 
			
		||||
                    DOWNLOAD_EPISODE_CACHE,
 | 
			
		||||
                    parentId.toString()
 | 
			
		||||
                ), // 3 deep folder for faster acess
 | 
			
		||||
                episode.id.toString(),
 | 
			
		||||
                VideoDownloadHelper.DownloadEpisodeCached(
 | 
			
		||||
                    episode.name,
 | 
			
		||||
                    episode.poster,
 | 
			
		||||
                    episode.episode,
 | 
			
		||||
                    episode.season,
 | 
			
		||||
                    episode.id,
 | 
			
		||||
                    parentId,
 | 
			
		||||
                    episode.rating,
 | 
			
		||||
                    episode.description,
 | 
			
		||||
                    System.currentTimeMillis(),
 | 
			
		||||
                )
 | 
			
		||||
            )
 | 
			
		||||
 | 
			
		||||
            // DOWNLOAD VIDEO
 | 
			
		||||
            VideoDownloadManager.downloadEpisodeUsingWorker(
 | 
			
		||||
                context ?: return,
 | 
			
		||||
                src,//url ?: return,
 | 
			
		||||
                folder,
 | 
			
		||||
                meta,
 | 
			
		||||
                links
 | 
			
		||||
            )
 | 
			
		||||
            // 1. Checks if the lang should be downloaded
 | 
			
		||||
            // 2. Makes it into the download format
 | 
			
		||||
            // 3. Downloads it as a .vtt file
 | 
			
		||||
            val downloadList = getDownloadSubsLanguageISO639_1()
 | 
			
		||||
            subs?.let { subsList ->
 | 
			
		||||
                subsList.filter {
 | 
			
		||||
                    downloadList.contains(
 | 
			
		||||
                        SubtitleHelper.fromLanguageToTwoLetters(
 | 
			
		||||
                            it.name,
 | 
			
		||||
                            true
 | 
			
		||||
                        )
 | 
			
		||||
                val meta =
 | 
			
		||||
                    getMeta(
 | 
			
		||||
                        episode,
 | 
			
		||||
                        currentHeaderName,
 | 
			
		||||
                        apiName,
 | 
			
		||||
                        currentPoster,
 | 
			
		||||
                        currentIsMovie,
 | 
			
		||||
                        currentType
 | 
			
		||||
                    )
 | 
			
		||||
                }
 | 
			
		||||
                    .map { ExtractorSubtitleLink(it.name, it.url, "") }
 | 
			
		||||
                    .forEach { link ->
 | 
			
		||||
                        val epName = meta.name
 | 
			
		||||
                            ?: "${context?.getString(R.string.episode)} ${meta.episode}"
 | 
			
		||||
                        val fileName =
 | 
			
		||||
                            sanitizeFilename(epName + if (downloadList.size > 1) " ${link.name}" else "")
 | 
			
		||||
 | 
			
		||||
                        withContext(Dispatchers.IO) {
 | 
			
		||||
                            normalSafeApiCall {
 | 
			
		||||
                                VideoDownloadManager.downloadThing(
 | 
			
		||||
                                    context ?: return@normalSafeApiCall,
 | 
			
		||||
                                    link,
 | 
			
		||||
                                    fileName,
 | 
			
		||||
                                    folder,
 | 
			
		||||
                                    "vtt",
 | 
			
		||||
                                    false,
 | 
			
		||||
                                    null
 | 
			
		||||
                                ) {
 | 
			
		||||
                                    // no notification
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                val folder = getFolder(currentType, currentHeaderName)
 | 
			
		||||
 | 
			
		||||
                val src = "$DOWNLOAD_NAVIGATE_TO/$parentId" // url ?: return@let
 | 
			
		||||
 | 
			
		||||
                // SET VISUAL KEYS
 | 
			
		||||
                setKey(
 | 
			
		||||
                    DOWNLOAD_HEADER_CACHE,
 | 
			
		||||
                    parentId.toString(),
 | 
			
		||||
                    VideoDownloadHelper.DownloadHeaderCached(
 | 
			
		||||
                        apiName,
 | 
			
		||||
                        url,
 | 
			
		||||
                        currentType,
 | 
			
		||||
                        currentHeaderName,
 | 
			
		||||
                        currentPoster,
 | 
			
		||||
                        parentId,
 | 
			
		||||
                        System.currentTimeMillis(),
 | 
			
		||||
                    )
 | 
			
		||||
                )
 | 
			
		||||
 | 
			
		||||
                setKey(
 | 
			
		||||
                    getFolderName(
 | 
			
		||||
                        DOWNLOAD_EPISODE_CACHE,
 | 
			
		||||
                        parentId.toString()
 | 
			
		||||
                    ), // 3 deep folder for faster acess
 | 
			
		||||
                    episode.id.toString(),
 | 
			
		||||
                    VideoDownloadHelper.DownloadEpisodeCached(
 | 
			
		||||
                        episode.name,
 | 
			
		||||
                        episode.poster,
 | 
			
		||||
                        episode.episode,
 | 
			
		||||
                        episode.season,
 | 
			
		||||
                        episode.id,
 | 
			
		||||
                        parentId,
 | 
			
		||||
                        episode.rating,
 | 
			
		||||
                        episode.description,
 | 
			
		||||
                        System.currentTimeMillis(),
 | 
			
		||||
                    )
 | 
			
		||||
                )
 | 
			
		||||
 | 
			
		||||
                // DOWNLOAD VIDEO
 | 
			
		||||
                VideoDownloadManager.downloadEpisodeUsingWorker(
 | 
			
		||||
                    context,
 | 
			
		||||
                    src,//url ?: return,
 | 
			
		||||
                    folder,
 | 
			
		||||
                    meta,
 | 
			
		||||
                    links
 | 
			
		||||
                )
 | 
			
		||||
 | 
			
		||||
                // 1. Checks if the lang should be downloaded
 | 
			
		||||
                // 2. Makes it into the download format
 | 
			
		||||
                // 3. Downloads it as a .vtt file
 | 
			
		||||
                val downloadList = getDownloadSubsLanguageISO639_1()
 | 
			
		||||
                subs?.let { subsList ->
 | 
			
		||||
                    subsList.filter {
 | 
			
		||||
                        downloadList.contains(
 | 
			
		||||
                            SubtitleHelper.fromLanguageToTwoLetters(
 | 
			
		||||
                                it.name,
 | 
			
		||||
                                true
 | 
			
		||||
                            )
 | 
			
		||||
                        )
 | 
			
		||||
                    }
 | 
			
		||||
                        .map { ExtractorSubtitleLink(it.name, it.url, "") }
 | 
			
		||||
                        .forEach { link ->
 | 
			
		||||
                            val fileName = getFileName(context, meta)
 | 
			
		||||
                            downloadSubtitle(context, link, fileName, folder)
 | 
			
		||||
                        }
 | 
			
		||||
                }
 | 
			
		||||
            } catch (e: Exception) {
 | 
			
		||||
                logError(e)
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -353,6 +405,7 @@ class ResultFragment : Fragment(), PanelsChildGestureRegionObserver.GestureRegio
 | 
			
		|||
                }
 | 
			
		||||
 | 
			
		||||
                startDownload(
 | 
			
		||||
                    activity,
 | 
			
		||||
                    episode,
 | 
			
		||||
                    currentIsMovie,
 | 
			
		||||
                    currentHeaderName,
 | 
			
		||||
| 
						 | 
				
			
			@ -737,6 +790,21 @@ class ResultFragment : Fragment(), PanelsChildGestureRegionObserver.GestureRegio
 | 
			
		|||
                builder.create().show()
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            fun acquireSingleSubtitleLink(
 | 
			
		||||
                links: List<SubtitleData>,
 | 
			
		||||
                title: String,
 | 
			
		||||
                callback: (SubtitleData) -> Unit
 | 
			
		||||
            ) {
 | 
			
		||||
                val builder = AlertDialog.Builder(requireContext(), R.style.AlertDialogCustom)
 | 
			
		||||
 | 
			
		||||
                builder.setTitle(title)
 | 
			
		||||
                builder.setItems(links.map { it.name }.toTypedArray()) { dia, which ->
 | 
			
		||||
                    callback.invoke(links[which])
 | 
			
		||||
                    dia?.dismiss()
 | 
			
		||||
                }
 | 
			
		||||
                builder.create().show()
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            fun acquireSingeExtractorLink(title: String, callback: (ExtractorLink) -> Unit) {
 | 
			
		||||
                acquireSingleExtractorLink(sortUrls(currentLinks ?: return), title, callback)
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			@ -839,6 +907,29 @@ class ResultFragment : Fragment(), PanelsChildGestureRegionObserver.GestureRegio
 | 
			
		|||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                ACTION_DOWNLOAD_EPISODE_SUBTITLE -> {
 | 
			
		||||
                    acquireSingleSubtitleLink(
 | 
			
		||||
                        sortSubs(
 | 
			
		||||
                            currentSubs ?: return@main
 | 
			
		||||
                        ),//(currentLinks ?: return@main).filter { !it.isM3u8 },
 | 
			
		||||
                        getString(R.string.episode_action_download_subtitle)
 | 
			
		||||
                    ) { link ->
 | 
			
		||||
                        downloadSubtitle(
 | 
			
		||||
                            context,
 | 
			
		||||
                            link,
 | 
			
		||||
                            getMeta(
 | 
			
		||||
                                episodeClick.data,
 | 
			
		||||
                                currentHeaderName ?: return@acquireSingleSubtitleLink,
 | 
			
		||||
                                apiName,
 | 
			
		||||
                                currentPoster ?: return@acquireSingleSubtitleLink,
 | 
			
		||||
                                currentIsMovie ?: return@acquireSingleSubtitleLink,
 | 
			
		||||
                                currentType ?: return@acquireSingleSubtitleLink
 | 
			
		||||
                            )
 | 
			
		||||
                        )
 | 
			
		||||
                        showToast(activity, R.string.download_started, Toast.LENGTH_SHORT)
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                ACTION_SHOW_OPTIONS -> {
 | 
			
		||||
                    context?.let { ctx ->
 | 
			
		||||
                        val builder = AlertDialog.Builder(ctx, R.style.AlertDialogCustom)
 | 
			
		||||
| 
						 | 
				
			
			@ -862,6 +953,7 @@ class ResultFragment : Fragment(), PanelsChildGestureRegionObserver.GestureRegio
 | 
			
		|||
                            val add = when (opv) {
 | 
			
		||||
                                ACTION_CHROME_CAST_EPISODE -> isConnected
 | 
			
		||||
                                ACTION_CHROME_CAST_MIRROR -> isConnected
 | 
			
		||||
                                ACTION_DOWNLOAD_EPISODE_SUBTITLE -> !currentSubs.isNullOrEmpty()
 | 
			
		||||
                                ACTION_DOWNLOAD_EPISODE -> hasDownloadSupport
 | 
			
		||||
                                ACTION_DOWNLOAD_MIRROR -> hasDownloadSupport
 | 
			
		||||
                                ACTION_PLAY_EPISODE_IN_VLC_PLAYER -> context?.isAppInstalled(
 | 
			
		||||
| 
						 | 
				
			
			@ -1015,21 +1107,20 @@ class ResultFragment : Fragment(), PanelsChildGestureRegionObserver.GestureRegio
 | 
			
		|||
                        ),//(currentLinks ?: return@main).filter { !it.isM3u8 },
 | 
			
		||||
                        getString(R.string.episode_action_download_mirror)
 | 
			
		||||
                    ) { link ->
 | 
			
		||||
                        main {
 | 
			
		||||
                            startDownload(
 | 
			
		||||
                                episodeClick.data,
 | 
			
		||||
                                currentIsMovie ?: return@main,
 | 
			
		||||
                                currentHeaderName ?: return@main,
 | 
			
		||||
                                currentType ?: return@main,
 | 
			
		||||
                                currentPoster ?: return@main,
 | 
			
		||||
                                apiName,
 | 
			
		||||
                                currentId ?: return@main,
 | 
			
		||||
                                url ?: return@main,
 | 
			
		||||
                                listOf(link),
 | 
			
		||||
                                sortSubs(currentSubs ?: return@main)
 | 
			
		||||
                            )
 | 
			
		||||
                            showToast(activity, R.string.download_started, Toast.LENGTH_SHORT)
 | 
			
		||||
                        }
 | 
			
		||||
                        startDownload(
 | 
			
		||||
                            context,
 | 
			
		||||
                            episodeClick.data,
 | 
			
		||||
                            currentIsMovie ?: return@acquireSingleExtractorLink,
 | 
			
		||||
                            currentHeaderName ?: return@acquireSingleExtractorLink,
 | 
			
		||||
                            currentType ?: return@acquireSingleExtractorLink,
 | 
			
		||||
                            currentPoster ?: return@acquireSingleExtractorLink,
 | 
			
		||||
                            apiName,
 | 
			
		||||
                            currentId ?: return@acquireSingleExtractorLink,
 | 
			
		||||
                            url ?: return@acquireSingleExtractorLink,
 | 
			
		||||
                            listOf(link),
 | 
			
		||||
                            sortSubs(currentSubs ?: return@acquireSingleExtractorLink),
 | 
			
		||||
                        )
 | 
			
		||||
                        showToast(activity, R.string.download_started, Toast.LENGTH_SHORT)
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -27,6 +27,7 @@ import com.lagradost.cloudstream3.AcraApplication.Companion.removeKey
 | 
			
		|||
import com.lagradost.cloudstream3.AcraApplication.Companion.setKey
 | 
			
		||||
import com.lagradost.cloudstream3.MainActivity
 | 
			
		||||
import com.lagradost.cloudstream3.R
 | 
			
		||||
import com.lagradost.cloudstream3.TvType
 | 
			
		||||
import com.lagradost.cloudstream3.mvvm.logError
 | 
			
		||||
import com.lagradost.cloudstream3.mvvm.normalSafeApiCall
 | 
			
		||||
import com.lagradost.cloudstream3.services.VideoDownloadService
 | 
			
		||||
| 
						 | 
				
			
			@ -116,7 +117,8 @@ object VideoDownloadManager {
 | 
			
		|||
        @JsonProperty("poster") val poster: String?,
 | 
			
		||||
        @JsonProperty("name") val name: String?,
 | 
			
		||||
        @JsonProperty("season") val season: Int?,
 | 
			
		||||
        @JsonProperty("episode") val episode: Int?
 | 
			
		||||
        @JsonProperty("episode") val episode: Int?,
 | 
			
		||||
        @JsonProperty("type") val type: TvType?,
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    data class DownloadItem(
 | 
			
		||||
| 
						 | 
				
			
			@ -1335,6 +1337,33 @@ object VideoDownloadManager {
 | 
			
		|||
        return SUCCESS_DOWNLOAD_DONE
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun getFileName(context: Context, metadata: DownloadEpisodeMetadata): String {
 | 
			
		||||
        return getFileName(context, metadata.name, metadata.episode, metadata.season)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun getFileName(context: Context, epName: String?, episode: Int?, season: Int?): String {
 | 
			
		||||
        // kinda ugly ik
 | 
			
		||||
        return sanitizeFilename(
 | 
			
		||||
            if (epName == null) {
 | 
			
		||||
                if (season != null) {
 | 
			
		||||
                    "${context.getString(R.string.season)} $season ${context.getString(R.string.episode)} $episode"
 | 
			
		||||
                } else {
 | 
			
		||||
                    "${context.getString(R.string.episode)} $episode"
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                if (episode != null) {
 | 
			
		||||
                    if (season != null) {
 | 
			
		||||
                        "${context.getString(R.string.season)} $season ${context.getString(R.string.episode)} $episode - $epName"
 | 
			
		||||
                    } else {
 | 
			
		||||
                        "${context.getString(R.string.episode)} $episode - $epName"
 | 
			
		||||
                    }
 | 
			
		||||
                } else {
 | 
			
		||||
                    epName
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun downloadSingleEpisode(
 | 
			
		||||
        context: Context,
 | 
			
		||||
        source: String?,
 | 
			
		||||
| 
						 | 
				
			
			@ -1344,19 +1373,7 @@ object VideoDownloadManager {
 | 
			
		|||
        notificationCallback: (Int, Notification) -> Unit,
 | 
			
		||||
        tryResume: Boolean = false,
 | 
			
		||||
    ): Int {
 | 
			
		||||
        val name =
 | 
			
		||||
            // kinda ugly ik
 | 
			
		||||
            sanitizeFilename(
 | 
			
		||||
                if (ep.name == null) {
 | 
			
		||||
                    "${context.getString(R.string.episode)} ${ep.episode}"
 | 
			
		||||
                } else {
 | 
			
		||||
                    if (ep.episode != null) {
 | 
			
		||||
                        "${context.getString(R.string.episode)} ${ep.episode} - ${ep.name}"
 | 
			
		||||
                    } else {
 | 
			
		||||
                        ep.name
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            )
 | 
			
		||||
        val name = getFileName(context, ep)
 | 
			
		||||
 | 
			
		||||
        // Make sure this is cancelled when download is done or cancelled.
 | 
			
		||||
        val extractorJob = ioSafe {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -150,8 +150,10 @@
 | 
			
		|||
        <item>@string/episode_action_copy_link</item>
 | 
			
		||||
        <item>@string/episode_action_auto_download</item>
 | 
			
		||||
        <item>@string/episode_action_download_mirror</item>
 | 
			
		||||
        <item>@string/episode_action_download_subtitle</item>
 | 
			
		||||
        <item>@string/episode_action_reload_links</item>
 | 
			
		||||
    </array>
 | 
			
		||||
 | 
			
		||||
    <array name="episode_long_click_options_values">
 | 
			
		||||
        <item>4</item>
 | 
			
		||||
        <item>5</item>
 | 
			
		||||
| 
						 | 
				
			
			@ -161,6 +163,7 @@
 | 
			
		|||
        <item>9</item>
 | 
			
		||||
        <item>6</item>
 | 
			
		||||
        <item>7</item>
 | 
			
		||||
        <item>13</item>
 | 
			
		||||
        <item>8</item>
 | 
			
		||||
    </array>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -304,15 +304,16 @@
 | 
			
		|||
    <string name="unexpected_error">Unexpected player error</string>
 | 
			
		||||
    <string name="storage_error">Download error, check storage permissions</string>
 | 
			
		||||
 | 
			
		||||
    <string name="episode_action_chromecast_episode">Chromecast Episode</string>
 | 
			
		||||
    <string name="episode_action_chromecast_mirror">Chromecast Mirror</string>
 | 
			
		||||
    <string name="episode_action_play_in_app">Play In App</string>
 | 
			
		||||
    <string name="episode_action_play_in_vlc">Play In VLC</string>
 | 
			
		||||
    <string name="episode_action_chromecast_episode">Chromecast episode</string>
 | 
			
		||||
    <string name="episode_action_chromecast_mirror">Chromecast mirror</string>
 | 
			
		||||
    <string name="episode_action_play_in_app">Play in app</string>
 | 
			
		||||
    <string name="episode_action_play_in_vlc">Play in VLC</string>
 | 
			
		||||
    <string name="episode_action_play_in_browser">Play in browser</string>
 | 
			
		||||
    <string name="episode_action_copy_link">Copy Link</string>
 | 
			
		||||
    <string name="episode_action_auto_download">Auto Download</string>
 | 
			
		||||
    <string name="episode_action_download_mirror">Download Mirror</string>
 | 
			
		||||
    <string name="episode_action_reload_links">Reload Links</string>
 | 
			
		||||
    <string name="episode_action_copy_link">Copy link</string>
 | 
			
		||||
    <string name="episode_action_auto_download">Auto download</string>
 | 
			
		||||
    <string name="episode_action_download_mirror">Download mirror</string>
 | 
			
		||||
    <string name="episode_action_reload_links">Reload links</string>
 | 
			
		||||
    <string name="episode_action_download_subtitle">Download subtitles</string>
 | 
			
		||||
 | 
			
		||||
    <string name="no_update_found">No Update Found</string>
 | 
			
		||||
    <string name="check_for_update">Check for Update</string>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue