implemented updating formats in the background worker

This commit is contained in:
deniscerri 2023-07-30 18:40:15 +02:00
parent 444f0cc582
commit 7191dc00f2
No known key found for this signature in database
GPG key ID: 95C43D517D830350
11 changed files with 220 additions and 54 deletions

View file

@ -60,7 +60,7 @@ import kotlin.random.nextInt
class DownloadViewModel(application: Application) : AndroidViewModel(application) { class DownloadViewModel(application: Application) : AndroidViewModel(application) {
private val dbManager: DBManager private val dbManager: DBManager
private val repository : DownloadRepository val repository : DownloadRepository
private val sharedPreferences: SharedPreferences private val sharedPreferences: SharedPreferences
private val commandTemplateDao: CommandTemplateDao private val commandTemplateDao: CommandTemplateDao
private val infoUtil : InfoUtil private val infoUtil : InfoUtil
@ -339,7 +339,7 @@ class DownloadViewModel(application: Application) : AndroidViewModel(application
} }
private fun getFormat(formats: List<Format>, type: Type) : Format { fun getFormat(formats: List<Format>, type: Type) : Format {
when(type) { when(type) {
Type.audio -> { Type.audio -> {
return cloneFormat ( return cloneFormat (
@ -539,7 +539,7 @@ class DownloadViewModel(application: Application) : AndroidViewModel(application
.build() .build()
workManager.enqueueUniqueWork( workManager.enqueueUniqueWork(
Random.nextInt(1000000000).toString(), it.id.toString(),
ExistingWorkPolicy.REPLACE, ExistingWorkPolicy.REPLACE,
workRequest workRequest
) )

View file

@ -3,6 +3,7 @@ package com.deniscerri.ytdlnis.receiver
import android.content.BroadcastReceiver import android.content.BroadcastReceiver
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import androidx.work.WorkManager
import com.deniscerri.ytdlnis.database.DBManager import com.deniscerri.ytdlnis.database.DBManager
import com.deniscerri.ytdlnis.database.repository.DownloadRepository import com.deniscerri.ytdlnis.database.repository.DownloadRepository
import com.deniscerri.ytdlnis.util.NotificationUtil import com.deniscerri.ytdlnis.util.NotificationUtil
@ -19,14 +20,17 @@ class CancelDownloadNotificationReceiver : BroadcastReceiver() {
if (message != null) { if (message != null) {
runCatching { runCatching {
val notificationUtil = NotificationUtil(c) val notificationUtil = NotificationUtil(c)
WorkManager.getInstance(c).cancelUniqueWork(id.toString())
notificationUtil.cancelDownloadNotification(id) notificationUtil.cancelDownloadNotification(id)
YoutubeDL.getInstance().destroyProcessById(id.toString()) YoutubeDL.getInstance().destroyProcessById(id.toString())
val dbManager = DBManager.getInstance(c) val dbManager = DBManager.getInstance(c)
CoroutineScope(Dispatchers.IO).launch{ CoroutineScope(Dispatchers.IO).launch{
val item = dbManager.downloadDao.getDownloadById(id.toLong()) runCatching {
item.status = DownloadRepository.Status.Cancelled.toString() val item = dbManager.downloadDao.getDownloadById(id.toLong())
dbManager.downloadDao.update(item) item.status = DownloadRepository.Status.Cancelled.toString()
dbManager.downloadDao.update(item)
}
} }
} }

View file

@ -31,6 +31,7 @@ import androidx.recyclerview.widget.RecyclerView
import com.deniscerri.ytdlnis.MainActivity import com.deniscerri.ytdlnis.MainActivity
import com.deniscerri.ytdlnis.R import com.deniscerri.ytdlnis.R
import com.deniscerri.ytdlnis.adapter.HomeAdapter import com.deniscerri.ytdlnis.adapter.HomeAdapter
import com.deniscerri.ytdlnis.database.models.DownloadItem
import com.deniscerri.ytdlnis.database.models.ResultItem import com.deniscerri.ytdlnis.database.models.ResultItem
import com.deniscerri.ytdlnis.database.viewmodel.DownloadViewModel import com.deniscerri.ytdlnis.database.viewmodel.DownloadViewModel
import com.deniscerri.ytdlnis.database.viewmodel.ResultViewModel import com.deniscerri.ytdlnis.database.viewmodel.ResultViewModel
@ -50,6 +51,7 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
import com.google.android.material.search.SearchBar import com.google.android.material.search.SearchBar
import com.google.android.material.search.SearchView import com.google.android.material.search.SearchView
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
@ -232,6 +234,18 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, OnClickListene
} }
} }
if (arguments?.getBoolean("showDownloadsWithUpdatedFormats") == true){
CoroutineScope(Dispatchers.IO).launch {
val ids = arguments?.getLongArray("downloadIds")
val items = mutableListOf<DownloadItem>()
ids?.forEach {
items.add(downloadViewModel.getItemByID(it))
}
val bottomSheet = DownloadMultipleBottomSheetDialog(items.toMutableList())
bottomSheet.show(parentFragmentManager, "downloadMultipleSheet")
}
}
} }
override fun onResume() { override fun onResume() {
@ -239,7 +253,9 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, OnClickListene
if(arguments?.getString("url") == null){ if(arguments?.getString("url") == null){
resultViewModel.checkTrending() resultViewModel.checkTrending()
}else{ }else{
arguments
arguments?.remove("url") arguments?.remove("url")
arguments?.remove("showDownloadsWithUpdatedFormats")
} }
if (searchView?.currentTransitionState == SearchView.TransitionState.SHOWN){ if (searchView?.currentTransitionState == SearchView.TransitionState.SHOWN){
lifecycleScope.launch { lifecycleScope.launch {
@ -612,7 +628,7 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, OnClickListene
downloadViewModel.turnResultItemsToDownloadItems(resultsList!!) downloadViewModel.turnResultItemsToDownloadItems(resultsList!!)
} }
if (sharedPreferences!!.getBoolean("download_card", true)) { if (sharedPreferences!!.getBoolean("download_card", true)) {
val bottomSheet = DownloadMultipleBottomSheetDialog(resultsList!!, downloadList.toMutableList()) val bottomSheet = DownloadMultipleBottomSheetDialog(downloadList.toMutableList())
bottomSheet.show(parentFragmentManager, "downloadMultipleSheet") bottomSheet.show(parentFragmentManager, "downloadMultipleSheet")
} else { } else {
downloadViewModel.queueDownloads(downloadList) downloadViewModel.queueDownloads(downloadList)
@ -673,7 +689,7 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, OnClickListene
if (selectedObjects!!.size == 1){ if (selectedObjects!!.size == 1){
showSingleDownloadSheet(selectedObjects!![0], DownloadViewModel.Type.valueOf(sharedPreferences!!.getString("preferred_download_type", "video")!!), false) showSingleDownloadSheet(selectedObjects!![0], DownloadViewModel.Type.valueOf(sharedPreferences!!.getString("preferred_download_type", "video")!!), false)
}else{ }else{
val bottomSheet = DownloadMultipleBottomSheetDialog(selectedObjects!!, downloadList.toMutableList()) val bottomSheet = DownloadMultipleBottomSheetDialog(downloadList.toMutableList())
bottomSheet.show(parentFragmentManager, "downloadMultipleSheet") bottomSheet.show(parentFragmentManager, "downloadMultipleSheet")
} }
} else { } else {

View file

@ -33,11 +33,14 @@ import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import androidx.work.Data
import androidx.work.ExistingWorkPolicy
import androidx.work.OneTimeWorkRequestBuilder
import androidx.work.WorkManager
import com.deniscerri.ytdlnis.R import com.deniscerri.ytdlnis.R
import com.deniscerri.ytdlnis.adapter.ConfigureMultipleDownloadsAdapter import com.deniscerri.ytdlnis.adapter.ConfigureMultipleDownloadsAdapter
import com.deniscerri.ytdlnis.database.models.DownloadItem import com.deniscerri.ytdlnis.database.models.DownloadItem
import com.deniscerri.ytdlnis.database.models.Format import com.deniscerri.ytdlnis.database.models.Format
import com.deniscerri.ytdlnis.database.models.ResultItem
import com.deniscerri.ytdlnis.database.repository.DownloadRepository import com.deniscerri.ytdlnis.database.repository.DownloadRepository
import com.deniscerri.ytdlnis.database.viewmodel.CommandTemplateViewModel import com.deniscerri.ytdlnis.database.viewmodel.CommandTemplateViewModel
import com.deniscerri.ytdlnis.database.viewmodel.DownloadViewModel import com.deniscerri.ytdlnis.database.viewmodel.DownloadViewModel
@ -45,6 +48,7 @@ import com.deniscerri.ytdlnis.database.viewmodel.ResultViewModel
import com.deniscerri.ytdlnis.receiver.ShareActivity import com.deniscerri.ytdlnis.receiver.ShareActivity
import com.deniscerri.ytdlnis.util.FileUtil import com.deniscerri.ytdlnis.util.FileUtil
import com.deniscerri.ytdlnis.util.UiUtil import com.deniscerri.ytdlnis.util.UiUtil
import com.deniscerri.ytdlnis.work.UpdatePlaylistFormatsWorker
import com.google.android.material.bottomappbar.BottomAppBar import com.google.android.material.bottomappbar.BottomAppBar
import com.google.android.material.bottomsheet.BottomSheetBehavior import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialog import com.google.android.material.bottomsheet.BottomSheetDialog
@ -62,7 +66,7 @@ import kotlinx.coroutines.withContext
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Locale import java.util.Locale
class DownloadMultipleBottomSheetDialog(private var results: List<ResultItem?>, private var items: MutableList<DownloadItem>) : BottomSheetDialogFragment(), ConfigureMultipleDownloadsAdapter.OnItemClickListener, View.OnClickListener, class DownloadMultipleBottomSheetDialog(private var items: MutableList<DownloadItem>) : BottomSheetDialogFragment(), ConfigureMultipleDownloadsAdapter.OnItemClickListener, View.OnClickListener,
ConfigureDownloadBottomSheetDialog.OnDownloadItemUpdateListener { ConfigureDownloadBottomSheetDialog.OnDownloadItemUpdateListener {
private lateinit var downloadViewModel: DownloadViewModel private lateinit var downloadViewModel: DownloadViewModel
private lateinit var commandTemplateViewModel: CommandTemplateViewModel private lateinit var commandTemplateViewModel: CommandTemplateViewModel
@ -193,6 +197,35 @@ class DownloadMultipleBottomSheetDialog(private var results: List<ResultItem?>,
listAdapter.submitList(items.toList()) listAdapter.submitList(items.toList())
listAdapter.notifyDataSetChanged() listAdapter.notifyDataSetChanged()
} }
override fun onContinueOnBackground(items: List<DownloadItem?>) {
requireActivity().lifecycleScope.launch {
val ids = mutableListOf<Long>()
runBlocking {
items.map { it!!.status = DownloadRepository.Status.Saved.toString() }
items.forEach {
ids.add(downloadViewModel.repository.insert(it!!))
}
}
val id = System.currentTimeMillis().toInt()
val workRequest = OneTimeWorkRequestBuilder<UpdatePlaylistFormatsWorker>()
.setInputData(
Data.Builder()
.putLongArray("ids", ids.toLongArray())
.putInt("id", id)
.build())
.addTag("updateFormats")
.build()
WorkManager.getInstance(requireContext()).enqueueUniqueWork(
id.toString(),
ExistingWorkPolicy.REPLACE,
workRequest
)
}
}
} }
bottomAppBar.setOnMenuItemClickListener { m: MenuItem -> bottomAppBar.setOnMenuItemClickListener { m: MenuItem ->

View file

@ -22,6 +22,7 @@ import com.facebook.shimmer.ShimmerFrameLayout
import com.google.android.material.bottomsheet.BottomSheetBehavior import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialogFragment import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import com.google.android.material.card.MaterialCardView import com.google.android.material.card.MaterialCardView
import com.google.android.material.snackbar.Snackbar
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
@ -45,6 +46,10 @@ class FormatSelectionBottomSheetDialog(private val items: List<DownloadItem?>, p
private lateinit var audioTitle : TextView private lateinit var audioTitle : TextView
private lateinit var sortBy : FormatSorting private lateinit var sortBy : FormatSorting
private lateinit var continueInBackgroundSnackBar : Snackbar
private lateinit var view: View
enum class FormatSorting { enum class FormatSorting {
filesize, container, id filesize, container, id
} }
@ -62,7 +67,7 @@ class FormatSelectionBottomSheetDialog(private val items: List<DownloadItem?>, p
@SuppressLint("RestrictedApi") @SuppressLint("RestrictedApi")
override fun setupDialog(dialog: Dialog, style: Int) { override fun setupDialog(dialog: Dialog, style: Int) {
super.setupDialog(dialog, style) super.setupDialog(dialog, style)
val view = LayoutInflater.from(context).inflate(R.layout.format_select_bottom_sheet, null) view = LayoutInflater.from(context).inflate(R.layout.format_select_bottom_sheet, null)
dialog.setContentView(view) dialog.setContentView(view)
sortBy = FormatSorting.valueOf(sharedPreferences.getString("format_order", "filesize")!!) sortBy = FormatSorting.valueOf(sharedPreferences.getString("format_order", "filesize")!!)
@ -121,6 +126,16 @@ class FormatSelectionBottomSheetDialog(private val items: List<DownloadItem?>, p
refreshBtn.setOnClickListener { refreshBtn.setOnClickListener {
lifecycleScope.launch { lifecycleScope.launch {
if (items.size > 10){
continueInBackgroundSnackBar = Snackbar.make(view, R.string.update_formats_background, Snackbar.LENGTH_INDEFINITE)
continueInBackgroundSnackBar.setAction(R.string.ok) {
listener.onContinueOnBackground(items)
this@FormatSelectionBottomSheetDialog.dismiss()
}
continueInBackgroundSnackBar.show()
}
chosenFormats = emptyList() chosenFormats = emptyList()
try { try {
refreshBtn.isEnabled = false refreshBtn.isEnabled = false
@ -333,6 +348,7 @@ class FormatSelectionBottomSheetDialog(private val items: List<DownloadItem?>, p
interface OnFormatClickListener{ interface OnFormatClickListener{
fun onFormatClick(allFormats: List<List<Format>>, item: List<FormatTuple>) fun onFormatClick(allFormats: List<List<Format>>, item: List<FormatTuple>)
fun onContinueOnBackground(items : List<DownloadItem?>) {}
} }
class FormatTuple internal constructor( class FormatTuple internal constructor(

View file

@ -157,7 +157,7 @@ class SelectPlaylistItemsBottomSheetDialog(private val items: List<ResultItem?>,
downloadItems.add(i) downloadItems.add(i)
} }
val bottomSheet = DownloadMultipleBottomSheetDialog(items, downloadItems) val bottomSheet = DownloadMultipleBottomSheetDialog(downloadItems)
bottomSheet.show(parentFragmentManager, "downloadMultipleSheet") bottomSheet.show(parentFragmentManager, "downloadMultipleSheet")
} }

View file

@ -138,7 +138,7 @@ class ActiveDownloadsFragment : Fragment(), ActiveDownloadAdapter.OnItemClickLis
it.forEach{item -> it.forEach{item ->
WorkManager.getInstance(requireContext()) WorkManager.getInstance(requireContext())
.getWorkInfosByTagLiveData(item.id.toString()) .getWorkInfosForUniqueWorkLiveData(item.id.toString())
.observe(viewLifecycleOwner){ list -> .observe(viewLifecycleOwner){ list ->
list.forEach {work -> list.forEach {work ->
if (work == null) return@observe if (work == null) return@observe

View file

@ -19,7 +19,6 @@ import com.deniscerri.ytdlnis.receiver.PauseDownloadNotificationReceiver
import com.deniscerri.ytdlnis.receiver.ResumeActivity import com.deniscerri.ytdlnis.receiver.ResumeActivity
import com.deniscerri.ytdlnis.receiver.ShareFileActivity import com.deniscerri.ytdlnis.receiver.ShareFileActivity
import java.io.File import java.io.File
import kotlin.math.log
class NotificationUtil(var context: Context) { class NotificationUtil(var context: Context) {
@ -342,12 +341,95 @@ class NotificationUtil(var context: Context) {
} }
} }
fun showYTDLUpdateNotification() : Notification{ fun createYTDLUpdateNotification() : Notification{
val notificationBuilder = getBuilder(DOWNLOAD_MISC_CHANNEL_ID) val notificationBuilder = getBuilder(DOWNLOAD_MISC_CHANNEL_ID)
notificationBuilder.setContentTitle("Updating YT-DLP...") notificationBuilder.setContentTitle("Updating YT-DLP...")
return notificationBuilder.build() return notificationBuilder.build()
} }
fun createFormatsUpdateNotification(workID: Int): Notification {
val notificationBuilder = getBuilder(DOWNLOAD_MISC_CHANNEL_ID)
val cancelIntent = Intent(context, CancelDownloadNotificationReceiver::class.java)
cancelIntent.putExtra("cancel", "")
cancelIntent.putExtra("workID", workID)
val cancelNotificationPendingIntent = PendingIntent.getBroadcast(
context,
workID,
cancelIntent,
PendingIntent.FLAG_IMMUTABLE
)
return notificationBuilder
.setContentTitle(context.getString(R.string.update_formats_background))
.setOngoing(true)
.setCategory(Notification.CATEGORY_PROGRESS)
.setSmallIcon(android.R.drawable.stat_sys_download)
.setLargeIcon(
BitmapFactory.decodeResource(
context.resources,
android.R.drawable.stat_sys_download
)
)
.setContentText("")
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setProgress(PROGRESS_MAX, PROGRESS_CURR, false)
.setForegroundServiceBehavior(NotificationCompat.FOREGROUND_SERVICE_IMMEDIATE)
.clearActions()
.addAction(0, context.getString(R.string.cancel), cancelNotificationPendingIntent)
.build()
}
fun updateFormatUpdateNotification(
id: Int,
progress: Int,
queue: Int,
) {
val notificationBuilder = getBuilder(DOWNLOAD_MISC_CHANNEL_ID)
val contentText = """${queue - progress} ${context.getString(R.string.items_left)}"""
try {
notificationBuilder.setProgress(queue, progress, false)
.setContentTitle(context.getString(R.string.update_formats_background))
.setStyle(NotificationCompat.BigTextStyle().bigText(contentText))
notificationManager.notify(id, notificationBuilder.build())
} catch (e: Exception) {
e.printStackTrace()
}
}
fun showFormatsUpdatedNotification(downloadIds: List<Long>) {
val notificationBuilder = getBuilder(DOWNLOAD_FINISHED_CHANNEL_ID)
val bundle = Bundle()
bundle.putBoolean("showDownloadsWithUpdatedFormats", true)
bundle.putLongArray("downloadIds", downloadIds.toLongArray())
val openMultipleDownloads = NavDeepLinkBuilder(context)
.setGraph(R.navigation.nav_graph)
.setDestination(R.id.homeFragment)
.setArguments(bundle)
.createPendingIntent()
notificationBuilder
.setContentTitle(context.getString(R.string.finished_download_notification_channel_name))
.setSmallIcon(R.drawable.ic_launcher_foreground_large)
.setLargeIcon(
BitmapFactory.decodeResource(
context.resources,
R.drawable.ic_launcher_foreground_large
)
)
.setContentIntent(openMultipleDownloads)
.setPriority(NotificationCompat.PRIORITY_MAX)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.clearActions()
notificationManager.notify(FORMAT_UPDATING_FINISHED_NOTIFICATION_ID, notificationBuilder.build())
}
companion object { companion object {
const val DOWNLOAD_SERVICE_CHANNEL_ID = "1" const val DOWNLOAD_SERVICE_CHANNEL_ID = "1"
const val COMMAND_DOWNLOAD_SERVICE_CHANNEL_ID = "2" const val COMMAND_DOWNLOAD_SERVICE_CHANNEL_ID = "2"
@ -355,6 +437,8 @@ class NotificationUtil(var context: Context) {
const val DOWNLOAD_FINISHED_NOTIFICATION_ID = 3 const val DOWNLOAD_FINISHED_NOTIFICATION_ID = 3
const val DOWNLOAD_RESUME_NOTIFICATION_ID = 4 const val DOWNLOAD_RESUME_NOTIFICATION_ID = 4
const val DOWNLOAD_UPDATING_NOTIFICATION_ID = 5 const val DOWNLOAD_UPDATING_NOTIFICATION_ID = 5
const val FORMAT_UPDATING_NOTIFICATION_ID = 6
const val FORMAT_UPDATING_FINISHED_NOTIFICATION_ID = 7
const val DOWNLOAD_MISC_CHANNEL_ID = "4" const val DOWNLOAD_MISC_CHANNEL_ID = "4"
const val DOWNLOAD_MISC_NOTIFICATION_ID = 4 const val DOWNLOAD_MISC_NOTIFICATION_ID = 4
private const val PROGRESS_MAX = 100 private const val PROGRESS_MAX = 100

View file

@ -5,6 +5,7 @@ import android.os.Handler
import android.os.Looper import android.os.Looper
import android.util.Log import android.util.Log
import android.widget.Toast import android.widget.Toast
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.NavDeepLinkBuilder import androidx.navigation.NavDeepLinkBuilder
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import androidx.work.CoroutineWorker import androidx.work.CoroutineWorker
@ -13,6 +14,7 @@ import androidx.work.ForegroundInfo
import androidx.work.Worker import androidx.work.Worker
import androidx.work.WorkerParameters import androidx.work.WorkerParameters
import androidx.work.workDataOf import androidx.work.workDataOf
import com.deniscerri.ytdlnis.App
import com.deniscerri.ytdlnis.R import com.deniscerri.ytdlnis.R
import com.deniscerri.ytdlnis.database.Converters import com.deniscerri.ytdlnis.database.Converters
import com.deniscerri.ytdlnis.database.DBManager import com.deniscerri.ytdlnis.database.DBManager
@ -23,13 +25,16 @@ import com.deniscerri.ytdlnis.database.models.HistoryItem
import com.deniscerri.ytdlnis.database.models.LogItem import com.deniscerri.ytdlnis.database.models.LogItem
import com.deniscerri.ytdlnis.database.repository.DownloadRepository import com.deniscerri.ytdlnis.database.repository.DownloadRepository
import com.deniscerri.ytdlnis.database.repository.LogRepository import com.deniscerri.ytdlnis.database.repository.LogRepository
import com.deniscerri.ytdlnis.database.viewmodel.DownloadViewModel
import com.deniscerri.ytdlnis.util.FileUtil import com.deniscerri.ytdlnis.util.FileUtil
import com.deniscerri.ytdlnis.util.InfoUtil import com.deniscerri.ytdlnis.util.InfoUtil
import com.deniscerri.ytdlnis.util.NotificationUtil import com.deniscerri.ytdlnis.util.NotificationUtil
import com.deniscerri.ytdlnis.util.NotificationUtil.Companion.FORMAT_UPDATING_NOTIFICATION_ID
import com.deniscerri.ytdlnis.util.UpdateUtil import com.deniscerri.ytdlnis.util.UpdateUtil
import com.yausername.youtubedl_android.YoutubeDL import com.yausername.youtubedl_android.YoutubeDL
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import java.io.File import java.io.File
@ -41,24 +46,56 @@ class UpdatePlaylistFormatsWorker(
) : CoroutineWorker(context, workerParams) { ) : CoroutineWorker(context, workerParams) {
override suspend fun doWork(): Result { override suspend fun doWork(): Result {
val dbManager = DBManager.getInstance(context) val dbManager = DBManager.getInstance(context)
val resultDao = dbManager.resultDao val dao = dbManager.downloadDao
val resDao = dbManager.resultDao
val infoUtil = InfoUtil(context) val infoUtil = InfoUtil(context)
val converters = Converters() val vm = DownloadViewModel(App.instance)
val urls = inputData.getStringArray("urls")!!.toMutableList() val notificationUtil = NotificationUtil(context)
val ids = inputData.getLongArray("ids")!!.toMutableList()
val workID = inputData.getInt("id", 0)
if (workID == 0) return Result.failure()
infoUtil.getFormatsMultiple(urls){ val notification = notificationUtil.createFormatsUpdateNotification(workID)
val formatStrings = mutableListOf<String>() val foregroundInfo = ForegroundInfo(FORMAT_UPDATING_NOTIFICATION_ID, notification)
it.forEach { i -> formatStrings.add(converters.formatToString(i)) } setForeground(foregroundInfo)
setProgressAsync(workDataOf("formats" to formatStrings.toTypedArray()))
CoroutineScope(Dispatchers.IO).launch { var count = 0
val result = resultDao.getResultByURL(urls.removeFirst()) ids.forEach {
val formats = infoUtil.getFormats(result.url) if (!isStopped){
result.formats = ArrayList(formats) val d = dao.getDownloadById(it)
resultDao.update(result) val r = resDao.getResultByURL(d.url)
if (d.allFormats.isNotEmpty()){
count++
return@forEach
}
runCatching {
d.allFormats.clear()
d.allFormats.addAll(infoUtil.getFormats(d.url))
d.format = vm.getFormat(d.allFormats,d.type)
r.formats.clear()
r.formats.addAll(d.allFormats)
dao.update(d)
resDao.update(r)
}
count++
notificationUtil.updateFormatUpdateNotification(FORMAT_UPDATING_NOTIFICATION_ID, count, ids.size)
}else{
notificationUtil.cancelDownloadNotification(FORMAT_UPDATING_NOTIFICATION_ID)
} }
} }
runBlocking {
notificationUtil.showFormatsUpdatedNotification(ids)
}
return Result.success() return Result.success()
} }
} }

View file

@ -1,37 +1,11 @@
package com.deniscerri.ytdlnis.work package com.deniscerri.ytdlnis.work
import android.content.Context import android.content.Context
import android.os.Handler
import android.os.Looper
import android.util.Log
import android.widget.Toast
import androidx.navigation.NavDeepLinkBuilder
import androidx.preference.PreferenceManager
import androidx.work.CoroutineWorker import androidx.work.CoroutineWorker
import androidx.work.Data
import androidx.work.ForegroundInfo import androidx.work.ForegroundInfo
import androidx.work.Worker
import androidx.work.WorkerParameters import androidx.work.WorkerParameters
import androidx.work.workDataOf
import com.deniscerri.ytdlnis.R
import com.deniscerri.ytdlnis.database.DBManager
import com.deniscerri.ytdlnis.database.dao.DownloadDao
import com.deniscerri.ytdlnis.database.dao.ResultDao
import com.deniscerri.ytdlnis.database.models.DownloadItem
import com.deniscerri.ytdlnis.database.models.HistoryItem
import com.deniscerri.ytdlnis.database.models.LogItem
import com.deniscerri.ytdlnis.database.repository.DownloadRepository
import com.deniscerri.ytdlnis.database.repository.LogRepository
import com.deniscerri.ytdlnis.util.FileUtil
import com.deniscerri.ytdlnis.util.InfoUtil
import com.deniscerri.ytdlnis.util.NotificationUtil import com.deniscerri.ytdlnis.util.NotificationUtil
import com.deniscerri.ytdlnis.util.UpdateUtil import com.deniscerri.ytdlnis.util.UpdateUtil
import com.yausername.youtubedl_android.YoutubeDL
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import java.io.File
class UpdateYTDLWorker( class UpdateYTDLWorker(
@ -39,7 +13,7 @@ class UpdateYTDLWorker(
workerParams: WorkerParameters workerParams: WorkerParameters
) : CoroutineWorker(context, workerParams) { ) : CoroutineWorker(context, workerParams) {
override suspend fun doWork(): Result { override suspend fun doWork(): Result {
val notification = NotificationUtil(context).showYTDLUpdateNotification() val notification = NotificationUtil(context).createYTDLUpdateNotification()
val foregroundInfo = ForegroundInfo(System.currentTimeMillis().toInt(), notification) val foregroundInfo = ForegroundInfo(System.currentTimeMillis().toInt(), notification)
setForeground(foregroundInfo) setForeground(foregroundInfo)
UpdateUtil(context).updateYoutubeDL() UpdateUtil(context).updateYoutubeDL()

View file

@ -300,4 +300,6 @@
<string name="use_cookies">Use Cookies</string> <string name="use_cookies">Use Cookies</string>
<string name="embed_metadata">Embed Metadata</string> <string name="embed_metadata">Embed Metadata</string>
<string name="embed_metadata_summary">Embed metadata to the video file. Also embeds chapters/infojson if present</string> <string name="embed_metadata_summary">Embed metadata to the video file. Also embeds chapters/infojson if present</string>
<string name="formats_updated">Formats have been updated</string>
<string name="update_formats_background">Update Formats in Background</string>
</resources> </resources>