reverted terminal mode to rxjava for simplicity sake
This commit is contained in:
parent
5482105a18
commit
3937dd6e4c
6 changed files with 142 additions and 99 deletions
|
|
@ -38,8 +38,7 @@ class Converters {
|
|||
return when(string){
|
||||
"audio" -> DownloadViewModel.Type.audio
|
||||
"video" -> DownloadViewModel.Type.video
|
||||
"command" -> DownloadViewModel.Type.command
|
||||
else -> DownloadViewModel.Type.terminal
|
||||
else -> DownloadViewModel.Type.command
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -52,7 +52,4 @@ interface DownloadDao {
|
|||
|
||||
@Query("SELECT * FROM downloads WHERE url=:url AND format=:format AND (status='Error' OR status='Cancelled') LIMIT 1")
|
||||
fun getUnfinishedByURLAndFormat(url: String, format: String) : DownloadItem
|
||||
|
||||
@Query("SELECT * FROM downloads WHERE type='terminal' ORDER BY id DESC LIMIT 1")
|
||||
fun getTerminalDownload() : DownloadItem
|
||||
}
|
||||
|
|
@ -65,7 +65,4 @@ class DownloadRepository(private val downloadDao: DownloadDao) {
|
|||
}
|
||||
}
|
||||
|
||||
fun getTerminalDownload() : Long {
|
||||
return downloadDao.getTerminalDownload().id
|
||||
}
|
||||
}
|
||||
|
|
@ -37,7 +37,7 @@ class DownloadViewModel(application: Application) : AndroidViewModel(application
|
|||
private var bestVideoFormat : Format
|
||||
private var bestAudioFormat : Format
|
||||
enum class Type {
|
||||
audio, video, command, terminal
|
||||
audio, video, command
|
||||
}
|
||||
|
||||
init {
|
||||
|
|
@ -204,39 +204,4 @@ class DownloadViewModel(application: Application) : AndroidViewModel(application
|
|||
}
|
||||
}
|
||||
|
||||
fun startTerminalDownload(command: String) = viewModelScope.launch(Dispatchers.IO) {
|
||||
val downloadPath = sharedPreferences.getString("command_path", getApplication<App>().resources.getString(R.string.command_path))
|
||||
val downloadItem = DownloadItem(0,
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
Type.terminal,
|
||||
Format("", "", 0, command),
|
||||
downloadPath!!, "", "", "", AudioPreferences(), VideoPreferences(), "", false, DownloadRepository.Status.Processing.toString(), 0
|
||||
)
|
||||
|
||||
downloadItem.status = DownloadRepository.Status.Queued.toString()
|
||||
Log.e("aaaaaaaa", downloadItem.toString())
|
||||
val id = repository.insert(downloadItem)
|
||||
downloadItem.id = id
|
||||
|
||||
val workRequest = OneTimeWorkRequestBuilder<DownloadWorker>()
|
||||
.setInputData(Data.Builder().putLong("id", downloadItem.id).build())
|
||||
.addTag("terminal")
|
||||
.build()
|
||||
val context = getApplication<App>().applicationContext
|
||||
WorkManager.getInstance(context).beginUniqueWork(
|
||||
downloadItem.id.toString(),
|
||||
ExistingWorkPolicy.KEEP,
|
||||
workRequest
|
||||
).enqueue()
|
||||
}
|
||||
|
||||
|
||||
fun getTerminalDownload(): Long {
|
||||
return repository.getTerminalDownload();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
package com.deniscerri.ytdlnis.ui
|
||||
|
||||
import android.Manifest
|
||||
import android.app.Notification
|
||||
import android.app.PendingIntent
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
|
|
@ -10,36 +12,36 @@ import android.view.View
|
|||
import android.widget.EditText
|
||||
import android.widget.ScrollView
|
||||
import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.app.ActivityCompat
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.core.app.NotificationManagerCompat
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.work.WorkInfo
|
||||
import androidx.work.WorkManager
|
||||
import com.deniscerri.ytdlnis.R
|
||||
import com.deniscerri.ytdlnis.database.viewmodel.DownloadViewModel
|
||||
import com.deniscerri.ytdlnis.service.IDownloaderService
|
||||
import com.deniscerri.ytdlnis.util.FileUtil
|
||||
import com.deniscerri.ytdlnis.util.NotificationUtil
|
||||
import com.deniscerri.ytdlnis.work.DownloadWorker
|
||||
import com.google.android.material.appbar.MaterialToolbar
|
||||
import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
|
||||
import com.yausername.youtubedl_android.YoutubeDL
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import com.yausername.youtubedl_android.YoutubeDLRequest
|
||||
import io.reactivex.Observable
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
import io.reactivex.disposables.Disposable
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.io.File
|
||||
import java.util.regex.Pattern
|
||||
|
||||
|
||||
class CustomCommandActivity : AppCompatActivity() {
|
||||
private var topAppBar: MaterialToolbar? = null
|
||||
private lateinit var downloadViewModel: DownloadViewModel
|
||||
private lateinit var notificationUtil: NotificationUtil
|
||||
private lateinit var workManager: WorkManager
|
||||
private var isDownloadServiceRunning = false
|
||||
private var output: TextView? = null
|
||||
private var input: EditText? = null
|
||||
private var fab: ExtendedFloatingActionButton? = null
|
||||
private var cancelFab: ExtendedFloatingActionButton? = null
|
||||
private var iDownloaderService: IDownloaderService? = null
|
||||
private var scrollView: ScrollView? = null
|
||||
var context: Context? = null
|
||||
|
||||
|
|
@ -56,6 +58,9 @@ class CustomCommandActivity : AppCompatActivity() {
|
|||
input!!.requestFocus()
|
||||
fab = findViewById(R.id.command_fab)
|
||||
fab!!.setOnClickListener {
|
||||
input!!.isEnabled = false
|
||||
output!!.text = ""
|
||||
swapFabs()
|
||||
startDownload(
|
||||
input!!.text.toString()
|
||||
)
|
||||
|
|
@ -65,9 +70,7 @@ class CustomCommandActivity : AppCompatActivity() {
|
|||
cancelDownload()
|
||||
input!!.isEnabled = true
|
||||
}
|
||||
downloadViewModel = ViewModelProvider(this)[DownloadViewModel::class.java]
|
||||
notificationUtil = NotificationUtil(this)
|
||||
workManager = WorkManager.getInstance(this)
|
||||
handleIntent(intent)
|
||||
}
|
||||
|
||||
|
|
@ -88,33 +91,141 @@ class CustomCommandActivity : AppCompatActivity() {
|
|||
}
|
||||
|
||||
|
||||
private fun swapFabs() {
|
||||
val cancel = cancelFab!!.visibility
|
||||
val start = fab!!.visibility
|
||||
cancelFab!!.visibility = start
|
||||
fab!!.visibility = cancel
|
||||
}
|
||||
|
||||
|
||||
private fun startDownload(command: String?) {
|
||||
if (isDownloadServiceRunning) return
|
||||
downloadViewModel.startTerminalDownload(command!!)
|
||||
output!!.text = ""
|
||||
workManager.getWorkInfosByTagLiveData("terminal")
|
||||
.observe(this){ list ->
|
||||
list.forEach {
|
||||
if(it.progress.getString("output") != null){
|
||||
output?.append("\n" + it.progress.getString("output") + "\n")
|
||||
output?.scrollTo(0, output!!.height)
|
||||
scrollView?.fullScroll(View.FOCUS_DOWN)
|
||||
downloadID = System.currentTimeMillis().toInt()
|
||||
|
||||
val theIntent = Intent(this, CustomCommandActivity::class.java)
|
||||
val pendingIntent = PendingIntent.getActivity(this, 0, theIntent, PendingIntent.FLAG_IMMUTABLE)
|
||||
|
||||
val commandNotification: Notification =
|
||||
notificationUtil.createDownloadServiceNotification(
|
||||
pendingIntent,
|
||||
getString(R.string.terminal),
|
||||
downloadID,
|
||||
NotificationUtil.COMMAND_DOWNLOAD_SERVICE_CHANNEL_ID
|
||||
)
|
||||
with(NotificationManagerCompat.from(this)){
|
||||
if (ActivityCompat.checkSelfPermission(
|
||||
context!!,
|
||||
Manifest.permission.POST_NOTIFICATIONS
|
||||
) == PackageManager.PERMISSION_GRANTED
|
||||
) {
|
||||
notify(downloadID, commandNotification)
|
||||
}
|
||||
}
|
||||
|
||||
val commandRegex = "\"([^\"]*)\"|(\\S+)"
|
||||
val request = YoutubeDLRequest(emptyList())
|
||||
|
||||
val tempFolder = StringBuilder(context!!.cacheDir.absolutePath + """/${command}##terminal""")
|
||||
val tempFileDir = File(tempFolder.toString())
|
||||
tempFileDir.delete()
|
||||
tempFileDir.mkdir()
|
||||
|
||||
|
||||
val m = Pattern.compile(commandRegex).matcher(command!!)
|
||||
while (m.find()) {
|
||||
if (m.group(1) != null) {
|
||||
request.addOption(m.group(1)!!)
|
||||
} else {
|
||||
request.addOption(m.group(2)!!)
|
||||
}
|
||||
}
|
||||
|
||||
request.addOption("-o", tempFileDir.absolutePath + "/%(uploader)s - %(title)s.%(ext)s")
|
||||
|
||||
cancelFab!!.visibility = View.VISIBLE
|
||||
fab!!.visibility = View.GONE
|
||||
|
||||
val disposable: Disposable = Observable.fromCallable {
|
||||
try{
|
||||
YoutubeDL.getInstance().execute(request, downloadID.toString()){ progress, _, line ->
|
||||
runOnUiThread {
|
||||
output!!.append("\n" + line)
|
||||
output!!.scrollTo(0, output!!.height)
|
||||
scrollView!!.fullScroll(View.FOCUS_DOWN)
|
||||
|
||||
val title: String = getString(R.string.terminal)
|
||||
notificationUtil.updateDownloadNotification(
|
||||
downloadID,
|
||||
line, progress.toInt(), 0, title,
|
||||
NotificationUtil.COMMAND_DOWNLOAD_SERVICE_CHANNEL_ID
|
||||
)
|
||||
}
|
||||
}
|
||||
}catch (e: Exception){
|
||||
e.printStackTrace()
|
||||
runOnUiThread {
|
||||
input!!.isEnabled = true
|
||||
|
||||
cancelFab!!.visibility = View.GONE
|
||||
fab!!.visibility = View.VISIBLE
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
.subscribeOn(Schedulers.newThread())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe({
|
||||
scrollView!!.scrollTo(0, scrollView!!.maxScrollAmount);
|
||||
input!!.setText("yt-dlp ");
|
||||
input!!.isEnabled = true;
|
||||
|
||||
cancelFab!!.visibility = View.GONE
|
||||
fab!!.visibility = View.VISIBLE
|
||||
|
||||
//move file from internal to set download directory
|
||||
try {
|
||||
moveFile(tempFileDir.absoluteFile, getString(R.string.command_path)){ }
|
||||
}catch (e: Exception){
|
||||
Toast.makeText(context, e.message, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
notificationUtil.cancelDownloadNotification(downloadID)
|
||||
}) { e ->
|
||||
scrollView!!.scrollTo(0, scrollView!!.maxScrollAmount)
|
||||
input!!.setText("yt-dlp ")
|
||||
input!!.isEnabled = true
|
||||
|
||||
cancelFab!!.visibility = View.GONE
|
||||
fab!!.visibility = View.VISIBLE
|
||||
|
||||
tempFileDir.delete()
|
||||
Toast.makeText(context, e.message, Toast.LENGTH_SHORT).show()
|
||||
|
||||
Log.e(DownloadWorker.TAG, context?.getString(R.string.failed_download), e)
|
||||
notificationUtil.cancelDownloadNotification(downloadID)
|
||||
}
|
||||
compositeDisposable.add(disposable)
|
||||
|
||||
}
|
||||
@Throws(Exception::class)
|
||||
private fun moveFile(originDir: File, downLocation: String, progress: (progress: Int) -> Unit){
|
||||
val fileUtil = FileUtil()
|
||||
fileUtil.moveFile(originDir, context!!, downLocation){ p ->
|
||||
progress(p)
|
||||
}
|
||||
}
|
||||
|
||||
private fun cancelDownload() {
|
||||
lifecycleScope.launch {
|
||||
val id = withContext(Dispatchers.IO){ downloadViewModel.getTerminalDownload(); }
|
||||
YoutubeDL.getInstance().destroyProcessById(id.toString())
|
||||
WorkManager.getInstance(this@CustomCommandActivity).cancelUniqueWork(id.toString())
|
||||
notificationUtil.cancelDownloadNotification(id.toInt())
|
||||
compositeDisposable.dispose()
|
||||
YoutubeDL.getInstance().destroyProcessById(downloadID.toString())
|
||||
notificationUtil.cancelDownloadNotification(downloadID)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val TAG = "CustomCommandActivity"
|
||||
private var downloadID = System.currentTimeMillis().toInt()
|
||||
private val compositeDisposable = CompositeDisposable()
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -190,32 +190,6 @@ class DownloadWorker(
|
|||
}
|
||||
}
|
||||
}
|
||||
DownloadViewModel.Type.terminal -> {
|
||||
if(downloadItem.format.format_note.startsWith("yt-dlp ")){
|
||||
downloadItem.format.format_note = downloadItem.format.format_note.substring(6).trim();
|
||||
}
|
||||
|
||||
val commandRegex = "\"([^\"]*)\"|(\\S+)"
|
||||
request = YoutubeDLRequest(emptyList())
|
||||
|
||||
tempFolder = StringBuilder(context.cacheDir.absolutePath + """/${downloadItem.format.format_id}##terminal""")
|
||||
tempFileDir = File(tempFolder.toString())
|
||||
tempFileDir.delete()
|
||||
tempFileDir.mkdir()
|
||||
|
||||
|
||||
val m = Pattern.compile(commandRegex).matcher(downloadItem.format.format_note)
|
||||
while (m.find()) {
|
||||
if (m.group(1) != null) {
|
||||
request.addOption(m.group(1)!!)
|
||||
} else {
|
||||
request.addOption(m.group(2)!!)
|
||||
}
|
||||
}
|
||||
|
||||
request.addOption("-o", tempFileDir.absolutePath + "/${downloadItem.customFileNameTemplate}.%(ext)s")
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
runCatching {
|
||||
|
|
|
|||
Loading…
Reference in a new issue