random bug fixes
This commit is contained in:
parent
0ac4ab20e3
commit
4699cb46e1
13 changed files with 85 additions and 57 deletions
|
|
@ -9,6 +9,7 @@ import androidx.room.Update
|
|||
import com.deniscerri.ytdl.database.models.DownloadItem
|
||||
import com.deniscerri.ytdl.database.models.HistoryItem
|
||||
import com.deniscerri.ytdl.database.repository.HistoryRepository
|
||||
import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
@Dao
|
||||
|
|
@ -83,6 +84,9 @@ interface HistoryDao {
|
|||
@Query("SELECT * FROM history WHERE url=:url")
|
||||
fun getAllHistoryByURL(url: String) : List<HistoryItem>
|
||||
|
||||
@Query("SELECT * FROM history WHERE url=:url and type=:type")
|
||||
fun getAllHistoryByURLAndType(url: String, type: DownloadViewModel.Type) : List<HistoryItem>
|
||||
|
||||
@Query("SELECT * FROM history WHERE id in (:ids)")
|
||||
fun getAllHistoryByIDs(ids: List<Long>) : List<HistoryItem>
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import androidx.paging.filter
|
|||
import com.deniscerri.ytdl.database.DBManager.SORTING
|
||||
import com.deniscerri.ytdl.database.dao.HistoryDao
|
||||
import com.deniscerri.ytdl.database.models.HistoryItem
|
||||
import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel
|
||||
import com.deniscerri.ytdl.database.viewmodel.HistoryViewModel
|
||||
import com.deniscerri.ytdl.util.FileUtil
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
|
@ -37,6 +38,10 @@ class HistoryRepository(private val historyDao: HistoryDao) {
|
|||
return historyDao.getAllHistoryByURL(url)
|
||||
}
|
||||
|
||||
fun getAllByURLAndType(url: String, type: DownloadViewModel.Type) : List<HistoryItem> {
|
||||
return historyDao.getAllHistoryByURLAndType(url, type)
|
||||
}
|
||||
|
||||
fun getAllByIDs(ids: List<Long>) : List<HistoryItem> {
|
||||
return historyDao.getAllHistoryByIDs(ids)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import androidx.work.WorkManager
|
|||
import com.deniscerri.ytdl.R
|
||||
import com.deniscerri.ytdl.database.dao.ObserveSourcesDao
|
||||
import com.deniscerri.ytdl.database.models.observeSources.ObserveSourcesItem
|
||||
import com.deniscerri.ytdl.util.Extensions.calculateNextTimeForObserving
|
||||
import com.deniscerri.ytdl.work.ObserveSourceWorker
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import java.util.Calendar
|
||||
|
|
|
|||
|
|
@ -1002,11 +1002,13 @@ class DownloadViewModel(private val application: Application) : AndroidViewModel
|
|||
val currentCommand = ytdlpUtil.buildYoutubeDLRequest(it)
|
||||
val parsedCurrentCommand = ytdlpUtil.parseYTDLRequestString(currentCommand)
|
||||
val existingDownload = activeAndQueuedDownloads.firstOrNull{d ->
|
||||
d.id = 0
|
||||
d.logID = null
|
||||
d.customFileNameTemplate = it.customFileNameTemplate
|
||||
d.status = DownloadRepository.Status.Queued.toString()
|
||||
d.toString() == it.toString()
|
||||
val normalized = d.copy(
|
||||
id = 0,
|
||||
logID = null,
|
||||
customFileNameTemplate = it.customFileNameTemplate,
|
||||
status = DownloadRepository.Status.Queued.toString()
|
||||
)
|
||||
normalized.toString() == it.toString()
|
||||
}
|
||||
|
||||
if (existingDownload != null){
|
||||
|
|
|
|||
|
|
@ -255,7 +255,7 @@ class FormatViewModel(private val application: Application) : AndroidViewModel(a
|
|||
_noFreeSpace.emit(null)
|
||||
if (size > 10L) {
|
||||
File(FileUtil.formatPath(path)).apply {
|
||||
if (size > this.freeSpace) {
|
||||
if (size > this.freeSpace && this.freeSpace >= 10L) {
|
||||
val warningTxt = application.getString(R.string.no_free_space_warning) +
|
||||
"\n" + "${application.getString(R.string.file_size)}:\t${FileUtil.convertFileSize(size)}" +
|
||||
"\n" + "${application.getString(R.string.freespace)}:\t${FileUtil.convertFileSize(this.freeSpace)}"
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ import android.widget.RadioButton
|
|||
import android.widget.TextView
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.appcompat.content.res.AppCompatResources
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.core.content.edit
|
||||
import androidx.core.view.children
|
||||
import androidx.core.view.isVisible
|
||||
|
|
@ -53,6 +54,7 @@ import com.google.android.material.tabs.TabLayout
|
|||
import com.google.android.material.textfield.TextInputLayout
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Calendar
|
||||
|
|
@ -471,7 +473,8 @@ class ObserveSourcesBottomSheetDialog : BottomSheetDialogFragment() {
|
|||
retryMissingDownloads.isChecked = currentItem?.retryMissingDownloads ?: false
|
||||
getOnlyNewUploads.isChecked = currentItem?.getOnlyNewUploads ?: false
|
||||
syncWithSource.isChecked = currentItem?.syncWithSource ?: false
|
||||
resetProcessedLinks.isVisible = currentItem != null
|
||||
|
||||
view.findViewById<ConstraintLayout>(R.id.resetProcessedLinksConstraint).isVisible = currentItem != null
|
||||
|
||||
if (currentItem != null) okButton.text = getString(R.string.update)
|
||||
okButton.setOnClickListener {
|
||||
|
|
@ -489,7 +492,7 @@ class ObserveSourcesBottomSheetDialog : BottomSheetDialogFragment() {
|
|||
endsAfterCount = endsAfterNr.editText!!.text.toString().toInt()
|
||||
}
|
||||
|
||||
val category = ObserveSourcesRepository.EveryCategory.values()[categoryAdapter.getPosition(everyCat.text.toString())]
|
||||
val category = ObserveSourcesRepository.EveryCategory.entries[categoryAdapter.getPosition(everyCat.text.toString())]
|
||||
|
||||
val observeItem = ObserveSourcesItem(
|
||||
id = currentItem?.id ?: 0,
|
||||
|
|
|
|||
|
|
@ -297,7 +297,7 @@ object Extensions {
|
|||
val badge = BadgeDrawable.create(context).apply {
|
||||
number = nr
|
||||
backgroundColor = context.getColor(R.color.white)
|
||||
verticalOffset = 30
|
||||
verticalOffset = 25
|
||||
horizontalOffset =
|
||||
if (nr < 10) dp(App.instance.resources, 16f)
|
||||
else if (nr < 100) dp(App.instance.resources, 19f)
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ class CleanUpLeftoverDownloads(
|
|||
val id = System.currentTimeMillis().toInt()
|
||||
|
||||
val notification = notificationUtil.createDeletingLeftoverDownloadsNotification()
|
||||
if (Build.VERSION.SDK_INT > 33) {
|
||||
if (Build.VERSION.SDK_INT >= 33) {
|
||||
setForegroundAsync(ForegroundInfo(id, notification, FOREGROUND_SERVICE_TYPE_DATA_SYNC))
|
||||
}else{
|
||||
setForegroundAsync(ForegroundInfo(id, notification))
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ class MoveCacheFilesWorker(
|
|||
val pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_IMMUTABLE)
|
||||
val notification = notificationUtil.createMoveCacheFilesNotification(pendingIntent, NotificationUtil.DOWNLOAD_MISC_CHANNEL_ID)
|
||||
|
||||
if (Build.VERSION.SDK_INT > 33) {
|
||||
if (Build.VERSION.SDK_INT >= 33) {
|
||||
setForegroundAsync(ForegroundInfo(id, notification, FOREGROUND_SERVICE_TYPE_DATA_SYNC))
|
||||
}else{
|
||||
setForegroundAsync(ForegroundInfo(id, notification))
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import androidx.work.WorkerParameters
|
|||
import com.deniscerri.ytdl.App
|
||||
import com.deniscerri.ytdl.database.DBManager
|
||||
import com.deniscerri.ytdl.database.models.DownloadItem
|
||||
import com.deniscerri.ytdl.database.models.ResultItem
|
||||
import com.deniscerri.ytdl.database.repository.DownloadRepository
|
||||
import com.deniscerri.ytdl.database.repository.HistoryRepository
|
||||
import com.deniscerri.ytdl.database.repository.ObserveSourcesRepository
|
||||
|
|
@ -36,9 +37,10 @@ class ObserveSourceWorker(
|
|||
workerParams: WorkerParameters
|
||||
) : CoroutineWorker(context, workerParams) {
|
||||
override suspend fun doWork(): Result {
|
||||
val notificationUtil = NotificationUtil(App.instance)
|
||||
val sourceID = inputData.getLong("id", 0)
|
||||
if (sourceID == 0L) return Result.failure()
|
||||
if (sourceID == 0L) return Result.success()
|
||||
|
||||
val notificationUtil = NotificationUtil(App.instance)
|
||||
val dbManager = DBManager.getInstance(context)
|
||||
val workManager = WorkManager.getInstance(context)
|
||||
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
|
||||
|
|
@ -46,17 +48,18 @@ class ObserveSourceWorker(
|
|||
val historyRepo = HistoryRepository(dbManager.historyDao)
|
||||
val downloadRepo = DownloadRepository(dbManager.downloadDao)
|
||||
val commandTemplateDao = dbManager.commandTemplateDao
|
||||
val ytdlpUtil = YTDLPUtil(context, commandTemplateDao)
|
||||
val resultRepository = ResultRepository(dbManager.resultDao, commandTemplateDao, context)
|
||||
|
||||
val ytdlpUtil = YTDLPUtil(context, commandTemplateDao)
|
||||
|
||||
val item = repo.getByID(sourceID)
|
||||
if (item.status == ObserveSourcesRepository.SourceStatus.STOPPED){
|
||||
return Result.failure()
|
||||
return Result.success()
|
||||
}
|
||||
|
||||
val workerID = System.currentTimeMillis().toInt()
|
||||
val notification = notificationUtil.createObserveSourcesNotification(item.name)
|
||||
if (Build.VERSION.SDK_INT > 33) {
|
||||
if (Build.VERSION.SDK_INT >= 33) {
|
||||
setForegroundAsync(ForegroundInfo(workerID, notification, FOREGROUND_SERVICE_TYPE_DATA_SYNC))
|
||||
}else{
|
||||
setForegroundAsync(ForegroundInfo(workerID, notification))
|
||||
|
|
@ -68,7 +71,8 @@ class ObserveSourceWorker(
|
|||
Log.e("observe", it.toString())
|
||||
}.getOrElse { listOf() }
|
||||
|
||||
if (list.isNotEmpty() && item.syncWithSource && item.alreadyProcessedLinks.isNotEmpty()){
|
||||
//delete downloaded items not present in source if sync is enabled
|
||||
if (item.syncWithSource && item.alreadyProcessedLinks.isNotEmpty()){
|
||||
val processedLinks = item.alreadyProcessedLinks
|
||||
val incomingLinks = list.map { it.url }
|
||||
|
||||
|
|
@ -81,37 +85,42 @@ class ObserveSourceWorker(
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
val res = list
|
||||
.filter { result ->
|
||||
//if first run and get new items only is preferred then dont get anything on first run
|
||||
if (item.getOnlyNewUploads && item.runCount == 0){
|
||||
item.ignoredLinks.add(result.url)
|
||||
false
|
||||
}else{
|
||||
true
|
||||
}
|
||||
val toProcess = mutableListOf<ResultItem>()
|
||||
//filter what results need to be downloaded, ignored
|
||||
for (result in list) {
|
||||
if (item.ignoredLinks.contains(result.url)) {
|
||||
continue
|
||||
}
|
||||
.filter { result ->
|
||||
val history = historyRepo.getAllByURL(result.url)
|
||||
|
||||
!item.ignoredLinks.contains(result.url) &&
|
||||
// if first run and get only new items, ignore
|
||||
if (item.getOnlyNewUploads && item.runCount == 0) {
|
||||
item.ignoredLinks.add(result.url)
|
||||
continue
|
||||
}
|
||||
|
||||
if (item.retryMissingDownloads){
|
||||
//all items that are not present in history
|
||||
history.none { hi -> hi.downloadPath.any { path -> FileUtil.exists(path) } }
|
||||
}else{
|
||||
//all items that are not already processed
|
||||
if(item.alreadyProcessedLinks.isEmpty()){
|
||||
!history.map { it.url }.contains(result.url)
|
||||
}else{
|
||||
!item.alreadyProcessedLinks.contains(result.url)
|
||||
}
|
||||
val history = historyRepo.getAllByURLAndType(result.url, item.downloadItemTemplate.type)
|
||||
//if history is empty or all history items are deleted, add for retry
|
||||
if (item.retryMissingDownloads && (history.isEmpty() || history.none { hi -> hi.downloadPath.any { path -> FileUtil.exists(path) } })) {
|
||||
toProcess.add(result)
|
||||
continue
|
||||
}
|
||||
|
||||
if (item.alreadyProcessedLinks.isEmpty()) {
|
||||
if (history.isEmpty()) {
|
||||
toProcess.add(result)
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
val items = mutableListOf<DownloadItem>()
|
||||
res.forEach {
|
||||
if (item.alreadyProcessedLinks.contains(result.url)) {
|
||||
continue
|
||||
}
|
||||
|
||||
toProcess.add(result)
|
||||
}
|
||||
|
||||
val downloadItems = mutableListOf<DownloadItem>()
|
||||
toProcess.forEach {
|
||||
val string = Gson().toJson(item.downloadItemTemplate, DownloadItem::class.java)
|
||||
val downloadItem = Gson().fromJson(string, DownloadItem::class.java)
|
||||
downloadItem.title = it.title
|
||||
|
|
@ -125,12 +134,11 @@ class ObserveSourceWorker(
|
|||
downloadItem.playlistURL = it.playlistURL
|
||||
downloadItem.playlistIndex = it.playlistIndex
|
||||
downloadItem.id = 0L
|
||||
items.add(downloadItem)
|
||||
downloadItems.add(downloadItem)
|
||||
}
|
||||
|
||||
|
||||
if (items.isNotEmpty()){
|
||||
|
||||
if (downloadItems.isNotEmpty()){
|
||||
//QUEUE DOWNLOADS
|
||||
//COPY OF QUEUE DOWNLOADS IN DOWNLOAD VIEW MODEL. NEEDS TO BE UPDATED IF THAT IS UPDATED
|
||||
val context = App.instance
|
||||
|
|
@ -146,16 +154,18 @@ class ObserveSourceWorker(
|
|||
// items.forEachIndexed { index, it -> it.playlistTitle = "Various[${index+1}]" }
|
||||
// }
|
||||
|
||||
items.forEach {
|
||||
downloadItems.forEach {
|
||||
it.status = DownloadRepository.Status.Queued.toString()
|
||||
val currentCommand = ytdlpUtil.buildYoutubeDLRequest(it)
|
||||
val parsedCurrentCommand = ytdlpUtil.parseYTDLRequestString(currentCommand)
|
||||
val existingDownload = activeAndQueuedDownloads.firstOrNull{d ->
|
||||
d.id = 0
|
||||
d.logID = null
|
||||
d.customFileNameTemplate = it.customFileNameTemplate
|
||||
d.status = DownloadRepository.Status.Queued.toString()
|
||||
d.toString() == it.toString()
|
||||
val normalized = d.copy(
|
||||
id = 0,
|
||||
logID = null,
|
||||
customFileNameTemplate = it.customFileNameTemplate,
|
||||
status = DownloadRepository.Status.Queued.toString()
|
||||
)
|
||||
normalized.toString() == it.toString()
|
||||
}
|
||||
if (existingDownload != null) {
|
||||
it.id = existingDownload.id
|
||||
|
|
@ -191,14 +201,15 @@ class ObserveSourceWorker(
|
|||
downloadRepo.startDownloadWorker(queuedItems, context)
|
||||
}
|
||||
|
||||
item.alreadyProcessedLinks.removeAll(items.map { it.url })
|
||||
item.alreadyProcessedLinks.addAll(items.map { it.url })
|
||||
item.alreadyProcessedLinks.addAll(downloadItems.map { it.url })
|
||||
}
|
||||
|
||||
item.runCount += 1
|
||||
|
||||
val currentTime = System.currentTimeMillis()
|
||||
val isFinished = (item.endsAfterCount > 0 && item.runCount >= item.endsAfterCount) || item.endsDate >= currentTime
|
||||
val isFinished =
|
||||
(item.endsAfterCount > 0 && item.runCount >= item.endsAfterCount) ||
|
||||
(item.endsDate > 0 && currentTime >= item.endsDate)
|
||||
|
||||
if (isFinished) {
|
||||
item.status = ObserveSourcesRepository.SourceStatus.STOPPED
|
||||
withContext(Dispatchers.IO){
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ class TerminalDownloadWorker(
|
|||
val intent = Intent(context, TerminalActivity::class.java)
|
||||
val pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_IMMUTABLE)
|
||||
val notification = notificationUtil.createDownloadServiceNotification(pendingIntent, command.take(65), NotificationUtil.DOWNLOAD_TERMINAL_RUNNING_NOTIFICATION_ID)
|
||||
if (Build.VERSION.SDK_INT > 33) {
|
||||
if (Build.VERSION.SDK_INT >= 33) {
|
||||
setForegroundAsync(ForegroundInfo(itemId, notification, FOREGROUND_SERVICE_TYPE_DATA_SYNC))
|
||||
}else{
|
||||
setForegroundAsync(ForegroundInfo(itemId, notification))
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ class UpdateMultipleDownloadsFormatsWorker(
|
|||
|
||||
val notification = notificationUtil.createFormatsUpdateNotification()
|
||||
|
||||
if (Build.VERSION.SDK_INT > 33) {
|
||||
if (Build.VERSION.SDK_INT >= 33) {
|
||||
setForegroundAsync(ForegroundInfo(workID, notification, FOREGROUND_SERVICE_TYPE_DATA_SYNC))
|
||||
}else{
|
||||
setForegroundAsync(ForegroundInfo(workID, notification))
|
||||
|
|
|
|||
|
|
@ -224,6 +224,7 @@
|
|||
app:chipSpacingVertical="0dp"
|
||||
android:paddingVertical="5dp"
|
||||
android:paddingHorizontal="10dp"
|
||||
app:selectionRequired="true"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<com.google.android.material.chip.Chip
|
||||
|
|
@ -589,6 +590,7 @@
|
|||
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/resetProcessedLinksConstraint"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_height="wrap_content">
|
||||
|
|
|
|||
Loading…
Reference in a new issue