added livedata to results
This commit is contained in:
parent
335be8299c
commit
09bddccb61
29 changed files with 1901 additions and 2014 deletions
|
|
@ -82,6 +82,7 @@ android {
|
|||
composeOptions {
|
||||
kotlinCompilerExtensionVersion composeVer
|
||||
}
|
||||
namespace 'com.deniscerri.ytdlnis'
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
312
app/schemas/com.deniscerri.ytdlnis.database.DBManager/1.json
Normal file
312
app/schemas/com.deniscerri.ytdlnis.database.DBManager/1.json
Normal file
|
|
@ -0,0 +1,312 @@
|
|||
{
|
||||
"formatVersion": 1,
|
||||
"database": {
|
||||
"version": 1,
|
||||
"identityHash": "1391e7ec82bbacc310cf6f23e3d1f85a",
|
||||
"entities": [
|
||||
{
|
||||
"tableName": "results",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`url` TEXT NOT NULL, `title` TEXT NOT NULL, `author` TEXT NOT NULL, `duration` TEXT NOT NULL, `thumb` TEXT NOT NULL, `website` TEXT NOT NULL, `playlistTitle` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT)",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "url",
|
||||
"columnName": "url",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "title",
|
||||
"columnName": "title",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "author",
|
||||
"columnName": "author",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "duration",
|
||||
"columnName": "duration",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "thumb",
|
||||
"columnName": "thumb",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "website",
|
||||
"columnName": "website",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "playlistTitle",
|
||||
"columnName": "playlistTitle",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"columnNames": [
|
||||
"id"
|
||||
],
|
||||
"autoGenerate": true
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "history",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`url` TEXT NOT NULL, `title` TEXT NOT NULL, `author` TEXT NOT NULL, `duration` TEXT NOT NULL, `thumb` TEXT NOT NULL, `type` TEXT NOT NULL, `time` INTEGER NOT NULL, `downloadPath` TEXT NOT NULL, `website` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT)",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "url",
|
||||
"columnName": "url",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "title",
|
||||
"columnName": "title",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "author",
|
||||
"columnName": "author",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "duration",
|
||||
"columnName": "duration",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "thumb",
|
||||
"columnName": "thumb",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "type",
|
||||
"columnName": "type",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "time",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "downloadPath",
|
||||
"columnName": "downloadPath",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "website",
|
||||
"columnName": "website",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"columnNames": [
|
||||
"id"
|
||||
],
|
||||
"autoGenerate": true
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "downloads",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`url` TEXT NOT NULL, `title` TEXT NOT NULL, `author` TEXT NOT NULL, `thumb` TEXT NOT NULL, `duration` TEXT NOT NULL, `type` TEXT NOT NULL, `audioQualityId` TEXT NOT NULL, `videoQualityId` TEXT NOT NULL, `customTemplateId` INTEGER NOT NULL, `audioFormat` TEXT NOT NULL, `videoFormat` TEXT NOT NULL, `formatDesc` TEXT NOT NULL, `removeAudio` INTEGER NOT NULL DEFAULT 0, `downloadPath` TEXT NOT NULL, `website` TEXT NOT NULL, `downloadSize` TEXT NOT NULL, `playlistTitle` TEXT NOT NULL, `status` TEXT NOT NULL DEFAULT 'Queued', `id` INTEGER PRIMARY KEY AUTOINCREMENT)",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "url",
|
||||
"columnName": "url",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "title",
|
||||
"columnName": "title",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "author",
|
||||
"columnName": "author",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "thumb",
|
||||
"columnName": "thumb",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "duration",
|
||||
"columnName": "duration",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "type",
|
||||
"columnName": "type",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "audioQualityId",
|
||||
"columnName": "audioQualityId",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "videoQualityId",
|
||||
"columnName": "videoQualityId",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "customTemplateId",
|
||||
"columnName": "customTemplateId",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "audioFormat",
|
||||
"columnName": "audioFormat",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "videoFormat",
|
||||
"columnName": "videoFormat",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "formatDesc",
|
||||
"columnName": "formatDesc",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "removeAudio",
|
||||
"columnName": "removeAudio",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true,
|
||||
"defaultValue": "0"
|
||||
},
|
||||
{
|
||||
"fieldPath": "downloadPath",
|
||||
"columnName": "downloadPath",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "website",
|
||||
"columnName": "website",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "downloadSize",
|
||||
"columnName": "downloadSize",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "playlistTitle",
|
||||
"columnName": "playlistTitle",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "status",
|
||||
"columnName": "status",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true,
|
||||
"defaultValue": "'Queued'"
|
||||
},
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"columnNames": [
|
||||
"id"
|
||||
],
|
||||
"autoGenerate": true
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "commandTemplates",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`title` TEXT NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT)",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "title",
|
||||
"columnName": "title",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "content",
|
||||
"columnName": "content",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"columnNames": [
|
||||
"id"
|
||||
],
|
||||
"autoGenerate": true
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
}
|
||||
],
|
||||
"views": [],
|
||||
"setupQueries": [
|
||||
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '1391e7ec82bbacc310cf6f23e3d1f85a')"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
package com.deniscerri.ytdlnis;
|
||||
|
||||
import android.content.Context;
|
||||
import androidx.test.platform.app.InstrumentationRegistry;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Instrumented test, which will execute on an Android device.
|
||||
*
|
||||
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
|
||||
*/
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class ExampleInstrumentedTest {
|
||||
@Test
|
||||
public void useAppContext() {
|
||||
// Context of the app under test.
|
||||
Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
|
||||
|
||||
assertEquals("com.deniscerri.ytdl", appContext.getPackageName());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
package com.deniscerri.ytdlnis
|
||||
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import org.junit.Assert
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
/**
|
||||
* Instrumented test, which will execute on an Android device.
|
||||
*
|
||||
* @see [Testing documentation](http://d.android.com/tools/testing)
|
||||
*/
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class ExampleInstrumentedTest {
|
||||
@Test
|
||||
fun useAppContext() {
|
||||
// Context of the app under test.
|
||||
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
|
||||
Assert.assertEquals("com.deniscerri.ytdl", appContext.packageName)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.deniscerri.ytdlnis" >
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import androidx.work.ExistingWorkPolicy
|
|||
import androidx.work.OneTimeWorkRequestBuilder
|
||||
import androidx.work.WorkManager
|
||||
import androidx.work.workDataOf
|
||||
import com.deniscerri.ytdlnis.database.Video
|
||||
import com.deniscerri.ytdlnis.database.models.ResultItem
|
||||
import com.deniscerri.ytdlnis.service.DownloadInfo
|
||||
import com.deniscerri.ytdlnis.service.IDownloaderListener
|
||||
import com.deniscerri.ytdlnis.service.IDownloaderService
|
||||
|
|
@ -46,7 +46,7 @@ class DownloaderService : Service() {
|
|||
ConcurrentHashMap()
|
||||
private val fileUtil = FileUtil()
|
||||
private val downloadInfo = DownloadInfo()
|
||||
private var downloadQueue = LinkedList<Video>()
|
||||
private var downloadQueue = LinkedList<ResultItem>()
|
||||
private val compositeDisposable = CompositeDisposable()
|
||||
private val notificationUtil = App.notificationUtil
|
||||
private var context: Context? = null
|
||||
|
|
@ -91,44 +91,45 @@ class DownloaderService : Service() {
|
|||
}
|
||||
|
||||
override fun onBind(intent: Intent): IBinder? {
|
||||
val theIntent: Intent
|
||||
val pendingIntent: PendingIntent
|
||||
if (intent.getBooleanExtra("rebind", false)) {
|
||||
return binder
|
||||
}
|
||||
when (val id = intent.getIntExtra("id", 1)) {
|
||||
NotificationUtil.DOWNLOAD_NOTIFICATION_ID -> {
|
||||
notificationChannelID = NotificationUtil.DOWNLOAD_SERVICE_CHANNEL_ID
|
||||
theIntent = Intent(this, MainActivity::class.java)
|
||||
pendingIntent =
|
||||
PendingIntent.getActivity(this, 0, theIntent, PendingIntent.FLAG_IMMUTABLE)
|
||||
downloadNotificationID = id
|
||||
val queue: ArrayList<out Video>? = intent.getParcelableArrayListExtra("queue")
|
||||
downloadQueue = LinkedList()
|
||||
downloadQueue.addAll(queue!!)
|
||||
downloadInfo.downloadQueue = downloadQueue
|
||||
val title = downloadInfo.video.title
|
||||
val notification =
|
||||
App.notificationUtil.createDownloadServiceNotification(pendingIntent, title, NotificationUtil.DOWNLOAD_SERVICE_CHANNEL_ID)
|
||||
startForeground(downloadNotificationID, notification)
|
||||
startDownload(downloadQueue)
|
||||
}
|
||||
NotificationUtil.COMMAND_DOWNLOAD_NOTIFICATION_ID -> {
|
||||
notificationChannelID = NotificationUtil.COMMAND_DOWNLOAD_SERVICE_CHANNEL_ID
|
||||
theIntent = Intent(this, CustomCommandActivity::class.java)
|
||||
pendingIntent =
|
||||
PendingIntent.getActivity(this, 0, theIntent, PendingIntent.FLAG_IMMUTABLE)
|
||||
downloadNotificationID = id
|
||||
val command = intent.getStringExtra("command")
|
||||
val commandNotification = App.notificationUtil.createDownloadServiceNotification(
|
||||
pendingIntent,
|
||||
getString(R.string.running_ytdlp_command),
|
||||
NotificationUtil.COMMAND_DOWNLOAD_SERVICE_CHANNEL_ID
|
||||
)
|
||||
startForeground(downloadNotificationID, commandNotification)
|
||||
startCommandDownload(command)
|
||||
}
|
||||
}
|
||||
// val theIntent: Intent
|
||||
// val pendingIntent: PendingIntent
|
||||
// if (intent.getBooleanExtra("rebind", false)) {
|
||||
// return binder
|
||||
// }
|
||||
// when (val id = intent.getIntExtra("id", 1)) {
|
||||
// NotificationUtil.DOWNLOAD_NOTIFICATION_ID -> {
|
||||
// notificationChannelID = NotificationUtil.DOWNLOAD_SERVICE_CHANNEL_ID
|
||||
// theIntent = Intent(this, MainActivity::class.java)
|
||||
// pendingIntent =
|
||||
// PendingIntent.getActivity(this, 0, theIntent, PendingIntent.FLAG_IMMUTABLE)
|
||||
// downloadNotificationID = id
|
||||
// val queue: ArrayList<out ResultItem>? = intent.getParcelableArrayListExtra("queue")
|
||||
// downloadQueue = LinkedList()
|
||||
// downloadQueue.addAll(queue!!)
|
||||
// downloadInfo.downloadQueue = downloadQueue
|
||||
// val title = downloadInfo.video.title
|
||||
// val notification =
|
||||
// App.notificationUtil.createDownloadServiceNotification(pendingIntent, title, 1, NotificationUtil.DOWNLOAD_SERVICE_CHANNEL_ID)
|
||||
// startForeground(downloadNotificationID, notification)
|
||||
// startDownload(downloadQueue)
|
||||
// }
|
||||
// NotificationUtil.COMMAND_DOWNLOAD_NOTIFICATION_ID -> {
|
||||
// notificationChannelID = NotificationUtil.COMMAND_DOWNLOAD_SERVICE_CHANNEL_ID
|
||||
// theIntent = Intent(this, CustomCommandActivity::class.java)
|
||||
// pendingIntent =
|
||||
// PendingIntent.getActivity(this, 0, theIntent, PendingIntent.FLAG_IMMUTABLE)
|
||||
// downloadNotificationID = id
|
||||
// val command = intent.getStringExtra("command")
|
||||
// val commandNotification = App.notificationUtil.createDownloadServiceNotification(
|
||||
// pendingIntent,
|
||||
// getString(R.string.running_ytdlp_command),
|
||||
// 1,
|
||||
// NotificationUtil.COMMAND_DOWNLOAD_SERVICE_CHANNEL_ID
|
||||
// )
|
||||
// startForeground(downloadNotificationID, commandNotification)
|
||||
// startCommandDownload(command)
|
||||
// }
|
||||
// }
|
||||
return binder
|
||||
}
|
||||
|
||||
|
|
@ -160,23 +161,24 @@ class DownloaderService : Service() {
|
|||
activities.remove(activity)
|
||||
}
|
||||
|
||||
override fun updateQueue(queue: ArrayList<Video>) {
|
||||
try {
|
||||
for (i in queue.indices) {
|
||||
downloadQueue.add(queue[i].clone() as Video)
|
||||
}
|
||||
if (downloadQueue.size == queue.size) {
|
||||
downloadInfo.downloadQueue = downloadQueue
|
||||
startDownload(downloadQueue)
|
||||
} else {
|
||||
downloadInfo.downloadQueue = downloadQueue
|
||||
Toast.makeText(context, getString(R.string.added_to_queue), Toast.LENGTH_SHORT)
|
||||
.show()
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Toast.makeText(context, "Couldn't update download queue! :(", Toast.LENGTH_SHORT)
|
||||
.show()
|
||||
}
|
||||
|
||||
override fun updateQueue(queue: ArrayList<ResultItem>) {
|
||||
// try {
|
||||
// for (i in queue.indices) {
|
||||
// downloadQueue.add(queue[i].clone() as ResultItem)
|
||||
// }
|
||||
// if (downloadQueue.size == queue.size) {
|
||||
// downloadInfo.downloadQueue = downloadQueue
|
||||
// startDownload(downloadQueue)
|
||||
// } else {
|
||||
// downloadInfo.downloadQueue = downloadQueue
|
||||
// Toast.makeText(context, getString(R.string.added_to_queue), Toast.LENGTH_SHORT)
|
||||
// .show()
|
||||
// }
|
||||
// } catch (e: Exception) {
|
||||
// Toast.makeText(context, "Couldn't update download queue! :(", Toast.LENGTH_SHORT)
|
||||
// .show()
|
||||
// }
|
||||
}
|
||||
|
||||
override fun cancelDownload(cancelAll: Boolean) {
|
||||
|
|
@ -192,30 +194,31 @@ class DownloaderService : Service() {
|
|||
}
|
||||
}
|
||||
|
||||
override fun removeItemFromDownloadQueue(video: Video, type: String) {
|
||||
//if its the same video with the same download type as the current downloading one
|
||||
if (downloadInfo.video.getURL() == video.getURL() && downloadInfo.video.downloadedType == video.downloadedType) {
|
||||
cancelDownload(false)
|
||||
downloadInfo.downloadType = type
|
||||
onDownloadCancel(downloadInfo)
|
||||
downloadQueue.pop()
|
||||
downloadInfo.downloadQueue = downloadQueue
|
||||
startDownload(downloadQueue)
|
||||
} else {
|
||||
downloadQueue.remove(video)
|
||||
try {
|
||||
val info = DownloadInfo()
|
||||
info.video = video
|
||||
info.downloadType = type
|
||||
onDownloadCancel(info)
|
||||
} catch (ignored: Exception) {
|
||||
}
|
||||
}
|
||||
Toast.makeText(
|
||||
context,
|
||||
video.title + " " + getString(R.string.removed_from_queue),
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
|
||||
override fun removeItemFromDownloadQueue(video: ResultItem?, type: String?) {
|
||||
// //if its the same video with the same download type as the current downloading one
|
||||
// if (downloadInfo.video.url == video.url && downloadInfo.video.type == video.downloadedType) {
|
||||
// cancelDownload(false)
|
||||
// downloadInfo.downloadType = type
|
||||
// onDownloadCancel(downloadInfo)
|
||||
// downloadQueue.pop()
|
||||
// downloadInfo.downloadQueue = downloadQueue
|
||||
// startDownload(downloadQueue)
|
||||
// } else {
|
||||
// downloadQueue.remove(video)
|
||||
// try {
|
||||
// val info = DownloadInfo()
|
||||
// info.video = video
|
||||
// info.downloadType = type
|
||||
// onDownloadCancel(info)
|
||||
// } catch (ignored: Exception) {
|
||||
// }
|
||||
// }
|
||||
// Toast.makeText(
|
||||
// context,
|
||||
// video.title + " " + getString(R.string.removed_from_queue),
|
||||
// Toast.LENGTH_SHORT
|
||||
// ).show()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -277,212 +280,212 @@ class DownloaderService : Service() {
|
|||
}
|
||||
}
|
||||
|
||||
private fun startDownload(videos: LinkedList<Video>) {
|
||||
if (videos.size == 0) {
|
||||
finishService()
|
||||
return
|
||||
}
|
||||
val video: Video = try {
|
||||
videos.peek() as Video
|
||||
} catch (e: Exception) {
|
||||
finishService()
|
||||
return
|
||||
}
|
||||
try {
|
||||
for (activity in activities.keys) {
|
||||
activity.runOnUiThread {
|
||||
for (i in activities[activity]!!.indices) {
|
||||
val callback = activities[activity]!![i]
|
||||
callback.onDownloadStart(downloadInfo)
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (err: Exception) {
|
||||
err.printStackTrace()
|
||||
}
|
||||
val url = video.getURL()
|
||||
val request = YoutubeDLRequest(url)
|
||||
val type = video.downloadedType
|
||||
val downloadLocation = getDownloadLocation(type)
|
||||
|
||||
var tempFileDir = File(cacheDir.absolutePath + """/${video.title}##${video.downloadedType}""")
|
||||
tempFileDir.delete()
|
||||
tempFileDir.mkdir()
|
||||
|
||||
val sharedPreferences = context!!.getSharedPreferences("root_preferences", MODE_PRIVATE)
|
||||
val aria2 = sharedPreferences.getBoolean("aria2", false)
|
||||
if (aria2) {
|
||||
request.addOption("--downloader", "libaria2c.so")
|
||||
request.addOption("--external-downloader-args", "aria2c:\"--summary-interval=1\"")
|
||||
} else {
|
||||
val concurrentFragments = sharedPreferences.getInt("concurrent_fragments", 1)
|
||||
if (concurrentFragments > 1) request.addOption("-N", concurrentFragments)
|
||||
}
|
||||
val limitRate = sharedPreferences.getString("limit_rate", "")
|
||||
if (limitRate != "") request.addOption("-r", limitRate!!)
|
||||
val writeThumbnail = sharedPreferences.getBoolean("write_thumbnail", false)
|
||||
if (writeThumbnail) {
|
||||
request.addOption("--write-thumbnail")
|
||||
request.addOption("--convert-thumbnails", "png")
|
||||
}
|
||||
request.addOption("--no-mtime")
|
||||
val sponsorBlockFilters = sharedPreferences.getStringSet("sponsorblock_filters", emptySet())
|
||||
if (sponsorBlockFilters!!.isNotEmpty()) {
|
||||
val filters = java.lang.String.join(",", sponsorBlockFilters)
|
||||
request.addOption("--sponsorblock-remove", filters)
|
||||
}
|
||||
if (type == "audio") {
|
||||
if (downloadLocation.equals(getString(R.string.music_path))){
|
||||
tempFileDir = File(getString(R.string.music_path))
|
||||
}
|
||||
|
||||
request.addOption("-x")
|
||||
var format = video.audioFormat
|
||||
if (format == null) format = sharedPreferences.getString("audio_format", "")
|
||||
request.addOption("--audio-format", format!!)
|
||||
request.addOption("--embed-metadata")
|
||||
|
||||
val embedThumb = sharedPreferences.getBoolean("embed_thumbnail", false)
|
||||
if (embedThumb) {
|
||||
request.addOption("--embed-thumbnail")
|
||||
request.addOption("--convert-thumbnails", "png")
|
||||
try {
|
||||
val config = File(cacheDir, "config" + video.videoId + ".txt")
|
||||
val config_data =
|
||||
"--ppa \"ffmpeg: -c:v png -vf crop=\\\"'if(gt(ih,iw),iw,ih)':'if(gt(iw,ih),ih,iw)'\\\"\""
|
||||
val stream = FileOutputStream(config)
|
||||
stream.write(config_data.toByteArray())
|
||||
stream.close()
|
||||
request.addOption("--config", config.absolutePath)
|
||||
} catch (ignored: java.lang.Exception) {
|
||||
}
|
||||
}
|
||||
request.addOption("--parse-metadata", "%(release_year,upload_date)s:%(meta_date)s")
|
||||
request.addCommands(Arrays.asList("--replace-in-metadata", "title", ".*.", video.title))
|
||||
request.addCommands(Arrays.asList("--replace-in-metadata", "uploader", ".*.", video.author))
|
||||
|
||||
if (!video.playlistTitle.isEmpty()) {
|
||||
request.addOption("--parse-metadata", "%(album,playlist,title)s:%(meta_album)s")
|
||||
request.addOption("--parse-metadata", "%(track_number,playlist_index)d:%(meta_track)s")
|
||||
} else {
|
||||
request.addOption("--parse-metadata", "%(album,title)s:%(meta_album)s")
|
||||
}
|
||||
request.addOption("-o", tempFileDir.absolutePath + "/%(uploader)s - %(title)s.%(ext)s")
|
||||
} else if (type == "video") {
|
||||
if (downloadLocation.equals(getString(R.string.video_path))){
|
||||
tempFileDir = File(getString(R.string.video_path))
|
||||
}
|
||||
|
||||
val addChapters = sharedPreferences.getBoolean("add_chapters", false)
|
||||
if (addChapters) {
|
||||
request.addOption("--sponsorblock-mark", "all")
|
||||
}
|
||||
val embedSubs = sharedPreferences.getBoolean("embed_subtitles", false)
|
||||
if (embedSubs) {
|
||||
request.addOption("--embed-subs", "")
|
||||
}
|
||||
var videoQuality = video.videoQuality
|
||||
if (videoQuality == null) videoQuality =
|
||||
sharedPreferences.getString("video_quality", "")
|
||||
var formatArgument = "bestvideo+bestaudio/best"
|
||||
if (videoQuality == "Worst Quality") {
|
||||
formatArgument = "worst"
|
||||
} else if (!videoQuality!!.isEmpty() && videoQuality != "Best Quality") {
|
||||
formatArgument = "bestvideo[height<=" + videoQuality.substring(
|
||||
0,
|
||||
videoQuality.length - 1
|
||||
) + "]+bestaudio/best"
|
||||
}
|
||||
request.addOption("-f", formatArgument)
|
||||
var format = video.videoFormat
|
||||
if (format == null) format = sharedPreferences.getString("video_format", "")
|
||||
if (format != "DEFAULT") request.addOption("--merge-output-format", format!!)
|
||||
if (format != "webm") {
|
||||
val embedThumb = sharedPreferences.getBoolean("embed_thumbnail", false)
|
||||
if (embedThumb) {
|
||||
request.addOption("--embed-thumbnail")
|
||||
}
|
||||
}
|
||||
request.addOption("-o", tempFileDir.absolutePath + "/%(uploader)s - %(title)s.%(ext)s")
|
||||
}
|
||||
|
||||
val disposable = Observable.fromCallable {
|
||||
YoutubeDL.getInstance().execute(request, downloadProcessID, callback)
|
||||
}
|
||||
.subscribeOn(Schedulers.newThread())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe({
|
||||
val workTag = video.getURL()
|
||||
val workData = workDataOf(
|
||||
originDir to tempFileDir.absolutePath,
|
||||
downLocation to downloadLocation,
|
||||
title to video.title
|
||||
)
|
||||
val fileTransferWorkRequest = OneTimeWorkRequestBuilder<FileTransferWorker>()
|
||||
.addTag(workTag)
|
||||
.setInputData(workData)
|
||||
.build()
|
||||
workManager.enqueueUniqueWork(
|
||||
workTag,
|
||||
ExistingWorkPolicy.KEEP,
|
||||
fileTransferWorkRequest
|
||||
)
|
||||
|
||||
downloadInfo.downloadPath = fileUtil.formatPath(getDownloadLocation(type)!!)
|
||||
Log.e(TAG, downloadInfo.downloadPath)
|
||||
downloadInfo.downloadType = type
|
||||
|
||||
|
||||
|
||||
try {
|
||||
for (activity in activities.keys) {
|
||||
activity.runOnUiThread {
|
||||
for (i in activities[activity]!!.indices) {
|
||||
val callback = activities[activity]!![i]
|
||||
callback.onDownloadEnd(downloadInfo)
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Toast.makeText(context, e.message, Toast.LENGTH_LONG).show()
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
// SCAN NEXT IN QUEUE
|
||||
videos.remove()
|
||||
downloadInfo.downloadQueue = videos
|
||||
startDownload(videos)
|
||||
}) { e: Throwable? ->
|
||||
tempFileDir.delete()
|
||||
if (BuildConfig.DEBUG) {
|
||||
Toast.makeText(context, e!!.message, Toast.LENGTH_LONG).show()
|
||||
Log.e(TAG, getString(R.string.failed_download), e)
|
||||
}
|
||||
notificationUtil.updateDownloadNotification(
|
||||
NotificationUtil.DOWNLOAD_NOTIFICATION_ID,
|
||||
getString(R.string.failed_download), 0, 0, downloadQueue.peek()?.title,
|
||||
NotificationUtil.DOWNLOAD_SERVICE_CHANNEL_ID
|
||||
)
|
||||
downloadInfo.downloadType = type
|
||||
try {
|
||||
for (activity in activities.keys) {
|
||||
activity.runOnUiThread {
|
||||
for (i in activities[activity]!!.indices) {
|
||||
val callback = activities[activity]!![i]
|
||||
callback.onDownloadError(downloadInfo)
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (err: Exception) {
|
||||
err.printStackTrace()
|
||||
}
|
||||
|
||||
// SCAN NEXT IN QUEUE
|
||||
videos.remove()
|
||||
downloadInfo.downloadQueue = videos
|
||||
startDownload(videos)
|
||||
}
|
||||
compositeDisposable.add(disposable)
|
||||
private fun startDownload(videos: LinkedList<ResultItem>) {
|
||||
// if (videos.size == 0) {
|
||||
// finishService()
|
||||
// return
|
||||
// }
|
||||
// val video: ResultItem = try {
|
||||
// videos.peek() as ResultItem
|
||||
// } catch (e: Exception) {
|
||||
// finishService()
|
||||
// return
|
||||
// }
|
||||
// try {
|
||||
// for (activity in activities.keys) {
|
||||
// activity.runOnUiThread {
|
||||
// for (i in activities[activity]!!.indices) {
|
||||
// val callback = activities[activity]!![i]
|
||||
// callback.onDownloadStart(downloadInfo)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// } catch (err: Exception) {
|
||||
// err.printStackTrace()
|
||||
// }
|
||||
// val url = video.getURL()
|
||||
// val request = YoutubeDLRequest(url)
|
||||
// val type = video.downloadedType
|
||||
// val downloadLocation = getDownloadLocation(type)
|
||||
//
|
||||
// var tempFileDir = File(cacheDir.absolutePath + """/${video.title}##${video.downloadedType}""")
|
||||
// tempFileDir.delete()
|
||||
// tempFileDir.mkdir()
|
||||
//
|
||||
// val sharedPreferences = context!!.getSharedPreferences("root_preferences", MODE_PRIVATE)
|
||||
// val aria2 = sharedPreferences.getBoolean("aria2", false)
|
||||
// if (aria2) {
|
||||
// request.addOption("--downloader", "libaria2c.so")
|
||||
// request.addOption("--external-downloader-args", "aria2c:\"--summary-interval=1\"")
|
||||
// } else {
|
||||
// val concurrentFragments = sharedPreferences.getInt("concurrent_fragments", 1)
|
||||
// if (concurrentFragments > 1) request.addOption("-N", concurrentFragments)
|
||||
// }
|
||||
// val limitRate = sharedPreferences.getString("limit_rate", "")
|
||||
// if (limitRate != "") request.addOption("-r", limitRate!!)
|
||||
// val writeThumbnail = sharedPreferences.getBoolean("write_thumbnail", false)
|
||||
// if (writeThumbnail) {
|
||||
// request.addOption("--write-thumbnail")
|
||||
// request.addOption("--convert-thumbnails", "png")
|
||||
// }
|
||||
// request.addOption("--no-mtime")
|
||||
// val sponsorBlockFilters = sharedPreferences.getStringSet("sponsorblock_filters", emptySet())
|
||||
// if (sponsorBlockFilters!!.isNotEmpty()) {
|
||||
// val filters = java.lang.String.join(",", sponsorBlockFilters)
|
||||
// request.addOption("--sponsorblock-remove", filters)
|
||||
// }
|
||||
// if (type == "audio") {
|
||||
// if (downloadLocation.equals(getString(R.string.music_path))){
|
||||
// tempFileDir = File(getString(R.string.music_path))
|
||||
// }
|
||||
//
|
||||
// request.addOption("-x")
|
||||
// var format = video.audioFormat
|
||||
// if (format == null) format = sharedPreferences.getString("audio_format", "")
|
||||
// request.addOption("--audio-format", format!!)
|
||||
// request.addOption("--embed-metadata")
|
||||
//
|
||||
// val embedThumb = sharedPreferences.getBoolean("embed_thumbnail", false)
|
||||
// if (embedThumb) {
|
||||
// request.addOption("--embed-thumbnail")
|
||||
// request.addOption("--convert-thumbnails", "png")
|
||||
// try {
|
||||
// val config = File(cacheDir, "config" + video.videoId + ".txt")
|
||||
// val config_data =
|
||||
// "--ppa \"ffmpeg: -c:v png -vf crop=\\\"'if(gt(ih,iw),iw,ih)':'if(gt(iw,ih),ih,iw)'\\\"\""
|
||||
// val stream = FileOutputStream(config)
|
||||
// stream.write(config_data.toByteArray())
|
||||
// stream.close()
|
||||
// request.addOption("--config", config.absolutePath)
|
||||
// } catch (ignored: java.lang.Exception) {
|
||||
// }
|
||||
// }
|
||||
// request.addOption("--parse-metadata", "%(release_year,upload_date)s:%(meta_date)s")
|
||||
// request.addCommands(Arrays.asList("--replace-in-metadata", "title", ".*.", video.title))
|
||||
// request.addCommands(Arrays.asList("--replace-in-metadata", "uploader", ".*.", video.author))
|
||||
//
|
||||
// if (!video.playlistTitle.isEmpty()) {
|
||||
// request.addOption("--parse-metadata", "%(album,playlist,title)s:%(meta_album)s")
|
||||
// request.addOption("--parse-metadata", "%(track_number,playlist_index)d:%(meta_track)s")
|
||||
// } else {
|
||||
// request.addOption("--parse-metadata", "%(album,title)s:%(meta_album)s")
|
||||
// }
|
||||
// request.addOption("-o", tempFileDir.absolutePath + "/%(uploader)s - %(title)s.%(ext)s")
|
||||
// } else if (type == "video") {
|
||||
// if (downloadLocation.equals(getString(R.string.video_path))){
|
||||
// tempFileDir = File(getString(R.string.video_path))
|
||||
// }
|
||||
//
|
||||
// val addChapters = sharedPreferences.getBoolean("add_chapters", false)
|
||||
// if (addChapters) {
|
||||
// request.addOption("--sponsorblock-mark", "all")
|
||||
// }
|
||||
// val embedSubs = sharedPreferences.getBoolean("embed_subtitles", false)
|
||||
// if (embedSubs) {
|
||||
// request.addOption("--embed-subs", "")
|
||||
// }
|
||||
// var videoQuality = video.videoQuality
|
||||
// if (videoQuality == null) videoQuality =
|
||||
// sharedPreferences.getString("video_quality", "")
|
||||
// var formatArgument = "bestvideo+bestaudio/best"
|
||||
// if (videoQuality == "Worst Quality") {
|
||||
// formatArgument = "worst"
|
||||
// } else if (!videoQuality!!.isEmpty() && videoQuality != "Best Quality") {
|
||||
// formatArgument = "bestvideo[height<=" + videoQuality.substring(
|
||||
// 0,
|
||||
// videoQuality.length - 1
|
||||
// ) + "]+bestaudio/best"
|
||||
// }
|
||||
// request.addOption("-f", formatArgument)
|
||||
// var format = video.videoFormat
|
||||
// if (format == null) format = sharedPreferences.getString("video_format", "")
|
||||
// if (format != "DEFAULT") request.addOption("--merge-output-format", format!!)
|
||||
// if (format != "webm") {
|
||||
// val embedThumb = sharedPreferences.getBoolean("embed_thumbnail", false)
|
||||
// if (embedThumb) {
|
||||
// request.addOption("--embed-thumbnail")
|
||||
// }
|
||||
// }
|
||||
// request.addOption("-o", tempFileDir.absolutePath + "/%(uploader)s - %(title)s.%(ext)s")
|
||||
// }
|
||||
//
|
||||
// val disposable = Observable.fromCallable {
|
||||
// YoutubeDL.getInstance().execute(request, downloadProcessID, callback)
|
||||
// }
|
||||
// .subscribeOn(Schedulers.newThread())
|
||||
// .observeOn(AndroidSchedulers.mainThread())
|
||||
// .subscribe({
|
||||
// val workTag = video.getURL()
|
||||
// val workData = workDataOf(
|
||||
// originDir to tempFileDir.absolutePath,
|
||||
// downLocation to downloadLocation,
|
||||
// title to video.title
|
||||
// )
|
||||
// val fileTransferWorkRequest = OneTimeWorkRequestBuilder<FileTransferWorker>()
|
||||
// .addTag(workTag)
|
||||
// .setInputData(workData)
|
||||
// .build()
|
||||
// workManager.enqueueUniqueWork(
|
||||
// workTag,
|
||||
// ExistingWorkPolicy.KEEP,
|
||||
// fileTransferWorkRequest
|
||||
// )
|
||||
//
|
||||
// downloadInfo.downloadPath = fileUtil.formatPath(getDownloadLocation(type)!!)
|
||||
// Log.e(TAG, downloadInfo.downloadPath)
|
||||
// downloadInfo.downloadType = type
|
||||
//
|
||||
//
|
||||
//
|
||||
// try {
|
||||
// for (activity in activities.keys) {
|
||||
// activity.runOnUiThread {
|
||||
// for (i in activities[activity]!!.indices) {
|
||||
// val callback = activities[activity]!![i]
|
||||
// callback.onDownloadEnd(downloadInfo)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// } catch (e: Exception) {
|
||||
// Toast.makeText(context, e.message, Toast.LENGTH_LONG).show()
|
||||
// e.printStackTrace()
|
||||
// }
|
||||
//
|
||||
// // SCAN NEXT IN QUEUE
|
||||
// videos.remove()
|
||||
// downloadInfo.downloadQueue = videos
|
||||
// startDownload(videos)
|
||||
// }) { e: Throwable? ->
|
||||
// tempFileDir.delete()
|
||||
// if (BuildConfig.DEBUG) {
|
||||
// Toast.makeText(context, e!!.message, Toast.LENGTH_LONG).show()
|
||||
// Log.e(TAG, getString(R.string.failed_download), e)
|
||||
// }
|
||||
// notificationUtil.updateDownloadNotification(
|
||||
// NotificationUtil.DOWNLOAD_NOTIFICATION_ID,
|
||||
// getString(R.string.failed_download), 0, 0, downloadQueue.peek()?.title,
|
||||
// NotificationUtil.DOWNLOAD_SERVICE_CHANNEL_ID
|
||||
// )
|
||||
// downloadInfo.downloadType = type
|
||||
// try {
|
||||
// for (activity in activities.keys) {
|
||||
// activity.runOnUiThread {
|
||||
// for (i in activities[activity]!!.indices) {
|
||||
// val callback = activities[activity]!![i]
|
||||
// callback.onDownloadError(downloadInfo)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// } catch (err: Exception) {
|
||||
// err.printStackTrace()
|
||||
// }
|
||||
//
|
||||
// // SCAN NEXT IN QUEUE
|
||||
// videos.remove()
|
||||
// downloadInfo.downloadQueue = videos
|
||||
// startDownload(videos)
|
||||
// }
|
||||
// compositeDisposable.add(disposable)
|
||||
}
|
||||
|
||||
private fun startCommandDownload(text: String?) {
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ import androidx.fragment.app.Fragment
|
|||
import androidx.fragment.app.FragmentManager
|
||||
import com.deniscerri.ytdlnis.DownloaderService.LocalBinder
|
||||
import com.deniscerri.ytdlnis.database.DatabaseManager
|
||||
import com.deniscerri.ytdlnis.database.Video
|
||||
import com.deniscerri.ytdlnis.database.models.ResultItem
|
||||
import com.deniscerri.ytdlnis.databinding.ActivityMainBinding
|
||||
import com.deniscerri.ytdlnis.ui.DownloadsFragment
|
||||
import com.deniscerri.ytdlnis.ui.HomeFragment
|
||||
|
|
@ -193,7 +193,6 @@ class MainActivity : AppCompatActivity() {
|
|||
.commit()
|
||||
lastFragment = homeFragment
|
||||
listeners = ArrayList()
|
||||
listeners.add(homeFragment.listener)
|
||||
}
|
||||
|
||||
private fun replaceFragment(f: Fragment) {
|
||||
|
|
@ -202,37 +201,38 @@ class MainActivity : AppCompatActivity() {
|
|||
}
|
||||
|
||||
fun startDownloadService(
|
||||
downloadQueue: ArrayList<Video>,
|
||||
downloadQueue: ArrayList<ResultItem>,
|
||||
awaitingListener: IDownloaderListener
|
||||
) {
|
||||
addQueueToDownloads(downloadQueue)
|
||||
if (isDownloadServiceRunning) {
|
||||
iDownloaderService?.updateQueue(downloadQueue)
|
||||
return
|
||||
}
|
||||
if (!listeners.contains(awaitingListener)) listeners.add(awaitingListener)
|
||||
val serviceIntent = Intent(context, DownloaderService::class.java)
|
||||
serviceIntent.putParcelableArrayListExtra("queue", downloadQueue)
|
||||
context.applicationContext.startService(serviceIntent)
|
||||
context.applicationContext.bindService(serviceIntent, serviceConnection, BIND_AUTO_CREATE)
|
||||
// addQueueToDownloads(downloadQueue)
|
||||
// if (isDownloadServiceRunning) {
|
||||
// iDownloaderService?.updateQueue(downloadQueue)
|
||||
// return
|
||||
// }
|
||||
// if (!listeners.contains(awaitingListener)) listeners.add(awaitingListener)
|
||||
// val serviceIntent = Intent(context, DownloaderService::class.java)
|
||||
// serviceIntent.putParcelableArrayListExtra("queue", downloadQueue)
|
||||
// context.applicationContext.startService(serviceIntent)
|
||||
// context.applicationContext.bindService(serviceIntent, serviceConnection, BIND_AUTO_CREATE)
|
||||
|
||||
}
|
||||
|
||||
private fun addQueueToDownloads(downloadQueue: ArrayList<Video>) {
|
||||
try {
|
||||
val sharedPreferences = context.getSharedPreferences("root_preferences", MODE_PRIVATE)
|
||||
if (!sharedPreferences.getBoolean("incognito", false)) {
|
||||
val databaseManager = DatabaseManager(context)
|
||||
for (i in downloadQueue.indices.reversed()) {
|
||||
val v = downloadQueue[i]
|
||||
v.isQueuedDownload = true
|
||||
databaseManager.addToHistory(v)
|
||||
}
|
||||
databaseManager.close()
|
||||
//downloadsFragment.initCards()
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
private fun addQueueToDownloads(downloadQueue: ArrayList<ResultItem>) {
|
||||
// try {
|
||||
// val sharedPreferences = context.getSharedPreferences("root_preferences", MODE_PRIVATE)
|
||||
// if (!sharedPreferences.getBoolean("incognito", false)) {
|
||||
// val databaseManager = DatabaseManager(context)
|
||||
// for (i in downloadQueue.indices.reversed()) {
|
||||
// val v = downloadQueue[i]
|
||||
// v.isQueuedDownload = true
|
||||
// databaseManager.addToHistory(v)
|
||||
// }
|
||||
// databaseManager.close()
|
||||
// //downloadsFragment.initCards()
|
||||
// }
|
||||
// } catch (e: Exception) {
|
||||
// e.printStackTrace()
|
||||
// }
|
||||
}
|
||||
|
||||
fun stopDownloadService() {
|
||||
|
|
@ -257,7 +257,7 @@ class MainActivity : AppCompatActivity() {
|
|||
stopDownloadService()
|
||||
}
|
||||
|
||||
fun removeItemFromDownloadQueue(video: Video?, type: String?) {
|
||||
fun removeItemFromDownloadQueue(video: ResultItem?, type: String?) {
|
||||
iDownloaderService!!.removeItemFromDownloadQueue(video, type)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -84,7 +84,6 @@ public class HistoryAdapter extends ListAdapter<HistoryItem, HistoryAdapter.View
|
|||
@Override
|
||||
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
|
||||
HistoryItem video = getItem(position);
|
||||
Log.e("AAA", String.valueOf(position));
|
||||
MaterialCardView card = holder.cardView;
|
||||
// THUMBNAIL ----------------------------------
|
||||
ImageView thumbnail = card.findViewById(R.id.downloads_image_view);
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import android.app.Activity;
|
|||
import android.graphics.Color;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
|
@ -12,10 +13,12 @@ import android.widget.LinearLayout;
|
|||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.recyclerview.widget.DiffUtil;
|
||||
import androidx.recyclerview.widget.ListAdapter;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.deniscerri.ytdlnis.R;
|
||||
import com.deniscerri.ytdlnis.database.Video;
|
||||
import com.deniscerri.ytdlnis.database.models.ResultItem;
|
||||
import com.google.android.material.button.MaterialButton;
|
||||
import com.google.android.material.card.MaterialCardView;
|
||||
import com.google.android.material.progressindicator.LinearProgressIndicator;
|
||||
|
|
@ -23,19 +26,33 @@ import com.squareup.picasso.Picasso;
|
|||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class HomeAdapter extends RecyclerView.Adapter<HomeAdapter.ViewHolder> {
|
||||
private ArrayList<Video> videoList;
|
||||
private ArrayList<Integer> checkedVideos;
|
||||
public class HomeAdapter extends ListAdapter<ResultItem, HomeAdapter.ViewHolder> {
|
||||
private final ArrayList<Integer> checkedVideos;
|
||||
private final OnItemClickListener onItemClickListener;
|
||||
private Activity activity;
|
||||
|
||||
public HomeAdapter(ArrayList<Video> videos, OnItemClickListener onItemClickListener, Activity activity){
|
||||
this.videoList = videos;
|
||||
public HomeAdapter(HomeAdapter.OnItemClickListener onItemClickListener, Activity activity){
|
||||
super(DIFF_CALLBACK);
|
||||
this.checkedVideos = new ArrayList<>();
|
||||
this.onItemClickListener = onItemClickListener;
|
||||
this.activity = activity;
|
||||
Log.e("TAG", "adapter");
|
||||
}
|
||||
|
||||
private static final DiffUtil.ItemCallback<ResultItem> DIFF_CALLBACK = new DiffUtil.ItemCallback<ResultItem>() {
|
||||
@Override
|
||||
public boolean areItemsTheSame(@NonNull ResultItem oldItem, @NonNull ResultItem newItem) {
|
||||
Log.e("TAG", "adapter2");
|
||||
return oldItem.getId() == newItem.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean areContentsTheSame(@NonNull ResultItem oldItem, @NonNull ResultItem newItem) {
|
||||
Log.e("TAG", "adapter3");
|
||||
return oldItem.getUrl().equals(newItem.getUrl());
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
return super.getItemViewType(position);
|
||||
|
|
@ -61,8 +78,8 @@ public class HomeAdapter extends RecyclerView.Adapter<HomeAdapter.ViewHolder> {
|
|||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
|
||||
Video video = videoList.get(position);
|
||||
|
||||
ResultItem video = getItem(position);
|
||||
Log.e("TAG", "adapter4");
|
||||
MaterialCardView card = holder.cardView;
|
||||
// THUMBNAIL ----------------------------------
|
||||
ImageView thumbnail = card.findViewById(R.id.result_image_view);
|
||||
|
|
@ -97,7 +114,7 @@ public class HomeAdapter extends RecyclerView.Adapter<HomeAdapter.ViewHolder> {
|
|||
}
|
||||
|
||||
// BUTTONS ----------------------------------
|
||||
String videoID = video.getVideoId();
|
||||
int videoID = video.getId();
|
||||
|
||||
LinearLayout buttonLayout = card.findViewById(R.id.download_button_layout);
|
||||
|
||||
|
|
@ -116,39 +133,42 @@ public class HomeAdapter extends RecyclerView.Adapter<HomeAdapter.ViewHolder> {
|
|||
|
||||
LinearProgressIndicator progressBar = card.findViewById(R.id.download_progress);
|
||||
progressBar.setTag(videoID + "##progress");
|
||||
progressBar.setProgress(0);
|
||||
progressBar.setIndeterminate(true);
|
||||
progressBar.setVisibility(View.GONE);
|
||||
|
||||
if (video.isDownloading()){
|
||||
progressBar.setVisibility(View.VISIBLE);
|
||||
}else {
|
||||
progressBar.setProgress(0);
|
||||
progressBar.setIndeterminate(true);
|
||||
progressBar.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if (video.isDownloadingAudio()) {
|
||||
musicBtn.setIcon(ContextCompat.getDrawable(activity, R.drawable.ic_cancel));
|
||||
musicBtn.setTag(R.id.cancelDownload, "true");
|
||||
}else{
|
||||
if(video.isAudioDownloaded() == 1){
|
||||
musicBtn.setIcon(ContextCompat.getDrawable(activity, R.drawable.ic_music_downloaded));
|
||||
}else{
|
||||
musicBtn.setIcon(ContextCompat.getDrawable(activity, R.drawable.ic_music));
|
||||
}
|
||||
}
|
||||
|
||||
if (video.isDownloadingVideo()){
|
||||
videoBtn.setIcon(ContextCompat.getDrawable(activity, R.drawable.ic_cancel));
|
||||
videoBtn.setTag(R.id.cancelDownload, "true");
|
||||
}else{
|
||||
if(video.isVideoDownloaded() == 1){
|
||||
videoBtn.setIcon(ContextCompat.getDrawable(activity, R.drawable.ic_video_downloaded));
|
||||
}else{
|
||||
videoBtn.setIcon(ContextCompat.getDrawable(activity, R.drawable.ic_video));
|
||||
}
|
||||
}
|
||||
// if (video.isDownloading()){
|
||||
// progressBar.setVisibility(View.VISIBLE);
|
||||
// }else {
|
||||
// progressBar.setProgress(0);
|
||||
// progressBar.setIndeterminate(true);
|
||||
// progressBar.setVisibility(View.GONE);
|
||||
// }
|
||||
//
|
||||
// if (video.isDownloadingAudio()) {
|
||||
// musicBtn.setIcon(ContextCompat.getDrawable(activity, R.drawable.ic_cancel));
|
||||
// musicBtn.setTag(R.id.cancelDownload, "true");
|
||||
// }else{
|
||||
// if(video.isAudioDownloaded() == 1){
|
||||
// musicBtn.setIcon(ContextCompat.getDrawable(activity, R.drawable.ic_music_downloaded));
|
||||
// }else{
|
||||
// musicBtn.setIcon(ContextCompat.getDrawable(activity, R.drawable.ic_music));
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (video.isDownloadingVideo()){
|
||||
// videoBtn.setIcon(ContextCompat.getDrawable(activity, R.drawable.ic_cancel));
|
||||
// videoBtn.setTag(R.id.cancelDownload, "true");
|
||||
// }else{
|
||||
// if(video.isVideoDownloaded() == 1){
|
||||
// videoBtn.setIcon(ContextCompat.getDrawable(activity, R.drawable.ic_video_downloaded));
|
||||
// }else{
|
||||
// videoBtn.setIcon(ContextCompat.getDrawable(activity, R.drawable.ic_video));
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
if(checkedVideos.contains(position)){
|
||||
if(checkedVideos.contains(videoID)){
|
||||
card.setChecked(true);
|
||||
card.setStrokeWidth(5);
|
||||
}else{
|
||||
|
|
@ -158,41 +178,32 @@ public class HomeAdapter extends RecyclerView.Adapter<HomeAdapter.ViewHolder> {
|
|||
|
||||
card.setTag(videoID + "##card");
|
||||
card.setOnLongClickListener(view -> {
|
||||
checkCard(card, position);
|
||||
checkCard(card, videoID);
|
||||
return true;
|
||||
});
|
||||
card.setOnClickListener(view -> {
|
||||
if(checkedVideos.size() > 0){
|
||||
checkCard(card, position);
|
||||
checkCard(card, videoID);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void checkCard(MaterialCardView card, int position){
|
||||
private void checkCard(MaterialCardView card, int videoID){
|
||||
if(card.isChecked()){
|
||||
card.setStrokeWidth(0);
|
||||
checkedVideos.remove(Integer.valueOf(position));
|
||||
checkedVideos.remove(Integer.valueOf(videoID));
|
||||
}else{
|
||||
card.setStrokeWidth(5);
|
||||
checkedVideos.add(position);
|
||||
checkedVideos.add(videoID);
|
||||
}
|
||||
card.setChecked(!card.isChecked());
|
||||
onItemClickListener.onCardClick(position, card.isChecked());
|
||||
onItemClickListener.onCardClick(videoID, card.isChecked());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return videoList.size();
|
||||
}
|
||||
|
||||
public interface OnItemClickListener {
|
||||
void onButtonClick(int position, String type);
|
||||
void onCardClick(int position, boolean add);
|
||||
}
|
||||
|
||||
public void updateVideoListItem(Video v, int position){
|
||||
videoList.set(position, v);
|
||||
notifyItemChanged(position);
|
||||
void onButtonClick(int videoID, String type);
|
||||
void onCardClick(int videoID, boolean add);
|
||||
}
|
||||
|
||||
public void clearCheckedVideos(){
|
||||
|
|
@ -203,16 +214,4 @@ public class HomeAdapter extends RecyclerView.Adapter<HomeAdapter.ViewHolder> {
|
|||
}
|
||||
checkedVideos.clear();
|
||||
}
|
||||
|
||||
public void clear(){
|
||||
int size = videoList.size();
|
||||
videoList = new ArrayList<>();
|
||||
notifyItemRangeRemoved(0, size);
|
||||
}
|
||||
|
||||
public void add(ArrayList<Video> vids){
|
||||
int position = videoList.size() + 1;
|
||||
videoList.addAll(vids);
|
||||
notifyItemRangeInserted(position, vids.size());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ import android.database.sqlite.SQLiteOpenHelper;
|
|||
import android.widget.Toast;
|
||||
|
||||
import com.deniscerri.ytdlnis.R;
|
||||
import com.deniscerri.ytdlnis.database.models.HistoryItem;
|
||||
import com.deniscerri.ytdlnis.database.models.ResultItem;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
|
|
@ -90,63 +92,63 @@ public class DatabaseManager extends SQLiteOpenHelper {
|
|||
}
|
||||
|
||||
@SuppressLint("Range")
|
||||
public void clearHistoryItem(Video video, boolean delete_file){
|
||||
SQLiteDatabase db = this.getWritableDatabase();
|
||||
|
||||
if (delete_file){
|
||||
try{
|
||||
Cursor cursor = db.rawQuery("SELECT * FROM " + history_table_name + " WHERE url='" +
|
||||
video.getURL() + "' AND type='"+video.getDownloadedType() + "' LIMIT 1", null);
|
||||
|
||||
if(cursor.moveToFirst()){
|
||||
String path = cursor.getString(cursor.getColumnIndex(downloadPath));
|
||||
File file = new File(path);
|
||||
if(file.exists()){
|
||||
file.delete();
|
||||
}
|
||||
}
|
||||
}catch (Exception e){
|
||||
Toast.makeText(context, R.string.error_deleting_file, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
db.execSQL("DELETE FROM " + history_table_name + " WHERE id=" + video.getId());
|
||||
|
||||
String where = "";
|
||||
switch(video.getDownloadedType()){
|
||||
case "audio":
|
||||
where = " SET downloadedAudio=0 WHERE downloadedAudio=1 AND videoId='" + video.getVideoId()+"'";
|
||||
break;
|
||||
case "video":
|
||||
where = " SET downloadedVideo=0 WHERE downloadedVideo=1 AND videoId='" + video.getVideoId()+"'";
|
||||
break;
|
||||
}
|
||||
|
||||
//remove downloaded status from results
|
||||
db.execSQL("UPDATE "+results_table_name+ where);
|
||||
public void clearHistoryItem(HistoryItem video, boolean delete_file){
|
||||
// SQLiteDatabase db = this.getWritableDatabase();
|
||||
//
|
||||
// if (delete_file){
|
||||
// try{
|
||||
// Cursor cursor = db.rawQuery("SELECT * FROM " + history_table_name + " WHERE url='" +
|
||||
// video.getURL() + "' AND type='"+video.getDownloadedType() + "' LIMIT 1", null);
|
||||
//
|
||||
// if(cursor.moveToFirst()){
|
||||
// String path = cursor.getString(cursor.getColumnIndex(downloadPath));
|
||||
// File file = new File(path);
|
||||
// if(file.exists()){
|
||||
// file.delete();
|
||||
// }
|
||||
// }
|
||||
// }catch (Exception e){
|
||||
// Toast.makeText(context, R.string.error_deleting_file, Toast.LENGTH_SHORT).show();
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//
|
||||
// db.execSQL("DELETE FROM " + history_table_name + " WHERE id=" + video.getId());
|
||||
//
|
||||
// String where = "";
|
||||
// switch(video.getDownloadedType()){
|
||||
// case "audio":
|
||||
// where = " SET downloadedAudio=0 WHERE downloadedAudio=1 AND videoId='" + video.getVideoId()+"'";
|
||||
// break;
|
||||
// case "video":
|
||||
// where = " SET downloadedVideo=0 WHERE downloadedVideo=1 AND videoId='" + video.getVideoId()+"'";
|
||||
// break;
|
||||
// }
|
||||
//
|
||||
// //remove downloaded status from results
|
||||
// db.execSQL("UPDATE "+results_table_name+ where);
|
||||
}
|
||||
|
||||
public void clearDeletedHistory(){
|
||||
ArrayList<Video> videos = getHistory("","","","");
|
||||
for (int i = 0; i < videos.size(); i++){
|
||||
Video video = videos.get(i);
|
||||
String path = video.getDownloadPath();
|
||||
File file = new File(path);
|
||||
if(!file.exists() && !path.isEmpty()){
|
||||
clearHistoryItem(video, false);
|
||||
}
|
||||
}
|
||||
// ArrayList<ResultItem> videos = getHistory("","","","");
|
||||
// for (int i = 0; i < videos.size(); i++){
|
||||
// ResultItem video = videos.get(i);
|
||||
// String path = video.getDownloadPath();
|
||||
// File file = new File(path);
|
||||
// if(!file.exists() && !path.isEmpty()){
|
||||
// clearHistoryItem(video, false);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
public void clearDownloadingHistory(){
|
||||
ArrayList<Video> videos = getHistory("","","","");
|
||||
for (int i = 0; i < videos.size(); i++){
|
||||
Video video = videos.get(i);
|
||||
if(video.isQueuedDownload()){
|
||||
clearHistoryItem(video, false);
|
||||
}
|
||||
}
|
||||
// ArrayList<ResultItem> videos = getHistory("","","","");
|
||||
// for (int i = 0; i < videos.size(); i++){
|
||||
// ResultItem video = videos.get(i);
|
||||
// if(video.isQueuedDownload()){
|
||||
// clearHistoryItem(video, false);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
public void clearDuplicateHistory(){
|
||||
|
|
@ -176,36 +178,36 @@ public class DatabaseManager extends SQLiteOpenHelper {
|
|||
|
||||
|
||||
@SuppressLint("Range")
|
||||
public ArrayList<Video> getResults(){
|
||||
public ArrayList<ResultItem> getResults(){
|
||||
SQLiteDatabase db = this.getReadableDatabase();
|
||||
Cursor cursor = db.rawQuery("SELECT * FROM " + results_table_name, null);
|
||||
ArrayList<Video> list = new ArrayList<>();
|
||||
ArrayList<ResultItem> list = new ArrayList<>();
|
||||
|
||||
if(cursor.moveToFirst()){
|
||||
do {
|
||||
// on below line we are adding the data from cursor to our array list.
|
||||
list.add(new Video(cursor.getString(cursor.getColumnIndex(videoId)),
|
||||
cursor.getString(cursor.getColumnIndex(url)),
|
||||
cursor.getString(cursor.getColumnIndex(title)),
|
||||
cursor.getString(cursor.getColumnIndex(author)),
|
||||
cursor.getString(cursor.getColumnIndex(duration)),
|
||||
cursor.getString(cursor.getColumnIndex(thumb)),
|
||||
cursor.getInt(cursor.getColumnIndex(downloadedAudio)),
|
||||
cursor.getInt(cursor.getColumnIndex(downloadedVideo)),
|
||||
cursor.getInt(cursor.getColumnIndex(isPlaylistItem)),
|
||||
cursor.getString(cursor.getColumnIndex(website)),
|
||||
cursor.getInt(cursor.getColumnIndex(downloadedAudio)),
|
||||
cursor.getInt(cursor.getColumnIndex(downloadingVideo)),
|
||||
cursor.getString(cursor.getColumnIndex(playlistTitle))));
|
||||
} while (cursor.moveToNext());
|
||||
}
|
||||
|
||||
cursor.close();
|
||||
// if(cursor.moveToFirst()){
|
||||
// do {
|
||||
// // on below line we are adding the data from cursor to our array list.
|
||||
// list.add(new ResultItem(cursor.getString(cursor.getColumnIndex(videoId)),
|
||||
// cursor.getString(cursor.getColumnIndex(url)),
|
||||
// cursor.getString(cursor.getColumnIndex(title)),
|
||||
// cursor.getString(cursor.getColumnIndex(author)),
|
||||
// cursor.getString(cursor.getColumnIndex(duration)),
|
||||
// cursor.getString(cursor.getColumnIndex(thumb)),
|
||||
// cursor.getInt(cursor.getColumnIndex(downloadedAudio)),
|
||||
// cursor.getInt(cursor.getColumnIndex(downloadedVideo)),
|
||||
// cursor.getInt(cursor.getColumnIndex(isPlaylistItem)),
|
||||
// cursor.getString(cursor.getColumnIndex(website)),
|
||||
// cursor.getInt(cursor.getColumnIndex(downloadedAudio)),
|
||||
// cursor.getInt(cursor.getColumnIndex(downloadingVideo)),
|
||||
// cursor.getString(cursor.getColumnIndex(playlistTitle))));
|
||||
// } while (cursor.moveToNext());
|
||||
// }
|
||||
//
|
||||
// cursor.close();
|
||||
return list;
|
||||
}
|
||||
|
||||
@SuppressLint("Range")
|
||||
public ArrayList<Video> getHistory(String query, String format, String site, String sort){
|
||||
public ArrayList<ResultItem> getHistory(String query, String format, String site, String sort){
|
||||
SQLiteDatabase db = this.getReadableDatabase();
|
||||
|
||||
if (sort == null || sort.isEmpty()) sort = "DESC";
|
||||
|
|
@ -215,91 +217,91 @@ public class DatabaseManager extends SQLiteOpenHelper {
|
|||
" AND website LIKE '%"+site+"%'"+
|
||||
" ORDER BY id "+sort,
|
||||
null);
|
||||
ArrayList<Video> list = new ArrayList<>();
|
||||
|
||||
if(cursor.moveToFirst()){
|
||||
do {
|
||||
// on below line we are adding the data from cursor to our array list.
|
||||
list.add(new Video(cursor.getInt(cursor.getColumnIndex(id)),
|
||||
cursor.getString(cursor.getColumnIndex(url)),
|
||||
cursor.getString(cursor.getColumnIndex(title)),
|
||||
cursor.getString(cursor.getColumnIndex(author)),
|
||||
cursor.getString(cursor.getColumnIndex(duration)),
|
||||
cursor.getString(cursor.getColumnIndex(thumb)),
|
||||
cursor.getString(cursor.getColumnIndex(type)),
|
||||
cursor.getString(cursor.getColumnIndex(time)),
|
||||
cursor.getString(cursor.getColumnIndex(downloadPath)),
|
||||
cursor.getString(cursor.getColumnIndex(website)),
|
||||
cursor.getInt(cursor.getColumnIndex(isQueuedDownload))));
|
||||
} while (cursor.moveToNext());
|
||||
}
|
||||
|
||||
cursor.close();
|
||||
ArrayList<ResultItem> list = new ArrayList<>();
|
||||
//
|
||||
// if(cursor.moveToFirst()){
|
||||
// do {
|
||||
// // on below line we are adding the data from cursor to our array list.
|
||||
// list.add(new ResultItem(cursor.getInt(cursor.getColumnIndex(id)),
|
||||
// cursor.getString(cursor.getColumnIndex(url)),
|
||||
// cursor.getString(cursor.getColumnIndex(title)),
|
||||
// cursor.getString(cursor.getColumnIndex(author)),
|
||||
// cursor.getString(cursor.getColumnIndex(duration)),
|
||||
// cursor.getString(cursor.getColumnIndex(thumb)),
|
||||
// cursor.getString(cursor.getColumnIndex(type)),
|
||||
// cursor.getString(cursor.getColumnIndex(time)),
|
||||
// cursor.getString(cursor.getColumnIndex(downloadPath)),
|
||||
// cursor.getString(cursor.getColumnIndex(website)),
|
||||
// cursor.getInt(cursor.getColumnIndex(isQueuedDownload))));
|
||||
// } while (cursor.moveToNext());
|
||||
// }
|
||||
//
|
||||
// cursor.close();
|
||||
return list;
|
||||
}
|
||||
|
||||
public void addToResults(ArrayList<Video> videot){
|
||||
public void addToResults(ArrayList<ResultItem> videot){
|
||||
SQLiteDatabase db = this.getWritableDatabase();
|
||||
ContentValues values = new ContentValues();
|
||||
|
||||
for(Video v : videot){
|
||||
values.put(videoId, v.getVideoId());
|
||||
values.put(url, v.getURL());
|
||||
values.put(title, v.getTitle());
|
||||
values.put(author, v.getAuthor());
|
||||
values.put(duration, v.getDuration());
|
||||
values.put(thumb, v.getThumb());
|
||||
values.put(downloadedAudio, v.isAudioDownloaded());
|
||||
values.put(downloadedVideo, v.isVideoDownloaded());
|
||||
values.put(isPlaylistItem, v.getIsPlaylistItem());
|
||||
values.put(website, v.getWebsite());
|
||||
values.put(downloadingAudio, 0);
|
||||
values.put(downloadingVideo, 0);
|
||||
values.put(playlistTitle, v.getPlaylistTitle());
|
||||
|
||||
db.insert(results_table_name, null, values);
|
||||
}
|
||||
|
||||
db.close();
|
||||
// for(ResultItem v : videot){
|
||||
// values.put(videoId, v.getVideoId());
|
||||
// values.put(url, v.getURL());
|
||||
// values.put(title, v.getTitle());
|
||||
// values.put(author, v.getAuthor());
|
||||
// values.put(duration, v.getDuration());
|
||||
// values.put(thumb, v.getThumb());
|
||||
// values.put(downloadedAudio, v.isAudioDownloaded());
|
||||
// values.put(downloadedVideo, v.isVideoDownloaded());
|
||||
// values.put(isPlaylistItem, v.getIsPlaylistItem());
|
||||
// values.put(website, v.getWebsite());
|
||||
// values.put(downloadingAudio, 0);
|
||||
// values.put(downloadingVideo, 0);
|
||||
// values.put(playlistTitle, v.getPlaylistTitle());
|
||||
//
|
||||
// db.insert(results_table_name, null, values);
|
||||
// }
|
||||
//
|
||||
// db.close();
|
||||
}
|
||||
|
||||
public void addToHistory(Video v){
|
||||
public void addToHistory(ResultItem v){
|
||||
SQLiteDatabase db = this.getWritableDatabase();
|
||||
ContentValues values = new ContentValues();
|
||||
|
||||
values.put(url, v.getURL());
|
||||
values.put(title, v.getTitle());
|
||||
values.put(author, v.getAuthor());
|
||||
values.put(duration, v.getDuration());
|
||||
values.put(thumb, v.getThumb());
|
||||
values.put(type, v.getDownloadedType());
|
||||
values.put(time, v.getDownloadedTime());
|
||||
values.put(downloadPath, v.getDownloadPath());
|
||||
values.put(website, v.getWebsite());
|
||||
values.put(isQueuedDownload, (v.isQueuedDownload()) ? 1 : 0);
|
||||
|
||||
db.insert(history_table_name, null, values);
|
||||
db.close();
|
||||
//
|
||||
// values.put(url, v.getURL());
|
||||
// values.put(title, v.getTitle());
|
||||
// values.put(author, v.getAuthor());
|
||||
// values.put(duration, v.getDuration());
|
||||
// values.put(thumb, v.getThumb());
|
||||
// values.put(type, v.getDownloadedType());
|
||||
// values.put(time, v.getDownloadedTime());
|
||||
// values.put(downloadPath, v.getDownloadPath());
|
||||
// values.put(website, v.getWebsite());
|
||||
// values.put(isQueuedDownload, (v.isQueuedDownload()) ? 1 : 0);
|
||||
//
|
||||
// db.insert(history_table_name, null, values);
|
||||
// db.close();
|
||||
}
|
||||
|
||||
public void updateHistoryItem(Video v){
|
||||
public void updateHistoryItem(ResultItem v){
|
||||
SQLiteDatabase db = this.getWritableDatabase();
|
||||
ContentValues values = new ContentValues();
|
||||
|
||||
values.put(url, v.getURL());
|
||||
values.put(title, v.getTitle());
|
||||
values.put(author, v.getAuthor());
|
||||
values.put(duration, v.getDuration());
|
||||
values.put(thumb, v.getThumb());
|
||||
values.put(type, v.getDownloadedType());
|
||||
values.put(time, v.getDownloadedTime());
|
||||
values.put(downloadPath, v.getDownloadPath());
|
||||
values.put(website, v.getWebsite());
|
||||
values.put(isQueuedDownload, (v.isQueuedDownload()) ? 1 : 0);
|
||||
|
||||
String where = url + "='"+v.getURL()+"' AND "+isQueuedDownload+"=1 AND "+type+"='"+v.getDownloadedType()+"'";
|
||||
db.update(history_table_name, values, where, null);
|
||||
db.close();
|
||||
// values.put(url, v.getURL());
|
||||
// values.put(title, v.getTitle());
|
||||
// values.put(author, v.getAuthor());
|
||||
// values.put(duration, v.getDuration());
|
||||
// values.put(thumb, v.getThumb());
|
||||
// values.put(type, v.getDownloadedType());
|
||||
// values.put(time, v.getDownloadedTime());
|
||||
// values.put(downloadPath, v.getDownloadPath());
|
||||
// values.put(website, v.getWebsite());
|
||||
// values.put(isQueuedDownload, (v.isQueuedDownload()) ? 1 : 0);
|
||||
//
|
||||
// String where = url + "='"+v.getURL()+"' AND "+isQueuedDownload+"=1 AND "+type+"='"+v.getDownloadedType()+"'";
|
||||
// db.update(history_table_name, values, where, null);
|
||||
// db.close();
|
||||
}
|
||||
|
||||
public void updateDownloadStatusOnResult(String id, String type, boolean downloaded){
|
||||
|
|
|
|||
|
|
@ -1,338 +0,0 @@
|
|||
package com.deniscerri.ytdlnis.database;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
public class Video implements Parcelable, Cloneable {
|
||||
private int id;
|
||||
private String videoId;
|
||||
private String title;
|
||||
private String author;
|
||||
private String duration;
|
||||
private String thumb;
|
||||
private String url;
|
||||
private String downloadedType;
|
||||
private int downloadedAudio;
|
||||
private int downloadedVideo;
|
||||
private String downloadedTime;
|
||||
private int isPlaylistItem;
|
||||
private String downloadPath;
|
||||
private String website;
|
||||
private boolean downloadingAudio;
|
||||
private boolean downloadingVideo;
|
||||
private boolean queuedDownload;
|
||||
private String playlistTitle;
|
||||
private String audioFormat;
|
||||
private String videoFormat;
|
||||
private String videoQuality;
|
||||
|
||||
// RESULTS OBJECT
|
||||
public Video(String videoId, String url, String title, String author, String duration, String thumb,
|
||||
int downloadedAudio, int downloadedVideo, int isPlaylistItem, String website, int downloadingAudio, int downloadingVideo, String playlistTitle) {
|
||||
this.videoId = videoId;
|
||||
this.url = url;
|
||||
this.title = title;
|
||||
this.author = author;
|
||||
this.duration = duration;
|
||||
this.thumb = thumb;
|
||||
this.downloadedVideo = downloadedVideo;
|
||||
this.downloadedAudio = downloadedAudio;
|
||||
this.isPlaylistItem = isPlaylistItem;
|
||||
this.website = website;
|
||||
this.downloadingAudio = intToBoolean(downloadingAudio);
|
||||
this.downloadingVideo = intToBoolean(downloadingVideo);
|
||||
this.playlistTitle = playlistTitle;
|
||||
}
|
||||
|
||||
//HISTORY OBJECT
|
||||
public Video(int id, String url, String title, String author, String duration, String thumb,
|
||||
String downloadedType, String downloadedTime, String downloadPath, String website, int queued) {
|
||||
this.id = id;
|
||||
this.url = url;
|
||||
this.title = title;
|
||||
this.author = author;
|
||||
this.duration = duration;
|
||||
this.thumb = thumb;
|
||||
this.downloadedType = downloadedType;
|
||||
this.downloadedTime = downloadedTime;
|
||||
this.downloadPath = downloadPath;
|
||||
this.website = website;
|
||||
this.queuedDownload = (queued == 1);
|
||||
}
|
||||
|
||||
private boolean intToBoolean(int i){
|
||||
return i == 1;
|
||||
}
|
||||
|
||||
protected Video(Parcel in) {
|
||||
id = in.readInt();
|
||||
videoId = in.readString();
|
||||
title = in.readString();
|
||||
author = in.readString();
|
||||
duration = in.readString();
|
||||
thumb = in.readString();
|
||||
url = in.readString();
|
||||
downloadedType = in.readString();
|
||||
downloadedAudio = in.readInt();
|
||||
downloadedVideo = in.readInt();
|
||||
downloadedTime = in.readString();
|
||||
isPlaylistItem = in.readInt();
|
||||
downloadPath = in.readString();
|
||||
website = in.readString();
|
||||
playlistTitle = in.readString();
|
||||
audioFormat = in.readString();
|
||||
videoFormat = in.readString();
|
||||
videoQuality = in.readString();
|
||||
}
|
||||
|
||||
public static final Creator<Video> CREATOR = new Creator<Video>() {
|
||||
@Override
|
||||
public Video createFromParcel(Parcel in) {
|
||||
return new Video(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Video[] newArray(int size) {
|
||||
return new Video[size];
|
||||
}
|
||||
};
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getVideoId() {
|
||||
return videoId;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public String getAuthor() {
|
||||
return author;
|
||||
}
|
||||
|
||||
public String getDuration() {
|
||||
return duration;
|
||||
}
|
||||
|
||||
public String getThumb() {
|
||||
return thumb;
|
||||
}
|
||||
|
||||
public String getDownloadedType() {
|
||||
return downloadedType;
|
||||
}
|
||||
|
||||
public void setDownloadedType(String downloadedType) {
|
||||
this.downloadedType = downloadedType;
|
||||
}
|
||||
|
||||
public String getDownloadedTime() {
|
||||
return downloadedTime;
|
||||
}
|
||||
|
||||
public void setDownloadedTime(String downloadedTime) {
|
||||
this.downloadedTime = downloadedTime;
|
||||
}
|
||||
|
||||
public int getIsPlaylistItem() {
|
||||
return isPlaylistItem;
|
||||
}
|
||||
|
||||
public void setIsPlaylistItem(int playlistItem) {
|
||||
this.isPlaylistItem = playlistItem;
|
||||
}
|
||||
|
||||
public int isAudioDownloaded() {
|
||||
return downloadedAudio;
|
||||
}
|
||||
|
||||
public int isVideoDownloaded() {
|
||||
return downloadedVideo;
|
||||
}
|
||||
|
||||
public String getURL(){ return url; }
|
||||
|
||||
public void setURL(String url) { this.url = url;}
|
||||
|
||||
public String getWebsite() { return website; }
|
||||
|
||||
public void setWebsite(String site){ this.website = site; }
|
||||
|
||||
public void setVideoId(String videoId) {
|
||||
this.videoId = videoId;
|
||||
}
|
||||
|
||||
public void setAuthor(String author) {
|
||||
this.author = author;
|
||||
}
|
||||
|
||||
public void setDuration(String duration) {
|
||||
this.duration = duration;
|
||||
}
|
||||
|
||||
public void setThumb(String thumb) {
|
||||
this.thumb = thumb;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public int getDownloadedAudio() {
|
||||
return downloadedAudio;
|
||||
}
|
||||
|
||||
public void setDownloadedAudio(int downloadedAudio) {
|
||||
this.downloadedAudio = downloadedAudio;
|
||||
}
|
||||
|
||||
public int getDownloadedVideo() {
|
||||
return downloadedVideo;
|
||||
}
|
||||
|
||||
public void setDownloadedVideo(int downloadedVideo) {
|
||||
this.downloadedVideo = downloadedVideo;
|
||||
}
|
||||
|
||||
public String getDownloadPath() {
|
||||
return downloadPath;
|
||||
}
|
||||
|
||||
public void setDownloadPath(String downloadPath) {
|
||||
this.downloadPath = downloadPath;
|
||||
}
|
||||
|
||||
public boolean isDownloadingAudio() {
|
||||
return downloadingAudio;
|
||||
}
|
||||
|
||||
public void setDownloadingAudio(boolean downloadingAudio) {
|
||||
this.downloadingAudio = downloadingAudio;
|
||||
}
|
||||
|
||||
public boolean isDownloadingVideo() {
|
||||
return downloadingVideo;
|
||||
}
|
||||
|
||||
public void setDownloadingVideo(boolean downloadingVideo) {
|
||||
this.downloadingVideo = downloadingVideo;
|
||||
}
|
||||
|
||||
public boolean isDownloading() {
|
||||
return this.downloadingAudio || this.downloadingVideo;
|
||||
}
|
||||
|
||||
public String getPlaylistTitle() {
|
||||
return playlistTitle;
|
||||
}
|
||||
|
||||
public void setPlaylistTitle(String playlistTitle) {
|
||||
this.playlistTitle = playlistTitle;
|
||||
}
|
||||
|
||||
public boolean isQueuedDownload() {
|
||||
return queuedDownload;
|
||||
}
|
||||
|
||||
public void setQueuedDownload(boolean queuedDownload) {
|
||||
this.queuedDownload = queuedDownload;
|
||||
}
|
||||
|
||||
public String getAudioFormat() {
|
||||
return audioFormat;
|
||||
}
|
||||
|
||||
public void setAudioFormat(String audioFormat) {
|
||||
this.audioFormat = audioFormat;
|
||||
}
|
||||
|
||||
public String getVideoFormat() {
|
||||
return videoFormat;
|
||||
}
|
||||
|
||||
public void setVideoFormat(String videoFormat) {
|
||||
this.videoFormat = videoFormat;
|
||||
}
|
||||
|
||||
public String getVideoQuality() {
|
||||
return videoQuality;
|
||||
}
|
||||
|
||||
public void setVideoQuality(String videoQuality) {
|
||||
this.videoQuality = videoQuality;
|
||||
}
|
||||
|
||||
public Object clone() throws CloneNotSupportedException
|
||||
{
|
||||
return super.clone();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel parcel, int i) {
|
||||
parcel.writeInt(id);
|
||||
parcel.writeString(videoId);
|
||||
parcel.writeString(title);
|
||||
parcel.writeString(author);
|
||||
parcel.writeString(duration);
|
||||
parcel.writeString(thumb);
|
||||
parcel.writeString(url);
|
||||
parcel.writeString(downloadedType);
|
||||
parcel.writeInt(downloadedAudio);
|
||||
parcel.writeInt(downloadedVideo);
|
||||
parcel.writeString(downloadedTime);
|
||||
parcel.writeInt(isPlaylistItem);
|
||||
parcel.writeString(downloadPath);
|
||||
parcel.writeString(website);
|
||||
parcel.writeString(playlistTitle);
|
||||
parcel.writeString(audioFormat);
|
||||
parcel.writeString(videoFormat);
|
||||
parcel.writeString(videoQuality);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Video{" +
|
||||
"id=" + id +
|
||||
", videoId='" + videoId + '\'' +
|
||||
", title='" + title + '\'' +
|
||||
", author='" + author + '\'' +
|
||||
", duration='" + duration + '\'' +
|
||||
", thumb='" + thumb + '\'' +
|
||||
", url='" + url + '\'' +
|
||||
", downloadedType='" + downloadedType + '\'' +
|
||||
", downloadedAudio=" + downloadedAudio +
|
||||
", downloadedVideo=" + downloadedVideo +
|
||||
", downloadedTime='" + downloadedTime + '\'' +
|
||||
", isPlaylistItem=" + isPlaylistItem +
|
||||
", downloadPath='" + downloadPath + '\'' +
|
||||
", website='" + website + '\'' +
|
||||
", downloadingAudio=" + downloadingAudio +
|
||||
", downloadingVideo=" + downloadingVideo +
|
||||
", queuedDownload=" + queuedDownload +
|
||||
", playlistTitle='" + playlistTitle + '\'' +
|
||||
", audioFormat='" + audioFormat + '\'' +
|
||||
", videoFormat='" + videoFormat + '\'' +
|
||||
", videoQuality='" + videoQuality + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
|
@ -10,7 +10,7 @@ import com.deniscerri.ytdlnis.util.FileUtil
|
|||
interface DownloadDao {
|
||||
|
||||
@Query("SELECT * FROM downloads")
|
||||
fun getAllDownloads() : List<DownloadItem>
|
||||
fun getAllDownloads() : LiveData<List<DownloadItem>>
|
||||
|
||||
@Query("SELECT * FROM downloads WHERE status='Queued'")
|
||||
fun getQueuedDownloads() : List<DownloadItem>
|
||||
|
|
|
|||
|
|
@ -4,10 +4,11 @@ import androidx.room.ColumnInfo
|
|||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
|
||||
@Entity(tableName = "downloads")
|
||||
@Entity(tableName = "commandTemplates")
|
||||
data class CommandTemplate(
|
||||
@PrimaryKey(autoGenerate = true)
|
||||
val id: Int,
|
||||
val title: String,
|
||||
val content: String
|
||||
)
|
||||
){
|
||||
@PrimaryKey(autoGenerate = true)
|
||||
var id: Int? = null
|
||||
}
|
||||
|
|
@ -6,8 +6,6 @@ import androidx.room.PrimaryKey
|
|||
|
||||
@Entity(tableName = "downloads")
|
||||
data class DownloadItem(
|
||||
@PrimaryKey(autoGenerate = true)
|
||||
val id: Int,
|
||||
val url: String,
|
||||
val title: String,
|
||||
val author: String,
|
||||
|
|
@ -28,4 +26,7 @@ data class DownloadItem(
|
|||
val playlistTitle: String,
|
||||
@ColumnInfo(defaultValue = "Queued")
|
||||
var status: String
|
||||
)
|
||||
){
|
||||
@PrimaryKey(autoGenerate = true)
|
||||
var id: Int? = null
|
||||
}
|
||||
|
|
@ -8,13 +8,14 @@ import com.yausername.youtubedl_android.mapper.VideoInfo
|
|||
|
||||
@Entity(tableName = "results")
|
||||
data class ResultItem(
|
||||
@PrimaryKey(autoGenerate = true)
|
||||
val id: Int,
|
||||
val url: String,
|
||||
val title: String,
|
||||
val author: String,
|
||||
val duration: String,
|
||||
val thumb: String,
|
||||
val website: String,
|
||||
val playlistTitle: String
|
||||
)
|
||||
var playlistTitle: String
|
||||
){
|
||||
@PrimaryKey(autoGenerate = true)
|
||||
var id: Int? = null
|
||||
}
|
||||
|
|
@ -5,6 +5,7 @@ import com.deniscerri.ytdlnis.database.dao.DownloadDao
|
|||
import com.deniscerri.ytdlnis.database.models.DownloadItem
|
||||
|
||||
class DownloadRepository(private val downloadDao: DownloadDao) {
|
||||
val allDownloads : LiveData<List<DownloadItem>> = downloadDao.getAllDownloads()
|
||||
|
||||
suspend fun insert(item: DownloadItem){
|
||||
downloadDao.insert(item)
|
||||
|
|
@ -19,7 +20,7 @@ class DownloadRepository(private val downloadDao: DownloadDao) {
|
|||
}
|
||||
|
||||
suspend fun getQueuedDownloads() : List<DownloadItem>{
|
||||
var items = downloadDao.getQueuedDownloads();
|
||||
val items = downloadDao.getQueuedDownloads()
|
||||
for (i in items){
|
||||
i.status = "Downloading"
|
||||
downloadDao.update(i)
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ class HistoryRepository(private val historyDao: HistoryDao) {
|
|||
}
|
||||
|
||||
suspend fun delete(item: HistoryItem, deleteFile: Boolean){
|
||||
historyDao.delete(item.id)
|
||||
historyDao.delete(item.id!!)
|
||||
if (deleteFile){
|
||||
val fileUtil = FileUtil()
|
||||
fileUtil.deleteFile(item.downloadPath)
|
||||
|
|
@ -53,7 +53,7 @@ class HistoryRepository(private val historyDao: HistoryDao) {
|
|||
val fileUtil = FileUtil()
|
||||
items.value?.forEach { item ->
|
||||
if (!fileUtil.exists(item.downloadPath)){
|
||||
historyDao.delete(item.id)
|
||||
historyDao.delete(item.id!!)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,17 +1,26 @@
|
|||
package com.deniscerri.ytdlnis.database.repository
|
||||
|
||||
import android.content.Context
|
||||
import androidx.lifecycle.LiveData
|
||||
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.ResultItem
|
||||
import com.deniscerri.ytdlnis.util.InfoUtil
|
||||
|
||||
class ResultRepository(private val resultDao: ResultDao) {
|
||||
val allResults : LiveData<List<ResultItem>> = resultDao.getResults()
|
||||
|
||||
suspend fun insert(items: List<ResultItem>){
|
||||
items.forEach {
|
||||
resultDao.insert(it)
|
||||
suspend fun insert(it: ResultItem){
|
||||
resultDao.insert(it)
|
||||
}
|
||||
|
||||
suspend fun updateTrending(context: Context){
|
||||
resultDao.deleteAll();
|
||||
val infoUtil = InfoUtil(context)
|
||||
val items = infoUtil.getTrending(context)
|
||||
for (i in items){
|
||||
resultDao.insert(i!!);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,27 +3,37 @@ package com.deniscerri.ytdlnis.database.viewmodel
|
|||
import android.app.Application
|
||||
import androidx.lifecycle.AndroidViewModel
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MediatorLiveData
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.deniscerri.ytdlnis.database.DBManager
|
||||
import com.deniscerri.ytdlnis.database.models.DownloadItem
|
||||
import com.deniscerri.ytdlnis.database.models.HistoryItem
|
||||
import com.deniscerri.ytdlnis.database.models.ResultItem
|
||||
import com.deniscerri.ytdlnis.database.repository.DownloadRepository
|
||||
import com.deniscerri.ytdlnis.database.repository.ResultRepository
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class ResultViewModel(application: Application) : AndroidViewModel(application) {
|
||||
private val repository : ResultRepository
|
||||
private val allResults : LiveData<List<ResultItem>>
|
||||
val items : LiveData<List<ResultItem>>
|
||||
|
||||
init {
|
||||
val dao = DBManager.getInstance(application).resultDao
|
||||
repository = ResultRepository(dao)
|
||||
allResults = repository.allResults
|
||||
items = repository.allResults
|
||||
}
|
||||
|
||||
fun insert(items: List<ResultItem>) = viewModelScope.launch(Dispatchers.IO){
|
||||
repository.insert(items)
|
||||
fun checkTrending() : Boolean{
|
||||
return items.value?.get(0)?.playlistTitle.equals("ytdlnis-TRENDING");
|
||||
}
|
||||
fun getTrending() = viewModelScope.launch(Dispatchers.IO){
|
||||
repository.updateTrending(getApplication<Application>().applicationContext);
|
||||
}
|
||||
|
||||
fun insert(items: ArrayList<ResultItem?>) = viewModelScope.launch(Dispatchers.IO){
|
||||
items.forEach {
|
||||
repository.insert(it!!)
|
||||
}
|
||||
}
|
||||
|
||||
fun deleteAll() = viewModelScope.launch(Dispatchers.IO) {
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
package com.deniscerri.ytdlnis.service;
|
||||
|
||||
import com.deniscerri.ytdlnis.database.Video;
|
||||
import com.deniscerri.ytdlnis.database.models.ResultItem;
|
||||
|
||||
import java.util.LinkedList;
|
||||
|
||||
public class DownloadInfo {
|
||||
private Video video;
|
||||
private ResultItem video;
|
||||
private int progress;
|
||||
private LinkedList<Video> downloadQueue;
|
||||
private LinkedList<ResultItem> downloadQueue;
|
||||
private String outputLine;
|
||||
private String downloadStatus;
|
||||
private String downloadPath;
|
||||
|
|
@ -15,11 +15,11 @@ public class DownloadInfo {
|
|||
|
||||
public DownloadInfo(){}
|
||||
|
||||
public Video getVideo() {
|
||||
public ResultItem getVideo() {
|
||||
return video;
|
||||
}
|
||||
|
||||
public void setVideo(Video video) {
|
||||
public void setVideo(ResultItem video) {
|
||||
this.video = video;
|
||||
}
|
||||
|
||||
|
|
@ -31,11 +31,11 @@ public class DownloadInfo {
|
|||
this.progress = progress;
|
||||
}
|
||||
|
||||
public LinkedList<Video> getDownloadQueue() {
|
||||
public LinkedList<ResultItem> getDownloadQueue() {
|
||||
return downloadQueue;
|
||||
}
|
||||
|
||||
public void setDownloadQueue(LinkedList<Video> downloadQueue) {
|
||||
public void setDownloadQueue(LinkedList<ResultItem> downloadQueue) {
|
||||
this.downloadQueue = downloadQueue;
|
||||
this.video = downloadQueue.peek();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
package com.deniscerri.ytdlnis.service;
|
||||
|
||||
import com.deniscerri.ytdlnis.database.Video;
|
||||
|
||||
public interface IDownloaderListener {
|
||||
void onDownloadStart(DownloadInfo downloadInfo);
|
||||
void onDownloadProgress(DownloadInfo downloadInfo);
|
||||
|
|
|
|||
|
|
@ -1,14 +1,16 @@
|
|||
package com.deniscerri.ytdlnis.service;
|
||||
|
||||
import android.app.Activity;
|
||||
import com.deniscerri.ytdlnis.database.Video;
|
||||
|
||||
import com.deniscerri.ytdlnis.database.models.ResultItem;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public interface IDownloaderService {
|
||||
DownloadInfo getInfo();
|
||||
void addActivity(Activity activity, ArrayList<IDownloaderListener> callback);
|
||||
void removeActivity(Activity activity);
|
||||
void updateQueue(ArrayList<Video> queue);
|
||||
void updateQueue(ArrayList<ResultItem> queue);
|
||||
void cancelDownload(boolean cancelAll);
|
||||
void removeItemFromDownloadQueue(Video video, String type);
|
||||
void removeItemFromDownloadQueue(ResultItem video, String type);
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
921
app/src/main/java/com/deniscerri/ytdlnis/ui/HomeFragment.kt
Normal file
921
app/src/main/java/com/deniscerri/ytdlnis/ui/HomeFragment.kt
Normal file
|
|
@ -0,0 +1,921 @@
|
|||
package com.deniscerri.ytdlnis.ui
|
||||
|
||||
import android.Manifest
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.text.InputType
|
||||
import android.util.Log
|
||||
import android.view.*
|
||||
import android.view.View.GONE
|
||||
import android.view.View.VISIBLE
|
||||
import android.widget.*
|
||||
import androidx.appcompat.widget.SearchView
|
||||
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
import androidx.core.app.ActivityCompat
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.deniscerri.ytdlnis.MainActivity
|
||||
import com.deniscerri.ytdlnis.R
|
||||
import com.deniscerri.ytdlnis.adapter.HomeAdapter
|
||||
import com.deniscerri.ytdlnis.database.DatabaseManager
|
||||
import com.deniscerri.ytdlnis.database.models.ResultItem
|
||||
import com.deniscerri.ytdlnis.database.viewmodel.HistoryViewModel
|
||||
import com.deniscerri.ytdlnis.database.viewmodel.ResultViewModel
|
||||
import com.deniscerri.ytdlnis.databinding.FragmentDownloadsBinding
|
||||
import com.deniscerri.ytdlnis.service.DownloadInfo
|
||||
import com.deniscerri.ytdlnis.util.FileUtil
|
||||
import com.deniscerri.ytdlnis.util.InfoUtil
|
||||
import com.facebook.shimmer.ShimmerFrameLayout
|
||||
import com.google.android.material.appbar.AppBarLayout
|
||||
import com.google.android.material.appbar.MaterialToolbar
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||
import com.google.android.material.button.MaterialButton
|
||||
import com.google.android.material.chip.ChipGroup
|
||||
import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
import com.google.android.material.progressindicator.LinearProgressIndicator
|
||||
import com.google.android.material.textfield.TextInputLayout
|
||||
import java.util.*
|
||||
import java.util.regex.Pattern
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, View.OnClickListener {
|
||||
private var progressBar: LinearProgressIndicator? = null
|
||||
private var inputQuery: String? = null
|
||||
private var inputQueries: LinkedList<String?>? = null
|
||||
private var inputQueriesLength = 0
|
||||
private var homeAdapter: HomeAdapter? = null
|
||||
private var searchSuggestions: ScrollView? = null
|
||||
private var searchSuggestionsLinearLayout: LinearLayout? = null
|
||||
private var downloadFabs: CoordinatorLayout? = null
|
||||
private var downloadAllFabCoordinator: CoordinatorLayout? = null
|
||||
private var homeFabs: CoordinatorLayout? = null
|
||||
private var infoUtil: InfoUtil? = null
|
||||
private var downloadQueue: ArrayList<ResultItem>? = null
|
||||
private var downloadInfo: DownloadInfo? = null
|
||||
|
||||
private lateinit var resultViewModel : ResultViewModel
|
||||
|
||||
private var downloading = false
|
||||
private var fragmentView: View? = null
|
||||
private var databaseManager: DatabaseManager? = null
|
||||
private var activity: Activity? = null
|
||||
private var mainActivity: MainActivity? = null
|
||||
private var fragmentContext: Context? = null
|
||||
private var layoutinflater: LayoutInflater? = null
|
||||
private var shimmerCards: ShimmerFrameLayout? = null
|
||||
private var topAppBar: MaterialToolbar? = null
|
||||
private var recyclerView: RecyclerView? = null
|
||||
private var bottomSheet: BottomSheetDialog? = null
|
||||
private var sortSheet: BottomSheetDialog? = null
|
||||
private var uiHandler: Handler? = null
|
||||
private var noResults: RelativeLayout? = null
|
||||
private var selectionChips: LinearLayout? = null
|
||||
private var websiteGroup: ChipGroup? = null
|
||||
private var resultsList: List<ResultItem?>? = null
|
||||
private var selectedObjects: ArrayList<ResultItem>? = null
|
||||
private var deleteFab: ExtendedFloatingActionButton? = null
|
||||
private var fileUtil: FileUtil? = null
|
||||
|
||||
private var _binding : FragmentDownloadsBinding? = null
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
_binding = FragmentDownloadsBinding.inflate(inflater, container, false)
|
||||
fragmentView = inflater.inflate(R.layout.fragment_home, container, false)
|
||||
activity = getActivity()
|
||||
mainActivity = activity as MainActivity?
|
||||
return fragmentView
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
fragmentContext = context
|
||||
layoutinflater = LayoutInflater.from(context)
|
||||
shimmerCards = view.findViewById(R.id.shimmer_downloads_framelayout)
|
||||
topAppBar = view.findViewById(R.id.downloads_toolbar)
|
||||
noResults = view.findViewById(R.id.downloads_no_results)
|
||||
selectionChips = view.findViewById(R.id.downloads_selection_chips)
|
||||
websiteGroup = view.findViewById(R.id.website_chip_group)
|
||||
deleteFab = view.findViewById(R.id.delete_selected_fab)
|
||||
fileUtil = FileUtil()
|
||||
deleteFab?.tag = "deleteSelected"
|
||||
deleteFab?.setOnClickListener(this)
|
||||
uiHandler = Handler(Looper.getMainLooper())
|
||||
selectedObjects = ArrayList()
|
||||
downloading = mainActivity!!.isDownloadServiceRunning()
|
||||
|
||||
|
||||
downloadQueue = ArrayList()
|
||||
resultsList = mutableListOf()
|
||||
selectedObjects = ArrayList()
|
||||
|
||||
//initViews
|
||||
shimmerCards = view.findViewById(R.id.shimmer_results_framelayout)
|
||||
topAppBar = view.findViewById(R.id.home_toolbar)
|
||||
searchSuggestions = view.findViewById(R.id.search_suggestions_scroll_view)
|
||||
searchSuggestionsLinearLayout = view.findViewById(R.id.search_suggestions_linear_layout)
|
||||
|
||||
homeAdapter =
|
||||
HomeAdapter(
|
||||
this,
|
||||
activity
|
||||
)
|
||||
recyclerView = view.findViewById(R.id.recyclerViewHome)
|
||||
recyclerView?.layoutManager = LinearLayoutManager(context)
|
||||
recyclerView?.adapter = homeAdapter
|
||||
|
||||
resultViewModel = ViewModelProvider(this)[ResultViewModel::class.java]
|
||||
resultViewModel.items.observe(viewLifecycleOwner) {
|
||||
homeAdapter!!.submitList(it)
|
||||
resultsList = it
|
||||
shimmerCards!!.stopShimmer()
|
||||
shimmerCards!!.visibility = GONE
|
||||
}
|
||||
|
||||
initMenu()
|
||||
|
||||
homeFabs = view.findViewById(R.id.home_fabs)
|
||||
downloadFabs = homeFabs!!.findViewById(R.id.download_selected_coordinator)
|
||||
downloadAllFabCoordinator = homeFabs!!.findViewById(R.id.download_all_coordinator)
|
||||
val musicFab = downloadFabs!!.findViewById<FloatingActionButton>(R.id.audio_fab)
|
||||
val videoFab = downloadFabs!!.findViewById<FloatingActionButton>(R.id.video_fab)
|
||||
musicFab.tag = "SELECT##audio"
|
||||
videoFab.tag = "SELECT##video"
|
||||
musicFab.setOnClickListener(this)
|
||||
videoFab.setOnClickListener(this)
|
||||
val downloadAllFab =
|
||||
downloadAllFabCoordinator!!.findViewById<ExtendedFloatingActionButton>(R.id.download_all_fab)
|
||||
downloadAllFab.tag = "downloadAll"
|
||||
downloadAllFab.setOnClickListener(this)
|
||||
|
||||
if (inputQueries != null) {
|
||||
resultViewModel.deleteAll()
|
||||
inputQueriesLength = inputQueries!!.size
|
||||
shimmerCards!!.startShimmer()
|
||||
shimmerCards!!.visibility = VISIBLE
|
||||
val thread = Thread {
|
||||
while (!inputQueries!!.isEmpty()) {
|
||||
inputQuery = inputQueries!!.pop()
|
||||
parseQuery(false)
|
||||
}
|
||||
try {
|
||||
Handler(Looper.getMainLooper()).post {
|
||||
|
||||
// DOWNLOAD ALL BUTTON
|
||||
if (resultsList!!.size > 1 || inputQueriesLength > 1) {
|
||||
downloadAllFabCoordinator!!.visibility = VISIBLE
|
||||
}
|
||||
// databaseManager = DatabaseManager(context)
|
||||
// databaseManager!!.clearResults()
|
||||
// for (v in resultsList!!) v!!.isPlaylistItem = 1
|
||||
// databaseManager!!.addToResults(resultsList)
|
||||
}
|
||||
} catch (ignored: Exception) {
|
||||
}
|
||||
}
|
||||
thread.start()
|
||||
} else {
|
||||
if (resultViewModel.checkTrending()){
|
||||
shimmerCards!!.startShimmer()
|
||||
shimmerCards!!.visibility = VISIBLE
|
||||
resultViewModel.getTrending()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// private fun initCards() {
|
||||
// val uiHandler = Handler(Looper.getMainLooper())
|
||||
// try {
|
||||
// val thread = Thread {
|
||||
// databaseManager = DatabaseManager(context)
|
||||
// resultsList = databaseManager!!.results
|
||||
// var playlistTitle = ""
|
||||
// try {
|
||||
// playlistTitle = resultsList.get(0).playlistTitle
|
||||
// } catch (ignored: Exception) {
|
||||
// }
|
||||
// if (resultsList.size == 0 || playlistTitle == getString(R.string.trendingPlaylist) && !downloading) {
|
||||
// try {
|
||||
// databaseManager!!.clearResults()
|
||||
// uiHandler.post {
|
||||
// shimmerCards!!.startShimmer()
|
||||
// shimmerCards!!.visibility = View.VISIBLE
|
||||
// }
|
||||
// infoUtil = InfoUtil(context!!)
|
||||
// resultsList = infoUtil!!.getTrending(context!!)
|
||||
// databaseManager!!.addToResults(resultsList)
|
||||
// } catch (e: Exception) {
|
||||
// Log.e(TAG, e.toString())
|
||||
// }
|
||||
// } else {
|
||||
// if (!downloading) {
|
||||
// homeAdapter!!.add(resultsList)
|
||||
// for (i in resultsList.indices) {
|
||||
// val tmp = resultsList.get(i)
|
||||
// if (tmp!!.isDownloading) {
|
||||
// updateDownloadingStatusOnResult(tmp, "audio", false)
|
||||
// updateDownloadingStatusOnResult(tmp, "video", false)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// uiHandler.post {
|
||||
// if (homeAdapter!!.itemCount != resultsList.size) {
|
||||
// homeAdapter!!.add(resultsList)
|
||||
// }
|
||||
// shimmerCards!!.stopShimmer()
|
||||
// shimmerCards!!.visibility = View.GONE
|
||||
// }
|
||||
// databaseManager!!.close()
|
||||
// if (resultsList != null) {
|
||||
// uiHandler.post { scrollToTop() }
|
||||
// if (resultsList!!.size > 1 && resultsList!![1]!!.isPlaylistItem == 1) {
|
||||
// uiHandler.post { downloadAllFabCoordinator!!.visibility = View.VISIBLE }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// thread.start()
|
||||
// } catch (e: Exception) {
|
||||
// Log.e(TAG, e.toString())
|
||||
// uiHandler.post {
|
||||
// shimmerCards!!.stopShimmer()
|
||||
// shimmerCards!!.visibility = View.GONE
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
private fun initMenu() {
|
||||
val onActionExpandListener: MenuItem.OnActionExpandListener =
|
||||
object : MenuItem.OnActionExpandListener {
|
||||
override fun onMenuItemActionExpand(menuItem: MenuItem): Boolean {
|
||||
homeFabs!!.visibility = View.GONE
|
||||
recyclerView!!.visibility = View.GONE
|
||||
searchSuggestions!!.visibility = View.VISIBLE
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onMenuItemActionCollapse(menuItem: MenuItem): Boolean {
|
||||
homeFabs!!.visibility = View.VISIBLE
|
||||
recyclerView!!.visibility = View.VISIBLE
|
||||
searchSuggestions!!.visibility = View.GONE
|
||||
return true
|
||||
}
|
||||
}
|
||||
if (downloading) {
|
||||
topAppBar!!.menu.findItem(R.id.cancel_download).isVisible = true
|
||||
}
|
||||
topAppBar!!.menu.findItem(R.id.search).setOnActionExpandListener(onActionExpandListener)
|
||||
val searchView = topAppBar!!.menu.findItem(R.id.search).actionView as SearchView?
|
||||
searchView!!.inputType = InputType.TYPE_TEXT_VARIATION_URI
|
||||
searchView.queryHint = getString(R.string.search_hint)
|
||||
databaseManager = DatabaseManager(context)
|
||||
infoUtil = InfoUtil(requireContext())
|
||||
searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
|
||||
override fun onQueryTextSubmit(query: String): Boolean {
|
||||
topAppBar!!.menu.findItem(R.id.search).collapseActionView()
|
||||
downloadAllFabCoordinator!!.visibility = GONE
|
||||
downloadFabs!!.visibility = View.GONE
|
||||
selectedObjects = ArrayList()
|
||||
inputQuery = query.trim { it <= ' ' }
|
||||
shimmerCards!!.startShimmer()
|
||||
shimmerCards!!.visibility = View.VISIBLE
|
||||
resultViewModel.deleteAll()
|
||||
val thread = Thread {
|
||||
parseQuery(true)
|
||||
// DOWNLOAD ALL BUTTON
|
||||
if (resultsList!!.size > 1 && resultsList!![1]!!.playlistTitle.isNotEmpty()) {
|
||||
Handler(Looper.getMainLooper()).post {
|
||||
downloadAllFabCoordinator!!.visibility = View.VISIBLE
|
||||
}
|
||||
}
|
||||
}
|
||||
thread.start()
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onQueryTextChange(newText: String): Boolean {
|
||||
searchSuggestionsLinearLayout!!.removeAllViews()
|
||||
if (newText.isEmpty()) return false
|
||||
val thread = Thread {
|
||||
val suggestions = infoUtil!!.getSearchSuggestions(newText)
|
||||
for (i in suggestions.indices) {
|
||||
val v = LayoutInflater.from(fragmentContext)
|
||||
.inflate(R.layout.search_suggestion_item, null)
|
||||
val textView = v.findViewById<TextView>(R.id.suggestion_text)
|
||||
textView.text = suggestions[i]
|
||||
Handler(Looper.getMainLooper()).post {
|
||||
searchSuggestionsLinearLayout!!.addView(
|
||||
v
|
||||
)
|
||||
}
|
||||
textView.setOnClickListener { onQueryTextSubmit(textView.text.toString()) }
|
||||
val mb = v.findViewById<MaterialButton>(R.id.set_search_query_button)
|
||||
mb.setOnClickListener {
|
||||
searchView.setQuery(
|
||||
textView.text,
|
||||
false
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
thread.start()
|
||||
return false
|
||||
}
|
||||
})
|
||||
topAppBar!!.setOnClickListener { view: View? -> scrollToTop() }
|
||||
topAppBar!!.setOnMenuItemClickListener { m: MenuItem ->
|
||||
val itemId = m.itemId
|
||||
if (itemId == R.id.delete_results) {
|
||||
resultViewModel.getTrending()
|
||||
selectedObjects = ArrayList()
|
||||
downloadAllFabCoordinator!!.visibility = View.GONE
|
||||
downloadFabs!!.visibility = View.GONE
|
||||
}
|
||||
// } else if (itemId == R.id.cancel_download) {
|
||||
// try {
|
||||
// mainActivity!!.cancelDownloadService()
|
||||
// topAppBar!!.menu.findItem(itemId).isVisible = false
|
||||
// for (i in downloadInfo!!.downloadQueue.indices) {
|
||||
// val vid = downloadInfo!!.downloadQueue[i]
|
||||
// val type = vid.downloadedType
|
||||
// updateDownloadingStatusOnResult(vid, type, false)
|
||||
// }
|
||||
// downloadQueue = ArrayList()
|
||||
// downloading = false
|
||||
// } catch (ignored: Exception) {
|
||||
// }
|
||||
// }
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
fun handleIntent(intent: Intent) {
|
||||
inputQueries = LinkedList()
|
||||
inputQueries!!.add(intent.getStringExtra(Intent.EXTRA_TEXT))
|
||||
}
|
||||
|
||||
fun handleFileIntent(lines: LinkedList<String?>?) {
|
||||
inputQueries = lines
|
||||
}
|
||||
|
||||
fun scrollToTop() {
|
||||
recyclerView!!.scrollToPosition(0)
|
||||
(topAppBar!!.parent as AppBarLayout).setExpanded(true, true)
|
||||
}
|
||||
|
||||
private fun parseQuery(resetResults: Boolean) {
|
||||
databaseManager = DatabaseManager(context)
|
||||
infoUtil = InfoUtil(requireContext())
|
||||
Handler(Looper.getMainLooper()).post { scrollToTop() }
|
||||
var type = "Search"
|
||||
val p = Pattern.compile("^(https?)://(www.)?youtu(.be)?")
|
||||
val m = p.matcher(inputQuery!!)
|
||||
if (m.find()) {
|
||||
type = "Video"
|
||||
if (inputQuery!!.contains("playlist?list=")) {
|
||||
type = "Playlist"
|
||||
}
|
||||
} else if (inputQuery!!.contains("http")) {
|
||||
type = "Default"
|
||||
}
|
||||
Log.e(TAG, "$inputQuery $type")
|
||||
try {
|
||||
when (type) {
|
||||
"Search" -> {
|
||||
try {
|
||||
val res = infoUtil!!.search(
|
||||
inputQuery!!
|
||||
)
|
||||
Handler(Looper.getMainLooper()).post {
|
||||
if (resetResults) resultViewModel.deleteAll()
|
||||
resultViewModel.insert(res)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, e.toString())
|
||||
Handler(Looper.getMainLooper()).post {
|
||||
shimmerCards!!.stopShimmer()
|
||||
shimmerCards!!.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
}
|
||||
"Video" -> {
|
||||
var el: Array<String?> =
|
||||
inputQuery!!.split("/".toRegex()).dropLastWhile { it.isEmpty() }
|
||||
.toTypedArray()
|
||||
inputQuery = el[el.size - 1]
|
||||
if (inputQuery!!.contains("watch?v=")) {
|
||||
inputQuery = inputQuery!!.substring(8)
|
||||
}
|
||||
el = inputQuery!!.split("&".toRegex()).dropLastWhile { it.isEmpty() }
|
||||
.toTypedArray()
|
||||
inputQuery = el[0]
|
||||
el = inputQuery!!.split("\\?".toRegex()).dropLastWhile { it.isEmpty() }
|
||||
.toTypedArray()
|
||||
inputQuery = el[0]
|
||||
try {
|
||||
val v = infoUtil!!.getVideo(inputQuery!!)
|
||||
val res = ArrayList<ResultItem?>()
|
||||
res.add(v)
|
||||
Handler(Looper.getMainLooper()).post {
|
||||
if (resetResults) resultViewModel.deleteAll()
|
||||
resultViewModel.insert(res)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, e.toString())
|
||||
Handler(Looper.getMainLooper()).post {
|
||||
shimmerCards!!.stopShimmer()
|
||||
shimmerCards!!.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
}
|
||||
"Playlist" -> {
|
||||
inputQuery =
|
||||
inputQuery!!.split("list=".toRegex()).dropLastWhile { it.isEmpty() }
|
||||
.toTypedArray()[1]
|
||||
var nextPageToken = ""
|
||||
if (resetResults) resultViewModel.deleteAll()
|
||||
do {
|
||||
val tmp = infoUtil!!.getPlaylist(inputQuery!!, nextPageToken)
|
||||
val tmp_vids = tmp.videos
|
||||
val tmp_token = tmp.nextPageToken
|
||||
Handler(Looper.getMainLooper()).post {
|
||||
resultViewModel.insert(tmp_vids)
|
||||
}
|
||||
if (tmp_token.isEmpty()) break
|
||||
if (tmp_token == nextPageToken) break
|
||||
nextPageToken = tmp_token
|
||||
} while (true)
|
||||
}
|
||||
"Default" -> {
|
||||
try {
|
||||
val video = infoUtil!!.getFromYTDL(
|
||||
inputQuery!!
|
||||
)
|
||||
Handler(Looper.getMainLooper()).post {
|
||||
if (resetResults) resultViewModel.deleteAll()
|
||||
resultViewModel.insert(video)
|
||||
}
|
||||
Handler(Looper.getMainLooper()).post {
|
||||
shimmerCards!!.stopShimmer()
|
||||
shimmerCards!!.visibility = View.GONE
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, e.toString())
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, e.toString())
|
||||
}
|
||||
databaseManager!!.close()
|
||||
}
|
||||
|
||||
fun findVideo(url: String): ResultItem? {
|
||||
for (i in resultsList!!.indices) {
|
||||
val v = resultsList!![i]
|
||||
if (v!!.url == url) {
|
||||
return v
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
@SuppressLint("ResourceType")
|
||||
override fun onButtonClick(position: Int, type: String) {
|
||||
// Log.e(TAG, type)
|
||||
// val vid = resultsList!![position]
|
||||
// vid!!.downloadedType = type
|
||||
// val btn = recyclerView!!.findViewWithTag<MaterialButton>(vid.videoId + "##" + type)
|
||||
// if (downloading) {
|
||||
// try {
|
||||
// if (btn.getTag(R.id.cancelDownload) == "true") {
|
||||
// mainActivity!!.removeItemFromDownloadQueue(vid, type)
|
||||
// return
|
||||
// }
|
||||
// } catch (ignored: Exception) {
|
||||
// }
|
||||
// }
|
||||
// val sharedPreferences =
|
||||
// context!!.getSharedPreferences("root_preferences", Activity.MODE_PRIVATE)
|
||||
// if (sharedPreferences.getBoolean("download_card", true)) {
|
||||
// selectedObjects!!.clear()
|
||||
// selectedObjects!!.add(resultsList!![position])
|
||||
// showConfigureDownloadCard(type)
|
||||
// } else {
|
||||
// downloadQueue!!.add(vid)
|
||||
// updateDownloadingStatusOnResult(vid, type, true)
|
||||
// if (isStoragePermissionGranted) {
|
||||
// mainActivity!!.startDownloadService(downloadQueue, listener)
|
||||
// downloadQueue!!.clear()
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
private val isStoragePermissionGranted: Boolean
|
||||
get() = if (ActivityCompat.checkSelfPermission(
|
||||
requireContext(),
|
||||
Manifest.permission.WRITE_EXTERNAL_STORAGE
|
||||
)
|
||||
== PackageManager.PERMISSION_GRANTED
|
||||
) {
|
||||
true
|
||||
} else {
|
||||
downloadQueue = ArrayList()
|
||||
ActivityCompat.requestPermissions(
|
||||
requireActivity(),
|
||||
arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE),
|
||||
1
|
||||
)
|
||||
false
|
||||
}
|
||||
|
||||
fun updateDownloadStatusOnResult(v: ResultItem?, type: String?, downloaded: Boolean) {
|
||||
// if (v != null) {
|
||||
// databaseManager = DatabaseManager(context)
|
||||
// try {
|
||||
// databaseManager!!.updateDownloadStatusOnResult(v.videoId, type, downloaded)
|
||||
// databaseManager!!.close()
|
||||
// } catch (ignored: Exception) {
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
fun updateDownloadingStatusOnResult(v: ResultItem?, type: String, isDownloading: Boolean) {
|
||||
// if (v != null) {
|
||||
// if (type == "audio") v.isDownloadingAudio =
|
||||
// isDownloading else if (type == "video") v.isDownloadingVideo = isDownloading
|
||||
// homeAdapter!!.updateVideoListItem(v, resultsList!!.indexOf(v))
|
||||
// databaseManager = DatabaseManager(context)
|
||||
// try {
|
||||
// databaseManager!!.updateDownloadingStatusOnResult(v.videoId, type, isDownloading)
|
||||
// databaseManager!!.close()
|
||||
// } catch (ignored: Exception) {
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
override fun onCardClick(position: Int, add: Boolean) {
|
||||
val item = resultsList!![position]
|
||||
if (add) selectedObjects!!.add(item!!) else selectedObjects!!.remove(item)
|
||||
if (selectedObjects!!.size > 1) {
|
||||
downloadAllFabCoordinator!!.visibility = View.GONE
|
||||
downloadFabs!!.visibility = View.VISIBLE
|
||||
} else {
|
||||
downloadFabs!!.visibility = View.GONE
|
||||
if (resultsList!!.size > 1 && resultsList!![1]!!.playlistTitle.isNotEmpty()) {
|
||||
downloadAllFabCoordinator!!.visibility = View.VISIBLE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onClick(v: View) {
|
||||
val viewIdName: String
|
||||
viewIdName = try {
|
||||
v.tag.toString()
|
||||
} catch (e: Exception) {
|
||||
""
|
||||
}
|
||||
if (!viewIdName.isEmpty()) {
|
||||
if (viewIdName.contains("audio") || viewIdName.contains("video")) {
|
||||
val buttonData =
|
||||
viewIdName.split("##".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
|
||||
if (buttonData[0] == "SELECT") {
|
||||
initSelectedDownload(buttonData[1])
|
||||
}
|
||||
}
|
||||
if (viewIdName == "downloadAll") {
|
||||
//remove previously selected
|
||||
for (i in selectedObjects!!.indices) {
|
||||
val vid = findVideo(
|
||||
selectedObjects!![i]!!.url
|
||||
)
|
||||
homeAdapter!!.notifyItemChanged(resultsList!!.indexOf(vid))
|
||||
}
|
||||
selectedObjects = ArrayList()
|
||||
downloadFabs!!.visibility = View.GONE
|
||||
bottomSheet = BottomSheetDialog(fragmentContext!!)
|
||||
bottomSheet!!.requestWindowFeature(Window.FEATURE_NO_TITLE)
|
||||
bottomSheet!!.setContentView(R.layout.home_download_all_bottom_sheet)
|
||||
val first = bottomSheet!!.findViewById<TextInputLayout>(R.id.first_textinput)
|
||||
first!!.editText!!.setText(1.toString())
|
||||
val last = bottomSheet!!.findViewById<TextInputLayout>(R.id.last_textinput)
|
||||
last!!.editText!!.setText(resultsList!!.size.toString())
|
||||
val audio = bottomSheet!!.findViewById<Button>(R.id.bottomsheet_audio_button)
|
||||
audio!!.setOnClickListener { view: View? ->
|
||||
val start = first.editText!!.text.toString().toInt()
|
||||
val end = last.editText!!.text.toString().toInt()
|
||||
initDownloadAll(bottomSheet!!, start, end, "audio")
|
||||
}
|
||||
val video = bottomSheet!!.findViewById<Button>(R.id.bottomsheet_video_button)
|
||||
video!!.setOnClickListener { view: View? ->
|
||||
val start = first.editText!!.text.toString().toInt()
|
||||
val end = last.editText!!.text.toString().toInt()
|
||||
initDownloadAll(bottomSheet!!, start, end, "video")
|
||||
}
|
||||
bottomSheet!!.show()
|
||||
bottomSheet!!.window!!.setLayout(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.MATCH_PARENT
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun initDownloadAll(
|
||||
bottomSheet: BottomSheetDialog,
|
||||
start: Int,
|
||||
end: Int,
|
||||
type: String
|
||||
) {
|
||||
// var start = start
|
||||
// var end = end
|
||||
// if (start > end) {
|
||||
// val first = bottomSheet.findViewById<TextInputLayout>(R.id.first_textinput)
|
||||
// first!!.error = getString(R.string.first_cant_be_larger_than_last)
|
||||
// val last = bottomSheet.findViewById<TextInputLayout>(R.id.last_textinput)
|
||||
// last!!.error = getString(R.string.last_cant_be_smaller_than_first)
|
||||
// return
|
||||
// }
|
||||
// bottomSheet.cancel()
|
||||
// start--
|
||||
// end--
|
||||
// if (start <= 1) start = 0
|
||||
// val sharedPreferences =
|
||||
// requireContext().getSharedPreferences("root_preferences", Activity.MODE_PRIVATE)
|
||||
// if (sharedPreferences.getBoolean("download_card", true)) {
|
||||
// selectedObjects!!.clear()
|
||||
// selectedObjects!!.addAll(resultsList!!.subList(start, end + 1) as ArrayList<ResultItem>)
|
||||
// showConfigureDownloadCard(type)
|
||||
// } else {
|
||||
// for (i in start..end) {
|
||||
// val vid = findVideo(
|
||||
// resultsList!![i]!!.getURL()
|
||||
// )
|
||||
// vid!!.downloadedType = type
|
||||
// updateDownloadingStatusOnResult(vid, type, true)
|
||||
// downloadQueue!!.add(vid)
|
||||
// }
|
||||
// if (isStoragePermissionGranted) {
|
||||
// mainActivity!!.startDownloadService(downloadQueue, listener)
|
||||
// downloadQueue!!.clear()
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
private fun initSelectedDownload(type: String) {
|
||||
// val sharedPreferences =
|
||||
// context!!.getSharedPreferences("root_preferences", Activity.MODE_PRIVATE)
|
||||
// val editor = sharedPreferences.edit()
|
||||
// if (sharedPreferences.getBoolean("download_card", true)) {
|
||||
// showConfigureDownloadCard(type)
|
||||
// } else {
|
||||
// for (i in selectedObjects!!.indices) {
|
||||
// val vid = findVideo(
|
||||
// selectedObjects!![i]!!.getURL()
|
||||
// )
|
||||
// vid!!.downloadedType = type
|
||||
// updateDownloadingStatusOnResult(vid, type, true)
|
||||
// homeAdapter!!.notifyItemChanged(resultsList!!.indexOf(vid))
|
||||
// downloadQueue!!.add(vid)
|
||||
// }
|
||||
// selectedObjects = ArrayList()
|
||||
// homeAdapter!!.clearCheckedVideos()
|
||||
// downloadFabs!!.visibility = View.GONE
|
||||
// if (isStoragePermissionGranted) {
|
||||
// mainActivity!!.startDownloadService(downloadQueue, listener)
|
||||
// downloadQueue!!.clear()
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
private fun showConfigureDownloadCard(type: String) {
|
||||
// val sharedPreferences =
|
||||
// context!!.getSharedPreferences("root_preferences", Activity.MODE_PRIVATE)
|
||||
// val editor = sharedPreferences.edit()
|
||||
// try {
|
||||
// bottomSheet = BottomSheetDialog(fragmentContext!!)
|
||||
// bottomSheet!!.requestWindowFeature(Window.FEATURE_NO_TITLE)
|
||||
// if (type == "audio") {
|
||||
// bottomSheet!!.setContentView(R.layout.home_download_audio_bottom_sheet)
|
||||
// val title = bottomSheet!!.findViewById<TextInputLayout>(R.id.title_textinput)
|
||||
// if (selectedObjects!!.size > 1) {
|
||||
// title!!.editText!!.setText(getString(R.string.mutliple_titles))
|
||||
// title.editText!!.isClickable = false
|
||||
// title.editText!!.isLongClickable = false
|
||||
// } else {
|
||||
// title!!.editText!!.setText(selectedObjects!![0]!!.title)
|
||||
// title.editText!!.addTextChangedListener(object : TextWatcher {
|
||||
// override fun beforeTextChanged(
|
||||
// charSequence: CharSequence,
|
||||
// i: Int,
|
||||
// i1: Int,
|
||||
// i2: Int
|
||||
// ) {
|
||||
// }
|
||||
//
|
||||
// override fun onTextChanged(
|
||||
// charSequence: CharSequence,
|
||||
// i: Int,
|
||||
// i1: Int,
|
||||
// i2: Int
|
||||
// ) {
|
||||
// }
|
||||
//
|
||||
// override fun afterTextChanged(editable: Editable) {
|
||||
// val index = resultsList!!.indexOf(selectedObjects!![0])
|
||||
// resultsList!![index]!!.title = editable.toString()
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
// val author = bottomSheet!!.findViewById<TextInputLayout>(R.id.author_textinput)
|
||||
// if (selectedObjects!!.size > 1) {
|
||||
// author!!.editText!!.setText(getString(R.string.mutliple_authors))
|
||||
// author.editText!!.isClickable = false
|
||||
// author.editText!!.isLongClickable = false
|
||||
// } else {
|
||||
// author!!.editText!!.setText(selectedObjects!![0]!!.author)
|
||||
// author.editText!!.addTextChangedListener(object : TextWatcher {
|
||||
// override fun beforeTextChanged(
|
||||
// charSequence: CharSequence,
|
||||
// i: Int,
|
||||
// i1: Int,
|
||||
// i2: Int
|
||||
// ) {
|
||||
// }
|
||||
//
|
||||
// override fun onTextChanged(
|
||||
// charSequence: CharSequence,
|
||||
// i: Int,
|
||||
// i1: Int,
|
||||
// i2: Int
|
||||
// ) {
|
||||
// }
|
||||
//
|
||||
// override fun afterTextChanged(editable: Editable) {
|
||||
// val index = resultsList!!.indexOf(selectedObjects!![0])
|
||||
// resultsList!![index]!!.author = editable.toString()
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
// val audioFormats = context!!.resources.getStringArray(R.array.music_formats)
|
||||
// val audioFormat = bottomSheet!!.findViewById<TextInputLayout>(R.id.audio_format)
|
||||
// val autoCompleteTextView =
|
||||
// bottomSheet!!.findViewById<AutoCompleteTextView>(R.id.audio_format_textview)
|
||||
// val preference = sharedPreferences.getString("audio_format", "mp3")
|
||||
// autoCompleteTextView!!.setText(preference, false)
|
||||
// (audioFormat!!.editText as AutoCompleteTextView?)!!.onItemClickListener =
|
||||
// AdapterView.OnItemClickListener { adapterView: AdapterView<*>?, view: View?, index: Int, l: Long ->
|
||||
// for (i in selectedObjects!!.indices) {
|
||||
// val vid = findVideo(
|
||||
// selectedObjects!![i]!!.getURL()
|
||||
// )
|
||||
// vid!!.audioFormat = audioFormats[index]
|
||||
// }
|
||||
// editor.putString("audio_format", audioFormats[index])
|
||||
// editor.apply()
|
||||
// }
|
||||
// } else {
|
||||
// bottomSheet!!.setContentView(R.layout.home_download_video_bottom_sheet)
|
||||
// val title = bottomSheet!!.findViewById<TextInputLayout>(R.id.title_textinput)
|
||||
// if (selectedObjects!!.size > 1) {
|
||||
// title!!.editText!!.setText(getString(R.string.mutliple_titles))
|
||||
// title.editText!!.isClickable = false
|
||||
// title.editText!!.isLongClickable = false
|
||||
// } else {
|
||||
// title!!.editText!!.setText(selectedObjects!![0]!!.title)
|
||||
// title.editText!!.addTextChangedListener(object : TextWatcher {
|
||||
// override fun beforeTextChanged(
|
||||
// charSequence: CharSequence,
|
||||
// i: Int,
|
||||
// i1: Int,
|
||||
// i2: Int
|
||||
// ) {
|
||||
// }
|
||||
//
|
||||
// override fun onTextChanged(
|
||||
// charSequence: CharSequence,
|
||||
// i: Int,
|
||||
// i1: Int,
|
||||
// i2: Int
|
||||
// ) {
|
||||
// }
|
||||
//
|
||||
// override fun afterTextChanged(editable: Editable) {
|
||||
// val index = resultsList!!.indexOf(selectedObjects!![0])
|
||||
// resultsList!![index]!!.title = editable.toString()
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
// val videoFormats = context!!.resources.getStringArray(R.array.video_formats)
|
||||
// val videoQualities = context!!.resources.getStringArray(R.array.video_quality)
|
||||
// val videoFormat = bottomSheet!!.findViewById<TextInputLayout>(R.id.video_format)
|
||||
// var autoCompleteTextView =
|
||||
// bottomSheet!!.findViewById<AutoCompleteTextView>(R.id.video_format_textview)
|
||||
// var preference = sharedPreferences.getString("video_format", "webm")
|
||||
// autoCompleteTextView!!.setText(preference, false)
|
||||
// (videoFormat!!.editText as AutoCompleteTextView?)!!.onItemClickListener =
|
||||
// AdapterView.OnItemClickListener { adapterView: AdapterView<*>?, view: View?, index: Int, l: Long ->
|
||||
// for (i in selectedObjects!!.indices) {
|
||||
// val vid = findVideo(
|
||||
// selectedObjects!![i]!!.getURL()
|
||||
// )
|
||||
// vid!!.videoFormat = videoFormats[index]
|
||||
// }
|
||||
// editor.putString("video_format", videoFormats[index])
|
||||
// editor.apply()
|
||||
// }
|
||||
// val videoQuality = bottomSheet!!.findViewById<TextInputLayout>(R.id.video_quality)
|
||||
// autoCompleteTextView = bottomSheet!!.findViewById(R.id.video_quality_textview)
|
||||
// preference = sharedPreferences.getString("video_quality", "Best Quality")
|
||||
// autoCompleteTextView!!.setText(preference, false)
|
||||
// (videoQuality!!.editText as AutoCompleteTextView?)!!.onItemClickListener =
|
||||
// AdapterView.OnItemClickListener { adapterView: AdapterView<*>?, view: View?, index: Int, l: Long ->
|
||||
// for (i in selectedObjects!!.indices) {
|
||||
// val vid = findVideo(
|
||||
// selectedObjects!![i]!!.getURL()
|
||||
// )
|
||||
// vid!!.videoQuality = videoQualities[index]
|
||||
// }
|
||||
// editor.putString("video_quality", videoQualities[index])
|
||||
// editor.apply()
|
||||
// }
|
||||
// val embedSubs = bottomSheet!!.findViewById<Chip>(R.id.embed_subtitles)
|
||||
// embedSubs!!.isChecked = sharedPreferences.getBoolean("embed_subtitles", false)
|
||||
// embedSubs.setOnClickListener { view: View? ->
|
||||
// if (embedSubs.isChecked) {
|
||||
// editor.putBoolean("embed_subtitles", true)
|
||||
// } else {
|
||||
// editor.putBoolean("embed_subtitles", false)
|
||||
// }
|
||||
// editor.apply()
|
||||
// }
|
||||
// val addChapters = bottomSheet!!.findViewById<Chip>(R.id.add_chapters)
|
||||
// addChapters!!.isChecked = sharedPreferences.getBoolean("add_chapters", false)
|
||||
// addChapters.setOnClickListener { view: View? ->
|
||||
// if (addChapters.isChecked) {
|
||||
// editor.putBoolean("add_chapters", true)
|
||||
// } else {
|
||||
// editor.putBoolean("add_chapters", false)
|
||||
// }
|
||||
// editor.apply()
|
||||
// }
|
||||
// val saveThumbnail = bottomSheet!!.findViewById<Chip>(R.id.save_thumbnail)
|
||||
// saveThumbnail!!.isChecked = sharedPreferences.getBoolean("write_thumbnail", false)
|
||||
// saveThumbnail.setOnClickListener { view: View? ->
|
||||
// if (saveThumbnail.isChecked) {
|
||||
// editor.putBoolean("write_thumbnail", true)
|
||||
// } else {
|
||||
// editor.putBoolean("write_thumbnail", false)
|
||||
// }
|
||||
// editor.apply()
|
||||
// }
|
||||
// }
|
||||
// val cancel = bottomSheet!!.findViewById<Button>(R.id.bottomsheet_cancel_button)
|
||||
// cancel!!.setOnClickListener { view: View? -> bottomSheet!!.cancel() }
|
||||
// val download = bottomSheet!!.findViewById<Button>(R.id.bottomsheet_download_button)
|
||||
// download!!.setOnClickListener { view: View? ->
|
||||
// for (i in selectedObjects!!.indices) {
|
||||
// val vid = findVideo(
|
||||
// selectedObjects!![i]!!.getURL()
|
||||
// )
|
||||
// vid!!.downloadedType = type
|
||||
// updateDownloadingStatusOnResult(vid, type, true)
|
||||
// homeAdapter!!.notifyItemChanged(resultsList!!.indexOf(vid))
|
||||
// downloadQueue!!.add(vid)
|
||||
// }
|
||||
// selectedObjects = ArrayList()
|
||||
// homeAdapter!!.clearCheckedVideos()
|
||||
// downloadFabs!!.visibility = View.GONE
|
||||
// if (isStoragePermissionGranted) {
|
||||
// mainActivity!!.startDownloadService(downloadQueue, listener)
|
||||
// downloadQueue!!.clear()
|
||||
// }
|
||||
// bottomSheet!!.cancel()
|
||||
// }
|
||||
// bottomSheet!!.show()
|
||||
// bottomSheet!!.window!!.setLayout(
|
||||
// ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
// ViewGroup.LayoutParams.MATCH_PARENT
|
||||
// )
|
||||
// } catch (e: Exception) {
|
||||
// Toast.makeText(fragmentContext, e.message, Toast.LENGTH_LONG).show()
|
||||
// }
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val TAG = "HomeFragment"
|
||||
}
|
||||
}
|
||||
|
|
@ -3,17 +3,13 @@ package com.deniscerri.ytdlnis.util
|
|||
import android.content.Context
|
||||
import android.media.MediaScannerConnection
|
||||
import android.net.Uri
|
||||
import android.os.FileUtils
|
||||
import android.provider.DocumentsContract
|
||||
import android.util.Log
|
||||
import android.webkit.MimeTypeMap
|
||||
import android.widget.Toast
|
||||
import com.deniscerri.ytdlnis.DownloaderService
|
||||
import com.deniscerri.ytdlnis.R
|
||||
import com.deniscerri.ytdlnis.database.Video
|
||||
import com.deniscerri.ytdlnis.database.models.DownloadItem
|
||||
import com.deniscerri.ytdlnis.database.models.ResultItem
|
||||
import java.io.File
|
||||
import java.io.InputStream
|
||||
import java.io.OutputStream
|
||||
import java.net.URLDecoder
|
||||
import java.nio.charset.StandardCharsets
|
||||
|
||||
|
|
@ -55,7 +51,7 @@ class FileUtil() {
|
|||
return formattedPath.toString()
|
||||
}
|
||||
|
||||
fun scanMedia(video: Video, context: Context) : String {
|
||||
fun scanMedia(video: DownloadItem, context: Context) : String {
|
||||
val files = ArrayList<File>()
|
||||
val title: String = video.title.replace("[^a-zA-Z0-9]".toRegex(), "")
|
||||
var pathTmp: String
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import android.content.Context
|
|||
import android.util.Log
|
||||
import com.deniscerri.ytdlnis.R
|
||||
import com.deniscerri.ytdlnis.database.DatabaseManager
|
||||
import com.deniscerri.ytdlnis.database.Video
|
||||
import com.deniscerri.ytdlnis.database.models.ResultItem
|
||||
import com.yausername.youtubedl_android.YoutubeDL
|
||||
import com.yausername.youtubedl_android.YoutubeDLRequest
|
||||
import org.json.JSONArray
|
||||
|
|
@ -16,9 +16,10 @@ import java.io.InputStreamReader
|
|||
import java.net.HttpURLConnection
|
||||
import java.net.URL
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
class InfoUtil(context: Context) {
|
||||
private var videos: ArrayList<Video?>
|
||||
private var items: ArrayList<ResultItem?>
|
||||
private var key: String? = null
|
||||
private var useInvidous = false
|
||||
private var databaseManager: DatabaseManager? = null
|
||||
|
|
@ -32,7 +33,7 @@ class InfoUtil(context: Context) {
|
|||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
videos = ArrayList()
|
||||
items = ArrayList()
|
||||
}
|
||||
|
||||
private fun init(){
|
||||
|
|
@ -51,16 +52,16 @@ class InfoUtil(context: Context) {
|
|||
}
|
||||
|
||||
@Throws(JSONException::class)
|
||||
fun search(query: String): ArrayList<Video?> {
|
||||
fun search(query: String): ArrayList<ResultItem?> {
|
||||
init()
|
||||
videos = ArrayList()
|
||||
items = ArrayList()
|
||||
return if (key!!.isEmpty()) {
|
||||
if (useInvidous) searchFromInvidous(query) else getFromYTDL(query)
|
||||
} else searchFromKey(query)
|
||||
}
|
||||
|
||||
@Throws(JSONException::class)
|
||||
fun searchFromKey(query: String): ArrayList<Video?> {
|
||||
fun searchFromKey(query: String): ArrayList<ResultItem?> {
|
||||
//short data
|
||||
val res =
|
||||
genericRequest("https://youtube.googleapis.com/youtube/v3/search?part=snippet&q=$query&maxResults=25®ionCode=$countryCODE&key=$key")
|
||||
|
|
@ -102,14 +103,14 @@ class InfoUtil(context: Context) {
|
|||
if (v == null || v.thumb.isEmpty()) {
|
||||
continue
|
||||
}
|
||||
videos.add(createVideofromJSON(snippet))
|
||||
items.add(createVideofromJSON(snippet))
|
||||
}
|
||||
}
|
||||
return videos
|
||||
return items
|
||||
}
|
||||
|
||||
@Throws(JSONException::class)
|
||||
fun searchFromInvidous(query: String): ArrayList<Video?> {
|
||||
fun searchFromInvidous(query: String): ArrayList<ResultItem?> {
|
||||
val dataArray = genericArrayRequest(invidousURL + "search?q=" + query + "?type=video")
|
||||
if (dataArray.length() == 0) return getFromYTDL(query)
|
||||
for (i in 0 until dataArray.length()) {
|
||||
|
|
@ -128,15 +129,15 @@ class InfoUtil(context: Context) {
|
|||
if (v == null || v.thumb.isEmpty()) {
|
||||
continue
|
||||
}
|
||||
videos.add(v)
|
||||
items.add(v)
|
||||
}
|
||||
return videos
|
||||
return items
|
||||
}
|
||||
|
||||
@Throws(JSONException::class)
|
||||
fun getPlaylist(id: String, nextPageToken: String): PlaylistTuple {
|
||||
init()
|
||||
videos = ArrayList()
|
||||
items = ArrayList()
|
||||
if (key!!.isEmpty()) {
|
||||
return if (useInvidous) getPlaylistFromInvidous(id) else PlaylistTuple(
|
||||
"",
|
||||
|
|
@ -186,12 +187,12 @@ class InfoUtil(context: Context) {
|
|||
} else {
|
||||
j++
|
||||
}
|
||||
v.isPlaylistItem = 1
|
||||
videos.add(v)
|
||||
v.playlistTitle = "YTDLnis"
|
||||
items.add(v)
|
||||
i++
|
||||
}
|
||||
val next = res.optString("nextPageToken")
|
||||
return PlaylistTuple(next, videos)
|
||||
return PlaylistTuple(next, items)
|
||||
}
|
||||
|
||||
private fun getPlaylistFromInvidous(id: String): PlaylistTuple {
|
||||
|
|
@ -208,17 +209,16 @@ class InfoUtil(context: Context) {
|
|||
val v = createVideofromInvidiousJSON(element)
|
||||
if (v == null || v.thumb.isEmpty()) continue
|
||||
v.playlistTitle = res.getString("title")
|
||||
v.isPlaylistItem = 1
|
||||
videos.add(v)
|
||||
items.add(v)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
return PlaylistTuple("", videos)
|
||||
return PlaylistTuple("", items)
|
||||
}
|
||||
|
||||
@Throws(JSONException::class)
|
||||
fun getVideo(id: String): Video? {
|
||||
fun getVideo(id: String): ResultItem? {
|
||||
init()
|
||||
if (key!!.isEmpty()) {
|
||||
return if (useInvidous) {
|
||||
|
|
@ -245,8 +245,8 @@ class InfoUtil(context: Context) {
|
|||
return createVideofromJSON(res)
|
||||
}
|
||||
|
||||
private fun createVideofromJSON(obj: JSONObject): Video? {
|
||||
var video: Video? = null
|
||||
private fun createVideofromJSON(obj: JSONObject): ResultItem? {
|
||||
var video: ResultItem? = null
|
||||
try {
|
||||
val id = obj.getString("videoID")
|
||||
val title = obj.getString("title").toString()
|
||||
|
|
@ -257,20 +257,14 @@ class InfoUtil(context: Context) {
|
|||
val downloadedAudio = databaseManager!!.checkDownloaded(url, "audio")
|
||||
val downloadedVideo = databaseManager!!.checkDownloaded(url, "video")
|
||||
val isPlaylist = 0
|
||||
video = Video(
|
||||
video = ResultItem(
|
||||
id,
|
||||
url,
|
||||
title,
|
||||
author,
|
||||
duration,
|
||||
thumb,
|
||||
downloadedAudio,
|
||||
downloadedVideo,
|
||||
isPlaylist,
|
||||
"youtube",
|
||||
0,
|
||||
0,
|
||||
""
|
||||
"youtube"
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, e.toString())
|
||||
|
|
@ -278,8 +272,8 @@ class InfoUtil(context: Context) {
|
|||
return video
|
||||
}
|
||||
|
||||
private fun createVideofromInvidiousJSON(obj: JSONObject): Video? {
|
||||
var video: Video? = null
|
||||
private fun createVideofromInvidiousJSON(obj: JSONObject): ResultItem? {
|
||||
var video: ResultItem? = null
|
||||
try {
|
||||
val id = obj.getString("videoId")
|
||||
val title = obj.getString("title").toString()
|
||||
|
|
@ -290,20 +284,14 @@ class InfoUtil(context: Context) {
|
|||
val downloadedAudio = databaseManager!!.checkDownloaded(url, "audio")
|
||||
val downloadedVideo = databaseManager!!.checkDownloaded(url, "video")
|
||||
val isPlaylist = 0
|
||||
video = Video(
|
||||
video = ResultItem(
|
||||
id,
|
||||
url,
|
||||
title,
|
||||
author,
|
||||
duration,
|
||||
thumb,
|
||||
downloadedAudio,
|
||||
downloadedVideo,
|
||||
isPlaylist,
|
||||
"youtube",
|
||||
0,
|
||||
0,
|
||||
""
|
||||
"youtube"
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, e.toString())
|
||||
|
|
@ -395,16 +383,16 @@ class InfoUtil(context: Context) {
|
|||
}
|
||||
|
||||
@Throws(JSONException::class)
|
||||
fun getTrending(context: Context): ArrayList<Video?> {
|
||||
fun getTrending(context: Context): ArrayList<ResultItem?> {
|
||||
init()
|
||||
videos = ArrayList()
|
||||
items = ArrayList()
|
||||
return if (key!!.isEmpty()) {
|
||||
if (useInvidous) getTrendingFromInvidous(context) else ArrayList()
|
||||
} else getTrendingFromKey(context)
|
||||
}
|
||||
|
||||
@Throws(JSONException::class)
|
||||
fun getTrendingFromKey(context: Context): ArrayList<Video?> {
|
||||
fun getTrendingFromKey(context: Context): ArrayList<ResultItem?> {
|
||||
val url = "https://www.googleapis.com/youtube/v3/videos?part=snippet&chart=mostPopular&videoCategoryId=10®ionCode=$countryCODE&maxResults=25&key=$key"
|
||||
//short data
|
||||
val res = genericRequest(url)
|
||||
|
|
@ -428,12 +416,12 @@ class InfoUtil(context: Context) {
|
|||
continue
|
||||
}
|
||||
v.playlistTitle = context.getString(R.string.trendingPlaylist)
|
||||
videos.add(v)
|
||||
items.add(v)
|
||||
}
|
||||
return videos
|
||||
return items
|
||||
}
|
||||
|
||||
private fun getTrendingFromInvidous(context: Context): ArrayList<Video?> {
|
||||
private fun getTrendingFromInvidous(context: Context): ArrayList<ResultItem?> {
|
||||
val url = invidousURL + "trending?type=music®ion=" + countryCODE
|
||||
val res = genericArrayRequest(url)
|
||||
try {
|
||||
|
|
@ -443,17 +431,17 @@ class InfoUtil(context: Context) {
|
|||
val v = createVideofromInvidiousJSON(element)
|
||||
if (v == null || v.thumb.isEmpty()) continue
|
||||
v.playlistTitle = context.getString(R.string.trendingPlaylist)
|
||||
videos.add(v)
|
||||
items.add(v)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
return videos
|
||||
return items
|
||||
}
|
||||
|
||||
fun getFromYTDL(query: String): ArrayList<Video?> {
|
||||
fun getFromYTDL(query: String): ArrayList<ResultItem?> {
|
||||
init()
|
||||
videos = ArrayList()
|
||||
items = ArrayList()
|
||||
try {
|
||||
val request = YoutubeDLRequest(query)
|
||||
request.addOption("--flat-playlist")
|
||||
|
|
@ -501,28 +489,22 @@ class InfoUtil(context: Context) {
|
|||
val website = if (jsonObject.has("ie_key")) jsonObject.getString("ie_key") else jsonObject.getString("extractor")
|
||||
var playlistTitle: String? = ""
|
||||
if (jsonObject.has("playlist")) playlistTitle = jsonObject.getString("playlist")
|
||||
videos.add(
|
||||
Video(
|
||||
jsonObject.getString("id"),
|
||||
items.add(
|
||||
ResultItem(
|
||||
url,
|
||||
title,
|
||||
author,
|
||||
author!!,
|
||||
duration,
|
||||
thumb,
|
||||
databaseManager!!.checkDownloaded(url, "audio"),
|
||||
databaseManager!!.checkDownloaded(url, "video"),
|
||||
isPlaylist,
|
||||
thumb!!,
|
||||
website,
|
||||
0,
|
||||
0,
|
||||
playlistTitle
|
||||
playlistTitle!!
|
||||
)
|
||||
)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
return videos
|
||||
return items
|
||||
}
|
||||
|
||||
fun getSearchSuggestions(query: String): ArrayList<String> {
|
||||
|
|
@ -598,7 +580,7 @@ class InfoUtil(context: Context) {
|
|||
|
||||
class PlaylistTuple internal constructor(
|
||||
var nextPageToken: String,
|
||||
var videos: ArrayList<Video?>
|
||||
var videos: ArrayList<ResultItem?>
|
||||
)
|
||||
|
||||
companion object {
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ class DownloadWorker(
|
|||
setForeground(foregroundInfo)
|
||||
|
||||
while (queue.isNotEmpty()){
|
||||
val item = dao.getDownloadById(queue[0].id)
|
||||
val item = dao.getDownloadById(queue[0].id!!)
|
||||
queue.removeFirst()
|
||||
val url = item.url
|
||||
val request = YoutubeDLRequest(url)
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@
|
|||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:layout_width="match_parent"
|
||||
android:id="@+id/recycler_view_home"
|
||||
android:id="@+id/recyclerViewHome"
|
||||
android:nestedScrollingEnabled="false"
|
||||
android:orientation="vertical"
|
||||
android:layout_height="match_parent"
|
||||
|
|
|
|||
|
|
@ -36,8 +36,8 @@ buildscript {
|
|||
}
|
||||
|
||||
plugins {
|
||||
id 'com.android.application' version '7.3.1' apply false
|
||||
id 'com.android.library' version '7.3.1' apply false
|
||||
id 'com.android.application' version '7.4.0' apply false
|
||||
id 'com.android.library' version '7.4.0' apply false
|
||||
id 'org.jetbrains.kotlin.android' version '1.7.20' apply false
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue