pull/119/head
deniscerri 3 years ago
parent 794f591652
commit 98c1e20d51
No known key found for this signature in database
GPG Key ID: 95C43D517D830350

@ -77,7 +77,7 @@ class ActiveDownloadAdapter(onItemClickListener: OnItemClickListener, activity:
if (title.length > 100) {
title = title.substring(0, 40) + "..."
}
itemTitle.text = title.ifEmpty { "`${activity.getString(R.string.defaultValue)}`" }
itemTitle.text = title.ifEmpty { "<${activity.getString(R.string.defaultValue)}>" }
// Author ----------------------------------
val author = card.findViewById<TextView>(R.id.author)
@ -86,7 +86,7 @@ class ActiveDownloadAdapter(onItemClickListener: OnItemClickListener, activity:
if (item.author.isNotEmpty()) info += ""
info += item.duration
}
author.text = info.ifEmpty { "`${activity.getString(R.string.defaultValue)}`" }
author.text = info.ifEmpty { "<${activity.getString(R.string.defaultValue)}>" }
val type = card.findViewById<MaterialButton>(R.id.download_type)
when(item.type){

@ -73,7 +73,7 @@ class GenericDownloadAdapter(onItemClickListener: OnItemClickListener, activity:
if (title.length > 100) {
title = title.substring(0, 40) + "..."
}
itemTitle.text = title.ifEmpty { "`${activity.getString(R.string.defaultValue)}`" }
itemTitle.text = title.ifEmpty { "<${activity.getString(R.string.defaultValue)}>" }
val formatNote = card.findViewById<TextView>(R.id.format_note)
if (item.format.format_note == "?" || item.format.format_note == "") formatNote!!.visibility =

@ -20,7 +20,7 @@ data class DownloadItem(
var downloadSections: String,
val allFormats: ArrayList<Format>,
var downloadPath: String,
val website: String,
var website: String,
val downloadSize: String,
val playlistTitle: String,
val audioPreferences : AudioPreferences,

@ -193,6 +193,7 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, View.OnClickLi
if (arguments?.getString("url") != null){
val url = requireArguments().getString("url")
arguments?.remove("url")
if (inputQueries == null) inputQueries = mutableListOf()
searchBar?.text = url
inputQueries!!.add(url!!)
@ -202,6 +203,7 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, View.OnClickLi
resultViewModel.deleteAll()
lifecycleScope.launch(Dispatchers.IO){
resultViewModel.parseQueries(inputQueries!!)
inputQueries = null
}
}
}

@ -71,7 +71,7 @@ class DownloadBottomSheetDialog(private val resultItem: ResultItem, private val
behavior = BottomSheetBehavior.from(view.parent as View)
val displayMetrics = DisplayMetrics()
requireActivity().windowManager.defaultDisplay.getMetrics(displayMetrics)
behavior.peekHeight = displayMetrics.heightPixels - 700
behavior.peekHeight = displayMetrics.heightPixels
}
@ -159,9 +159,9 @@ class DownloadBottomSheetDialog(private val resultItem: ResultItem, private val
scheduleBtn.setOnClickListener{
scheduleBtn.isEnabled = false
download.isEnabled = false
uiUtil.showDatePicker(fragmentManager) {
scheduleBtn.isEnabled = false
download.isEnabled = false
val item: DownloadItem = getDownloadItem();
item.downloadStartTime = it.timeInMillis
runBlocking {
@ -197,13 +197,13 @@ class DownloadBottomSheetDialog(private val resultItem: ResultItem, private val
(updateItem.parent as LinearLayout).visibility = View.VISIBLE
updateItem.setOnClickListener {
if (activity is ShareActivity) {
dismiss()
val intent = Intent(context, ShareActivity::class.java)
intent.action = Intent.ACTION_SEND
intent.type = "text/plain"
intent.putExtra(Intent.EXTRA_TEXT, resultItem.url)
intent.putExtra("quick_download", false)
startActivity(intent)
dismiss()
}else{
dismiss()
val bundle = Bundle()

@ -106,9 +106,9 @@ class DownloadMultipleBottomSheetDialog(private var results: List<ResultItem?>,
scheduleBtn.setOnClickListener{
scheduleBtn.isEnabled = false
download.isEnabled = false
uiUtil.showDatePicker(parentFragmentManager) {
scheduleBtn.isEnabled = false
download.isEnabled = false
items.forEach { item ->
item.downloadStartTime = it.timeInMillis
}

@ -88,13 +88,13 @@ class SelectPlaylistItemsBottomSheetDialog(private val items: List<ResultItem?>,
val end = toTextInput.editText!!.text.toString()
if (checkRanges(start, end)) {
if (start < end){
if (start.toInt() < end.toInt()){
var startNr = Integer.parseInt(start)
startNr--
var endNr = Integer.parseInt(end)
endNr--
if (startNr <= 0) startNr = 0
if (endNr > items.size) endNr = items.size
if (endNr > items.size) endNr = items.size - 1
listAdapter.checkRange(startNr, endNr)
selectedText.text = "${listAdapter.getCheckedItems().size} ${resources.getString(R.string.selected)}"
}
@ -108,13 +108,13 @@ class SelectPlaylistItemsBottomSheetDialog(private val items: List<ResultItem?>,
val end = _text.toString()
if (checkRanges(start, end)) {
if (start < end){
if (start.toInt() < end.toInt()){
var startNr = Integer.parseInt(start)
startNr--
var endNr = Integer.parseInt(end)
endNr--
if (startNr <= 0) startNr = 0
if (endNr > items.size) endNr = items.size
if (endNr > items.size) endNr = items.size -1
listAdapter.checkRange(startNr, endNr)
selectedText.text = "${listAdapter.getCheckedItems().size} ${resources.getString(R.string.selected)}"
}

@ -120,7 +120,7 @@ class ActiveDownloadsFragment() : Fragment(), ActiveDownloadAdapter.OnItemClickL
val logFile = fileUtil.getLogFile(requireContext(), item)
if (logFile.exists()) {
val intent = Intent(requireContext(), DownloadLogActivity::class.java)
intent.putExtra("path", logFile.absolutePath)
intent.putExtra("logpath", logFile.absolutePath)
startActivity(intent)
}
}

@ -105,7 +105,7 @@ class ErroredDownloadsFragment : Fragment(), GenericDownloadAdapter.OnItemClickL
val item = items.find { it.id == itemID } ?: return
val file = fileUtil.getLogFile(requireContext(), item)
val intent = Intent(requireContext(), DownloadLogActivity::class.java)
intent.putExtra("path", file.absolutePath)
intent.putExtra("logpath", file.absolutePath)
startActivity(intent)
}

@ -45,7 +45,7 @@ class DownloadLogActivity : BaseActivity() {
clipboard.setText(content.text)
}
val path = intent.getStringExtra("path")
val path = intent.getStringExtra("logpath")
if (path == null) {
onBackPressedDispatcher.onBackPressed()
}

@ -125,7 +125,7 @@ class DownloadLogListActivity : BaseActivity(), DownloadLogsAdapter.OnItemClickL
override fun onItemClick(file: File) {
val intent = Intent(this, DownloadLogActivity::class.java)
intent.putExtra("path", file.absolutePath)
intent.putExtra("logpath", file.absolutePath)
startActivity(intent)
}

@ -7,6 +7,7 @@ import android.os.Looper
import android.util.Log
import android.widget.Toast
import com.deniscerri.ytdlnis.R
import com.deniscerri.ytdlnis.database.models.DownloadItem
import com.deniscerri.ytdlnis.database.models.Format
import com.deniscerri.ytdlnis.database.models.ResultItem
import com.google.gson.Gson
@ -674,6 +675,51 @@ class InfoUtil(private val context: Context) {
return items
}
fun getMissingInfo(url: String): ResultItem? {
try {
val request = YoutubeDLRequest(url)
request.addOption("--flat-playlist")
request.addOption("-J")
request.addOption("--skip-download")
request.addOption("-R", "1")
request.addOption("--socket-timeout", "5")
val cookiesFile = File(context.cacheDir, "cookies.txt")
if (cookiesFile.exists()){
request.addOption("--cookies", cookiesFile.absolutePath)
}
val youtubeDLResponse = YoutubeDL.getInstance().execute(request)
val jsonObject = JSONObject(youtubeDLResponse.out)
val thumbs = jsonObject.getJSONArray("thumbnails")
val thumb = thumbs.getJSONObject(thumbs.length() - 1).getString("url")
val isPlaylist = jsonObject.has("playlist_count")
return ResultItem(
0,
url,
if (isPlaylist){
"[${jsonObject.getInt("playlist_count")} Items] ${jsonObject.getString("title")}"
}else{
jsonObject.getString("title")
},
jsonObject.getString("uploader"),
if (jsonObject.has("duration")) formatIntegerDuration(jsonObject.getInt("duration"), Locale.US) else "",
thumb,
jsonObject.getString("extractor"),
if (isPlaylist) jsonObject.getString("title") else "",
arrayListOf(),
System.currentTimeMillis()
)
} catch (e: Exception) {
Looper.prepare().run {
Toast.makeText(context, e.message, Toast.LENGTH_LONG).show()
}
e.printStackTrace()
}
return null
}
fun getSearchSuggestions(query: String): ArrayList<String> {
val url = "https://suggestqueries.google.com/complete/search?client=youtube&ds=yt&client=firefox&q=$query"
// invidousURL + "search/suggestions?q=" + query

@ -1,9 +1,6 @@
package com.deniscerri.ytdlnis.util
import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.app.*
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
@ -140,16 +137,22 @@ class NotificationUtil(var context: Context) {
intent.action = Intent.ACTION_VIEW
intent.setDataAndType(uri, "*/*")
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
val openNotificationPendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_IMMUTABLE)
val openNotificationPendingIntent: PendingIntent = TaskStackBuilder.create(context).run {
addNextIntentWithParentStack(intent)
getPendingIntent(0,
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE)
}
//share intent
val shareIntent = Intent(context, SharedDownloadNotificationReceiver::class.java)
shareIntent.putExtra("share", "")
shareIntent.putExtra("path", filepath)
shareIntent.putExtra("notificationID", DOWNLOAD_FINISHED_NOTIFICATION_ID)
shareIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
val shareNotificationPendingIntent = PendingIntent.getActivity(context, 0, shareIntent, PendingIntent.FLAG_IMMUTABLE)
val shareNotificationPendingIntent: PendingIntent = TaskStackBuilder.create(context).run {
addNextIntentWithParentStack(shareIntent)
getPendingIntent(0,
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE)
}
notificationBuilder.addAction(0, context.getString(R.string.Open_File), openNotificationPendingIntent)
notificationBuilder.addAction(0, context.getString(R.string.share), shareNotificationPendingIntent)
@ -160,31 +163,34 @@ class NotificationUtil(var context: Context) {
fun createDownloadErrored(title: String?,
error: String?,
logFilePath: String?,
logFile: File?,
channel: String
) {
val notificationBuilder = getBuilder(channel)
val intent = Intent(context, DownloadLogActivity::class.java)
intent.putExtra("path", logFilePath)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
val errorPendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_IMMUTABLE)
intent.putExtra("logpath", logFile?.absolutePath)
val errorPendingIntent: PendingIntent = TaskStackBuilder.create(context).run {
addNextIntentWithParentStack(intent)
getPendingIntent(0,
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE)
}
notificationBuilder
.setContentTitle("${context.getString(R.string.failed_download)}: $title")
.setContentText(error)
.setContentIntent(errorPendingIntent)
.setSmallIcon(R.drawable.ic_app_icon)
.setSmallIcon(R.drawable.ic_launcher_foreground_large)
.setLargeIcon(
BitmapFactory.decodeResource(
context.resources,
R.drawable.ic_app_icon
R.drawable.ic_launcher_foreground_large
)
)
.setPriority(NotificationCompat.PRIORITY_MAX)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.clearActions()
if (logFilePath != null){
if (logFile != null){
notificationBuilder.setContentIntent(errorPendingIntent)
notificationBuilder.addAction(0, context.getString(R.string.logs), errorPendingIntent)
}
notificationManager.notify(DOWNLOAD_FINISHED_NOTIFICATION_ID, notificationBuilder.build())

@ -268,6 +268,22 @@ class DownloadWorker(
}
}
//update item if its incomplete
if (downloadItem.title.isEmpty() || downloadItem.author.isEmpty() || downloadItem.thumb.isEmpty()){
runCatching {
setProgressAsync(workDataOf("progress" to 0, "output" to "Updating Download Item Data", "id" to downloadItem.id, "log" to false))
val info = infoUtil.getMissingInfo(downloadItem.url)
if (downloadItem.title.isEmpty()) downloadItem.title = info?.title.toString()
if (downloadItem.author.isEmpty()) downloadItem.author = info?.author.toString()
if (downloadItem.thumb.isEmpty()) downloadItem.thumb = info?.thumb.toString()
downloadItem.duration = info?.duration.toString()
downloadItem.website = info?.website.toString()
runBlocking {
dao.update(downloadItem)
}
}
}
val logDownloads = sharedPreferences.getBoolean("log_downloads", false) && !sharedPreferences.getBoolean("incognito", false)
val logFolder = File(context.filesDir.absolutePath + "/logs")
val logFile = fileUtil.getLogFile(context, downloadItem)
@ -282,21 +298,6 @@ class DownloadWorker(
"Format: ${downloadItem.format}\n\n")
}
//update item if its incomplete
if (downloadItem.title.isEmpty() || downloadItem.author.isEmpty() || downloadItem.thumb.isEmpty()){
runCatching {
setProgressAsync(workDataOf("progress" to 0, "output" to "Updating Download Item Data", "id" to downloadItem.id, "log" to logDownloads))
val info = YoutubeDL.getInfo(downloadItem.url)
if (downloadItem.title.isEmpty()) downloadItem.title = info.title.toString()
if (downloadItem.author.isEmpty()) downloadItem.author = info.uploader.toString()
if (downloadItem.thumb.isEmpty()) downloadItem.thumb = info.thumbnail.toString()
downloadItem.duration = infoUtil.formatIntegerDuration(info.duration, Locale.US)
runBlocking {
dao.update(downloadItem)
}
}
}
runCatching {
YoutubeDL.getInstance().execute(request, downloadItem.id.toString()){ progress, _, line ->
setProgressAsync(workDataOf("progress" to progress.toInt(), "output" to line.chunked(5000).first().toString(), "id" to downloadItem.id, "log" to logDownloads))
@ -376,7 +377,7 @@ class DownloadWorker(
notificationUtil.createDownloadErrored(
downloadItem.title, it.message,
if (logDownloads) logFile.absolutePath else null,
if (logDownloads) logFile else null,
NotificationUtil.DOWNLOAD_FINISHED_CHANNEL_ID
)

@ -15,7 +15,7 @@
android:checkable="true"
android:clickable="true"
android:focusable="true"
android:background="?android:attr/selectableItemBackground"
android:backgroundTint="@android:color/transparent"
app:cardPreventCornerOverlap="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
@ -178,12 +178,13 @@
<com.google.android.material.button.MaterialButton
android:id="@+id/action_button"
style="?attr/materialIconButtonStyle"
android:layout_width="wrap_content"
android:layout_width="0dp"
android:padding="0dp"
android:minHeight="0dp"
android:layout_height="wrap_content"
app:cornerRadius="10dp"
app:iconTint="?attr/colorAccent"
app:icon="@drawable/ic_video"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0" />

@ -5,7 +5,7 @@ buildscript {
def versionMajor = 1
def versionMinor = 6
def versionPatch = 0
def versionPatch = 1
def versionBuild = 0 // bump for dogfood builds, public betas, etc.
ext {

@ -0,0 +1,11 @@
## Introducing Quick Download Mode
You can launch a download (or card) immediately without fetching data at first.
Added Theme Picker, Accents and High Contrast Mode
Added swipe actions on history,downloads,cookies,templates cards
Added finished download notification with actions
Fixed Tiktok videos not creating result cards
Added active downloads badge in the navigation bar
Added remove audio feature for videos
Added check for present downloads
Added preferred Format ID
Loading…
Cancel
Save