From 236f83d161a85218bf0e1cf357e767804dc30e82 Mon Sep 17 00:00:00 2001
From: deniscerri <64997243+deniscerri@users.noreply.github.com>
Date: Sat, 9 Sep 2023 12:15:07 +0200
Subject: [PATCH] stuff added auto preferred download type Show collected file
size in multi download card fixed app chossing worst format and not best
fixed update util not working in release fixed ytm playlists not loading
fixed sponsorblock not being checked in multiple download card added playlist
and playlist index metadata in download items added -a txt path if preferred
download type is command or if the txt file is shared in terminal fixed app
cancelling workmanager earlier than expected added title and author sync
between audio and video frgaments
---
app/src/main/AndroidManifest.xml | 2 -
.../com/deniscerri/ytdlnis/MainActivity.kt | 51 +++++---
.../ytdlnis/adapter/ActiveDownloadAdapter.kt | 1 +
.../ytdlnis/adapter/DownloadLogsAdapter.kt | 1 +
.../ytdlnis/database/models/DownloadItem.kt | 2 +-
.../ytdlnis/database/models/GithubRelease.kt | 7 +
.../database/viewmodel/DownloadViewModel.kt | 28 +++-
.../database/viewmodel/ResultViewModel.kt | 7 +-
.../com/deniscerri/ytdlnis/ui/HomeFragment.kt | 4 +-
.../ConfigureDownloadBottomSheetDialog.kt | 75 +++++++----
.../ui/downloadcard/DownloadAudioFragment.kt | 14 +-
.../downloadcard/DownloadBottomSheetDialog.kt | 120 ++++++++++++------
.../downloadcard/DownloadCommandFragment.kt | 55 +++++---
.../DownloadMultipleBottomSheetDialog.kt | 19 +++
.../ui/downloadcard/DownloadVideoFragment.kt | 13 +-
.../ui/downloadcard/TitleAuthorSync.kt | 5 +
.../ytdlnis/ui/more/TerminalActivity.kt | 13 +-
.../com/deniscerri/ytdlnis/util/FileUtil.kt | 8 +-
.../com/deniscerri/ytdlnis/util/InfoUtil.kt | 42 ++++--
.../com/deniscerri/ytdlnis/util/UiUtil.kt | 9 +-
.../com/deniscerri/ytdlnis/util/UpdateUtil.kt | 18 ++-
.../deniscerri/ytdlnis/work/DownloadWorker.kt | 3 -
.../layout/download_multiple_bottom_sheet.xml | 14 ++
.../res/layout/fragment_download_command.xml | 1 +
app/src/main/res/layout/textview.xml | 9 ++
app/src/main/res/values-bn-rIN/strings.xml | 1 -
app/src/main/res/values-jv/strings.xml | 1 -
app/src/main/res/values/arrays.xml | 3 +
.../main/res/xml/downloading_preferences.xml | 2 +-
29 files changed, 375 insertions(+), 153 deletions(-)
create mode 100644 app/src/main/java/com/deniscerri/ytdlnis/ui/downloadcard/TitleAuthorSync.kt
create mode 100644 app/src/main/res/layout/textview.xml
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index e1b2cd3a..116c926e 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -56,9 +56,7 @@
android:theme="@style/Theme.BottomSheet">
-
-
diff --git a/app/src/main/java/com/deniscerri/ytdlnis/MainActivity.kt b/app/src/main/java/com/deniscerri/ytdlnis/MainActivity.kt
index d7fdcf7a..126d0756 100644
--- a/app/src/main/java/com/deniscerri/ytdlnis/MainActivity.kt
+++ b/app/src/main/java/com/deniscerri/ytdlnis/MainActivity.kt
@@ -18,6 +18,7 @@ import android.view.View
import android.view.WindowInsets
import android.widget.CheckBox
import android.widget.TextView
+import android.widget.Toast
import androidx.annotation.RequiresApi
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.app.ActivityCompat
@@ -39,7 +40,9 @@ import com.deniscerri.ytdlnis.database.viewmodel.DownloadViewModel
import com.deniscerri.ytdlnis.database.viewmodel.ResultViewModel
import com.deniscerri.ytdlnis.ui.BaseActivity
import com.deniscerri.ytdlnis.ui.HomeFragment
+import com.deniscerri.ytdlnis.ui.downloadcard.DownloadBottomSheetDialog
import com.deniscerri.ytdlnis.ui.more.settings.SettingsActivity
+import com.deniscerri.ytdlnis.util.FileUtil
import com.deniscerri.ytdlnis.util.ThemeUtil
import com.deniscerri.ytdlnis.util.UpdateUtil
import com.google.android.material.bottomnavigation.BottomNavigationView
@@ -54,8 +57,10 @@ import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import java.io.BufferedReader
+import java.io.File
import java.io.InputStreamReader
import java.io.Reader
+import java.net.URI
import java.nio.charset.Charset
import java.nio.charset.StandardCharsets
import kotlin.system.exitProcess
@@ -332,26 +337,38 @@ class MainActivity : BaseActivity() {
}else{
intent.getParcelableExtra(Intent.EXTRA_STREAM)
}
- val `is` = contentResolver.openInputStream(uri!!)
- val textBuilder = StringBuilder()
- val reader: Reader = BufferedReader(
- InputStreamReader(
- `is`, Charset.forName(
- StandardCharsets.UTF_8.name()
+
+ if (preferences.getString("preferred_download_type", "video") == "command"){
+ val f = File(FileUtil.formatPath(uri?.path ?: ""))
+ if (!f.exists()){
+ Toast.makeText(context, "Couldn't read file", Toast.LENGTH_LONG).show()
+ return
+ }
+ val item = downloadViewModel.createEmptyResultItem(f.absolutePath)
+ val bottomSheet = DownloadBottomSheetDialog(item, DownloadViewModel.Type.command, null, true)
+ bottomSheet.show(supportFragmentManager, "downloadSingleSheet")
+ }else{
+ val `is` = contentResolver.openInputStream(uri!!)
+ val textBuilder = StringBuilder()
+ val reader: Reader = BufferedReader(
+ InputStreamReader(
+ `is`, Charset.forName(
+ StandardCharsets.UTF_8.name()
+ )
)
)
- )
- var c: Int
- while (reader.read().also { c = it } != -1) {
- textBuilder.append(c.toChar())
+ var c: Int
+ while (reader.read().also { c = it } != -1) {
+ textBuilder.append(c.toChar())
+ }
+ val bundle = Bundle()
+ bundle.putString("url", textBuilder.toString())
+ navController.popBackStack(R.id.homeFragment, true)
+ navController.navigate(
+ R.id.homeFragment,
+ bundle
+ )
}
- val bundle = Bundle()
- bundle.putString("url", textBuilder.toString())
- navController.popBackStack(R.id.homeFragment, true)
- navController.navigate(
- R.id.homeFragment,
- bundle
- )
} catch (e: Exception) {
e.printStackTrace()
}
diff --git a/app/src/main/java/com/deniscerri/ytdlnis/adapter/ActiveDownloadAdapter.kt b/app/src/main/java/com/deniscerri/ytdlnis/adapter/ActiveDownloadAdapter.kt
index 7ef835dc..8dc50782 100644
--- a/app/src/main/java/com/deniscerri/ytdlnis/adapter/ActiveDownloadAdapter.kt
+++ b/app/src/main/java/com/deniscerri/ytdlnis/adapter/ActiveDownloadAdapter.kt
@@ -104,6 +104,7 @@ class ActiveDownloadAdapter(onItemClickListener: OnItemClickListener, activity:
DownloadViewModel.Type.audio -> type.setIconResource(R.drawable.ic_music)
DownloadViewModel.Type.video -> type.setIconResource(R.drawable.ic_video)
DownloadViewModel.Type.command -> type.setIconResource(R.drawable.ic_terminal)
+ else -> {}
}
val formatDetailsChip = card.findViewById(R.id.format_note)
diff --git a/app/src/main/java/com/deniscerri/ytdlnis/adapter/DownloadLogsAdapter.kt b/app/src/main/java/com/deniscerri/ytdlnis/adapter/DownloadLogsAdapter.kt
index 6f1a6d89..6f5c972e 100644
--- a/app/src/main/java/com/deniscerri/ytdlnis/adapter/DownloadLogsAdapter.kt
+++ b/app/src/main/java/com/deniscerri/ytdlnis/adapter/DownloadLogsAdapter.kt
@@ -66,6 +66,7 @@ class DownloadLogsAdapter(onItemClickListener: OnItemClickListener, activity: Ac
DownloadViewModel.Type.audio -> downloadTypeIcon.setIconResource(R.drawable.ic_music)
DownloadViewModel.Type.video -> downloadTypeIcon.setIconResource(R.drawable.ic_video)
DownloadViewModel.Type.command -> downloadTypeIcon.setIconResource(R.drawable.ic_terminal)
+ else -> {}
}
val formatNote = card.findViewById(R.id.format_note)
diff --git a/app/src/main/java/com/deniscerri/ytdlnis/database/models/DownloadItem.kt b/app/src/main/java/com/deniscerri/ytdlnis/database/models/DownloadItem.kt
index bc34fd41..4b29f743 100644
--- a/app/src/main/java/com/deniscerri/ytdlnis/database/models/DownloadItem.kt
+++ b/app/src/main/java/com/deniscerri/ytdlnis/database/models/DownloadItem.kt
@@ -9,7 +9,7 @@ import com.deniscerri.ytdlnis.database.viewmodel.DownloadViewModel
data class DownloadItem(
@PrimaryKey(autoGenerate = true)
var id: Long,
- val url: String,
+ var url: String,
var title: String,
var author: String,
var thumb: String,
diff --git a/app/src/main/java/com/deniscerri/ytdlnis/database/models/GithubRelease.kt b/app/src/main/java/com/deniscerri/ytdlnis/database/models/GithubRelease.kt
index 6095dadc..5b132242 100644
--- a/app/src/main/java/com/deniscerri/ytdlnis/database/models/GithubRelease.kt
+++ b/app/src/main/java/com/deniscerri/ytdlnis/database/models/GithubRelease.kt
@@ -1,13 +1,20 @@
package com.deniscerri.ytdlnis.database.models
+import com.google.gson.annotations.SerializedName
+
data class GithubRelease(
+ @SerializedName(value = "tag_name")
var tag_name: String,
+ @SerializedName(value = "body")
var body: String,
+ @SerializedName(value = "assets")
var assets: List
)
data class GithubReleaseAsset(
+ @SerializedName(value = "name")
var name: String,
+ @SerializedName(value = "browser_download_url")
var browser_download_url: String
)
\ No newline at end of file
diff --git a/app/src/main/java/com/deniscerri/ytdlnis/database/viewmodel/DownloadViewModel.kt b/app/src/main/java/com/deniscerri/ytdlnis/database/viewmodel/DownloadViewModel.kt
index 61d06925..8deab4ea 100644
--- a/app/src/main/java/com/deniscerri/ytdlnis/database/viewmodel/DownloadViewModel.kt
+++ b/app/src/main/java/com/deniscerri/ytdlnis/database/viewmodel/DownloadViewModel.kt
@@ -85,9 +85,15 @@ class DownloadViewModel(application: Application) : AndroidViewModel(application
private val dao: DownloadDao
enum class Type {
- audio, video, command
+ auto, audio, video, command
}
+ private val urlsForAudioType = listOf(
+ "music",
+ "audio",
+ "soundcloud"
+ )
+
init {
dbManager = DBManager.getInstance(application)
dao = dbManager.downloadDao
@@ -194,6 +200,13 @@ class DownloadViewModel(application: Application) : AndroidViewModel(application
return repository.getItemByID(id)
}
+ private fun getSuitableDownloadType(url: String): Type{
+ if (urlsForAudioType.any { url.contains(it) }){
+ return Type.audio
+ }
+ return Type.video
+ }
+
fun createDownloadItemFromResult(resultItem: ResultItem, givenType: Type) : DownloadItem {
val embedSubs = sharedPreferences.getBoolean("embed_subtitles", false)
val saveSubs = sharedPreferences.getBoolean("write_subtitles", false)
@@ -202,6 +215,9 @@ class DownloadViewModel(application: Application) : AndroidViewModel(application
val embedThumb = sharedPreferences.getBoolean("embed_thumbnail", false)
var type = givenType
+ if (type == Type.auto){
+ type = getSuitableDownloadType(resultItem.url)
+ }
if(type == Type.command && commandTemplateDao.getTotalNumber() == 0) type = Type.video
val customFileNameTemplate = when(type) {
@@ -320,6 +336,7 @@ class DownloadViewModel(application: Application) : AndroidViewModel(application
Type.audio -> sharedPreferences.getString("music_path", FileUtil.getDefaultAudioPath())!!
Type.video -> sharedPreferences.getString("video_path", FileUtil.getDefaultVideoPath())!!
Type.command -> sharedPreferences.getString("command_path", FileUtil.getDefaultCommandPath())!!
+ else -> ""
}
list.forEach {
@@ -329,6 +346,7 @@ class DownloadViewModel(application: Application) : AndroidViewModel(application
Type.audio -> sharedPreferences.getString("music_path", FileUtil.getDefaultAudioPath())
Type.video -> sharedPreferences.getString("video_path", FileUtil.getDefaultVideoPath())
Type.command -> sharedPreferences.getString("command_path", FileUtil.getDefaultCommandPath())
+ else -> ""
}
if (it.downloadPath == currentDownloadPath) it.downloadPath = updatedDownloadPath
@@ -359,6 +377,7 @@ class DownloadViewModel(application: Application) : AndroidViewModel(application
Type.audio -> FileUtil.getDefaultAudioPath()
Type.video -> FileUtil.getDefaultVideoPath()
Type.command -> FileUtil.getDefaultCommandPath()
+ else -> ""
}
val sponsorblock = sharedPreferences.getStringSet("sponsorblock_filters", emptySet())
@@ -404,7 +423,7 @@ class DownloadViewModel(application: Application) : AndroidViewModel(application
Type.video -> {
return cloneFormat(
try {
- val theFormats = formats.filter { !it.format_note.contains("audio", true) }.sortedBy { it.format_id }.ifEmpty { defaultVideoFormats }
+ val theFormats = formats.filter { !it.format_note.contains("audio", true) }.sortedBy { it.format_id }.ifEmpty { defaultVideoFormats }.sortedByDescending { it.filesize }
when (videoQualityPreference) {
"worst" -> {
theFormats.first()
@@ -416,7 +435,7 @@ class DownloadViewModel(application: Application) : AndroidViewModel(application
requirements.add { it: Format -> it.format_note.contains(videoQualityPreference.substring(0, videoQualityPreference.length - 1)) }
requirements.add { it: Format -> it.vcodec.startsWith(videoCodec!!, true) }
- theFormats.reversed().maxByOrNull { f -> requirements.count{ req -> req(f)} } ?: throw Exception()
+ theFormats.maxByOrNull { f -> requirements.count{ req -> req(f)} } ?: throw Exception()
}
}
}catch (e: Exception){
@@ -468,8 +487,9 @@ class DownloadViewModel(application: Application) : AndroidViewModel(application
fun turnResultItemsToDownloadItems(items: List) : List {
val list : MutableList = mutableListOf()
- val preferredType = sharedPreferences.getString("preferred_download_type", "video")
+ var preferredType = sharedPreferences.getString("preferred_download_type", "video")
items.forEach {
+ if (preferredType == Type.auto.toString()) preferredType = getSuitableDownloadType(it!!.url).toString()
list.add(createDownloadItemFromResult(it!!, Type.valueOf(preferredType!!)))
}
return list
diff --git a/app/src/main/java/com/deniscerri/ytdlnis/database/viewmodel/ResultViewModel.kt b/app/src/main/java/com/deniscerri/ytdlnis/database/viewmodel/ResultViewModel.kt
index 9b0b2e08..e5f234f1 100644
--- a/app/src/main/java/com/deniscerri/ytdlnis/database/viewmodel/ResultViewModel.kt
+++ b/app/src/main/java/com/deniscerri/ytdlnis/database/viewmodel/ResultViewModel.kt
@@ -3,6 +3,7 @@ package com.deniscerri.ytdlnis.database.viewmodel
import android.app.Application
import android.content.SharedPreferences
import android.util.Log
+import android.util.Patterns
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
@@ -111,14 +112,14 @@ class ResultViewModel(application: Application) : AndroidViewModel(application)
}
private fun getQueryType(inputQuery: String) : String {
var type = "Search"
- val p = Pattern.compile("(^(https?)://(www.)?(music.)?youtu(.be)?)|(^(https?)://(www.)?piped.video)")
+ val p = Pattern.compile("(^(https?)://(www.)?youtu(.be)?)|(^(https?)://(www.)?piped.video)")
val m = p.matcher(inputQuery)
if (m.find()) {
type = "YT_Video"
- if (inputQuery.contains("playlist?list=") && !inputQuery.contains("music.youtu")) {
+ if (inputQuery.contains("playlist?list=")) {
type = "YT_Playlist"
}
- } else if (inputQuery.contains("http")) {
+ } else if (Patterns.WEB_URL.matcher(inputQuery).matches()) {
type = "Default"
}
return type
diff --git a/app/src/main/java/com/deniscerri/ytdlnis/ui/HomeFragment.kt b/app/src/main/java/com/deniscerri/ytdlnis/ui/HomeFragment.kt
index a0239791..cfe0b4fa 100644
--- a/app/src/main/java/com/deniscerri/ytdlnis/ui/HomeFragment.kt
+++ b/app/src/main/java/com/deniscerri/ytdlnis/ui/HomeFragment.kt
@@ -159,7 +159,7 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, OnClickListene
homeAdapter!!.submitList(it)
resultsList = it
if(resultViewModel.repository.itemCount.value > 1 || resultViewModel.repository.itemCount.value == -1){
- if (it.size > 1 && it[0].playlistTitle.isNotEmpty() && it[0].playlistTitle != getString(R.string.trendingPlaylist) && !loadingItems){
+ if (it.size > 1 && it[0].playlistTitle.isNotEmpty() && !loadingItems){
downloadAllFabCoordinator!!.visibility = VISIBLE
}else{
downloadAllFabCoordinator!!.visibility = GONE
@@ -187,7 +187,7 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, OnClickListene
recyclerView?.setPadding(0,0,0,100)
shimmerCards!!.stopShimmer()
shimmerCards!!.visibility = GONE
- if (resultsList!!.size > 1 && resultsList!![0]!!.playlistTitle.isNotEmpty() && resultsList!![0]!!.playlistTitle != getString(R.string.trendingPlaylist)){
+ if (resultsList!!.size > 1 && resultsList!![0]!!.playlistTitle.isNotEmpty()){
downloadAllFabCoordinator!!.visibility = VISIBLE
}else{
downloadAllFabCoordinator!!.visibility = GONE
diff --git a/app/src/main/java/com/deniscerri/ytdlnis/ui/downloadcard/ConfigureDownloadBottomSheetDialog.kt b/app/src/main/java/com/deniscerri/ytdlnis/ui/downloadcard/ConfigureDownloadBottomSheetDialog.kt
index ac4fbfd2..f13fe9b1 100644
--- a/app/src/main/java/com/deniscerri/ytdlnis/ui/downloadcard/ConfigureDownloadBottomSheetDialog.kt
+++ b/app/src/main/java/com/deniscerri/ytdlnis/ui/downloadcard/ConfigureDownloadBottomSheetDialog.kt
@@ -11,6 +11,7 @@ import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.Toast
+import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.RecyclerView
@@ -64,7 +65,6 @@ class ConfigureDownloadBottomSheetDialog(private val resultItem: ResultItem, pri
super.setupDialog(dialog, style)
val view = LayoutInflater.from(context).inflate(R.layout.configure_download_bottom_sheet, null)
dialog.setContentView(view)
-
dialog.setOnShowListener {
behavior = BottomSheetBehavior.from(view.parent as View)
val displayMetrics = DisplayMetrics()
@@ -80,7 +80,7 @@ class ConfigureDownloadBottomSheetDialog(private val resultItem: ResultItem, pri
overScrollMode = View.OVER_SCROLL_NEVER
}
- val fragments = mutableListOf(
+ val fragments = mutableListOf(
DownloadAudioFragment(resultItem, downloadItem),
DownloadVideoFragment(resultItem, downloadItem)
)
@@ -161,6 +161,9 @@ class ConfigureDownloadBottomSheetDialog(private val resultItem: ResultItem, pri
viewPager2.registerOnPageChangeCallback(object: ViewPager2.OnPageChangeCallback() {
override fun onPageSelected(position: Int) {
tabLayout.selectTab(tabLayout.getTabAt(position))
+ runCatching {
+ updateTitleAuthorWhenSwitching()
+ }
}
})
@@ -168,22 +171,7 @@ class ConfigureDownloadBottomSheetDialog(private val resultItem: ResultItem, pri
val ok = view.findViewById