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 {
|
composeOptions {
|
||||||
kotlinCompilerExtensionVersion composeVer
|
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"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
package="com.deniscerri.ytdlnis" >
|
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ import androidx.work.ExistingWorkPolicy
|
||||||
import androidx.work.OneTimeWorkRequestBuilder
|
import androidx.work.OneTimeWorkRequestBuilder
|
||||||
import androidx.work.WorkManager
|
import androidx.work.WorkManager
|
||||||
import androidx.work.workDataOf
|
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.DownloadInfo
|
||||||
import com.deniscerri.ytdlnis.service.IDownloaderListener
|
import com.deniscerri.ytdlnis.service.IDownloaderListener
|
||||||
import com.deniscerri.ytdlnis.service.IDownloaderService
|
import com.deniscerri.ytdlnis.service.IDownloaderService
|
||||||
|
|
@ -46,7 +46,7 @@ class DownloaderService : Service() {
|
||||||
ConcurrentHashMap()
|
ConcurrentHashMap()
|
||||||
private val fileUtil = FileUtil()
|
private val fileUtil = FileUtil()
|
||||||
private val downloadInfo = DownloadInfo()
|
private val downloadInfo = DownloadInfo()
|
||||||
private var downloadQueue = LinkedList<Video>()
|
private var downloadQueue = LinkedList<ResultItem>()
|
||||||
private val compositeDisposable = CompositeDisposable()
|
private val compositeDisposable = CompositeDisposable()
|
||||||
private val notificationUtil = App.notificationUtil
|
private val notificationUtil = App.notificationUtil
|
||||||
private var context: Context? = null
|
private var context: Context? = null
|
||||||
|
|
@ -91,44 +91,45 @@ class DownloaderService : Service() {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBind(intent: Intent): IBinder? {
|
override fun onBind(intent: Intent): IBinder? {
|
||||||
val theIntent: Intent
|
// val theIntent: Intent
|
||||||
val pendingIntent: PendingIntent
|
// val pendingIntent: PendingIntent
|
||||||
if (intent.getBooleanExtra("rebind", false)) {
|
// if (intent.getBooleanExtra("rebind", false)) {
|
||||||
return binder
|
// return binder
|
||||||
}
|
// }
|
||||||
when (val id = intent.getIntExtra("id", 1)) {
|
// when (val id = intent.getIntExtra("id", 1)) {
|
||||||
NotificationUtil.DOWNLOAD_NOTIFICATION_ID -> {
|
// NotificationUtil.DOWNLOAD_NOTIFICATION_ID -> {
|
||||||
notificationChannelID = NotificationUtil.DOWNLOAD_SERVICE_CHANNEL_ID
|
// notificationChannelID = NotificationUtil.DOWNLOAD_SERVICE_CHANNEL_ID
|
||||||
theIntent = Intent(this, MainActivity::class.java)
|
// theIntent = Intent(this, MainActivity::class.java)
|
||||||
pendingIntent =
|
// pendingIntent =
|
||||||
PendingIntent.getActivity(this, 0, theIntent, PendingIntent.FLAG_IMMUTABLE)
|
// PendingIntent.getActivity(this, 0, theIntent, PendingIntent.FLAG_IMMUTABLE)
|
||||||
downloadNotificationID = id
|
// downloadNotificationID = id
|
||||||
val queue: ArrayList<out Video>? = intent.getParcelableArrayListExtra("queue")
|
// val queue: ArrayList<out ResultItem>? = intent.getParcelableArrayListExtra("queue")
|
||||||
downloadQueue = LinkedList()
|
// downloadQueue = LinkedList()
|
||||||
downloadQueue.addAll(queue!!)
|
// downloadQueue.addAll(queue!!)
|
||||||
downloadInfo.downloadQueue = downloadQueue
|
// downloadInfo.downloadQueue = downloadQueue
|
||||||
val title = downloadInfo.video.title
|
// val title = downloadInfo.video.title
|
||||||
val notification =
|
// val notification =
|
||||||
App.notificationUtil.createDownloadServiceNotification(pendingIntent, title, NotificationUtil.DOWNLOAD_SERVICE_CHANNEL_ID)
|
// App.notificationUtil.createDownloadServiceNotification(pendingIntent, title, 1, NotificationUtil.DOWNLOAD_SERVICE_CHANNEL_ID)
|
||||||
startForeground(downloadNotificationID, notification)
|
// startForeground(downloadNotificationID, notification)
|
||||||
startDownload(downloadQueue)
|
// startDownload(downloadQueue)
|
||||||
}
|
// }
|
||||||
NotificationUtil.COMMAND_DOWNLOAD_NOTIFICATION_ID -> {
|
// NotificationUtil.COMMAND_DOWNLOAD_NOTIFICATION_ID -> {
|
||||||
notificationChannelID = NotificationUtil.COMMAND_DOWNLOAD_SERVICE_CHANNEL_ID
|
// notificationChannelID = NotificationUtil.COMMAND_DOWNLOAD_SERVICE_CHANNEL_ID
|
||||||
theIntent = Intent(this, CustomCommandActivity::class.java)
|
// theIntent = Intent(this, CustomCommandActivity::class.java)
|
||||||
pendingIntent =
|
// pendingIntent =
|
||||||
PendingIntent.getActivity(this, 0, theIntent, PendingIntent.FLAG_IMMUTABLE)
|
// PendingIntent.getActivity(this, 0, theIntent, PendingIntent.FLAG_IMMUTABLE)
|
||||||
downloadNotificationID = id
|
// downloadNotificationID = id
|
||||||
val command = intent.getStringExtra("command")
|
// val command = intent.getStringExtra("command")
|
||||||
val commandNotification = App.notificationUtil.createDownloadServiceNotification(
|
// val commandNotification = App.notificationUtil.createDownloadServiceNotification(
|
||||||
pendingIntent,
|
// pendingIntent,
|
||||||
getString(R.string.running_ytdlp_command),
|
// getString(R.string.running_ytdlp_command),
|
||||||
NotificationUtil.COMMAND_DOWNLOAD_SERVICE_CHANNEL_ID
|
// 1,
|
||||||
)
|
// NotificationUtil.COMMAND_DOWNLOAD_SERVICE_CHANNEL_ID
|
||||||
startForeground(downloadNotificationID, commandNotification)
|
// )
|
||||||
startCommandDownload(command)
|
// startForeground(downloadNotificationID, commandNotification)
|
||||||
}
|
// startCommandDownload(command)
|
||||||
}
|
// }
|
||||||
|
// }
|
||||||
return binder
|
return binder
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -160,23 +161,24 @@ class DownloaderService : Service() {
|
||||||
activities.remove(activity)
|
activities.remove(activity)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun updateQueue(queue: ArrayList<Video>) {
|
|
||||||
try {
|
override fun updateQueue(queue: ArrayList<ResultItem>) {
|
||||||
for (i in queue.indices) {
|
// try {
|
||||||
downloadQueue.add(queue[i].clone() as Video)
|
// for (i in queue.indices) {
|
||||||
}
|
// downloadQueue.add(queue[i].clone() as ResultItem)
|
||||||
if (downloadQueue.size == queue.size) {
|
// }
|
||||||
downloadInfo.downloadQueue = downloadQueue
|
// if (downloadQueue.size == queue.size) {
|
||||||
startDownload(downloadQueue)
|
// downloadInfo.downloadQueue = downloadQueue
|
||||||
} else {
|
// startDownload(downloadQueue)
|
||||||
downloadInfo.downloadQueue = downloadQueue
|
// } else {
|
||||||
Toast.makeText(context, getString(R.string.added_to_queue), Toast.LENGTH_SHORT)
|
// downloadInfo.downloadQueue = downloadQueue
|
||||||
.show()
|
// 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)
|
// } catch (e: Exception) {
|
||||||
.show()
|
// Toast.makeText(context, "Couldn't update download queue! :(", Toast.LENGTH_SHORT)
|
||||||
}
|
// .show()
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun cancelDownload(cancelAll: Boolean) {
|
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
|
override fun removeItemFromDownloadQueue(video: ResultItem?, type: String?) {
|
||||||
if (downloadInfo.video.getURL() == video.getURL() && downloadInfo.video.downloadedType == video.downloadedType) {
|
// //if its the same video with the same download type as the current downloading one
|
||||||
cancelDownload(false)
|
// if (downloadInfo.video.url == video.url && downloadInfo.video.type == video.downloadedType) {
|
||||||
downloadInfo.downloadType = type
|
// cancelDownload(false)
|
||||||
onDownloadCancel(downloadInfo)
|
// downloadInfo.downloadType = type
|
||||||
downloadQueue.pop()
|
// onDownloadCancel(downloadInfo)
|
||||||
downloadInfo.downloadQueue = downloadQueue
|
// downloadQueue.pop()
|
||||||
startDownload(downloadQueue)
|
// downloadInfo.downloadQueue = downloadQueue
|
||||||
} else {
|
// startDownload(downloadQueue)
|
||||||
downloadQueue.remove(video)
|
// } else {
|
||||||
try {
|
// downloadQueue.remove(video)
|
||||||
val info = DownloadInfo()
|
// try {
|
||||||
info.video = video
|
// val info = DownloadInfo()
|
||||||
info.downloadType = type
|
// info.video = video
|
||||||
onDownloadCancel(info)
|
// info.downloadType = type
|
||||||
} catch (ignored: Exception) {
|
// onDownloadCancel(info)
|
||||||
}
|
// } catch (ignored: Exception) {
|
||||||
}
|
// }
|
||||||
Toast.makeText(
|
// }
|
||||||
context,
|
// Toast.makeText(
|
||||||
video.title + " " + getString(R.string.removed_from_queue),
|
// context,
|
||||||
Toast.LENGTH_SHORT
|
// video.title + " " + getString(R.string.removed_from_queue),
|
||||||
).show()
|
// Toast.LENGTH_SHORT
|
||||||
|
// ).show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -277,212 +280,212 @@ class DownloaderService : Service() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun startDownload(videos: LinkedList<Video>) {
|
private fun startDownload(videos: LinkedList<ResultItem>) {
|
||||||
if (videos.size == 0) {
|
// if (videos.size == 0) {
|
||||||
finishService()
|
// finishService()
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
val video: Video = try {
|
// val video: ResultItem = try {
|
||||||
videos.peek() as Video
|
// videos.peek() as ResultItem
|
||||||
} catch (e: Exception) {
|
// } catch (e: Exception) {
|
||||||
finishService()
|
// finishService()
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
try {
|
// try {
|
||||||
for (activity in activities.keys) {
|
// for (activity in activities.keys) {
|
||||||
activity.runOnUiThread {
|
// activity.runOnUiThread {
|
||||||
for (i in activities[activity]!!.indices) {
|
// for (i in activities[activity]!!.indices) {
|
||||||
val callback = activities[activity]!![i]
|
// val callback = activities[activity]!![i]
|
||||||
callback.onDownloadStart(downloadInfo)
|
// callback.onDownloadStart(downloadInfo)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
} catch (err: Exception) {
|
// } catch (err: Exception) {
|
||||||
err.printStackTrace()
|
// err.printStackTrace()
|
||||||
}
|
// }
|
||||||
val url = video.getURL()
|
// val url = video.getURL()
|
||||||
val request = YoutubeDLRequest(url)
|
// val request = YoutubeDLRequest(url)
|
||||||
val type = video.downloadedType
|
// val type = video.downloadedType
|
||||||
val downloadLocation = getDownloadLocation(type)
|
// val downloadLocation = getDownloadLocation(type)
|
||||||
|
//
|
||||||
var tempFileDir = File(cacheDir.absolutePath + """/${video.title}##${video.downloadedType}""")
|
// var tempFileDir = File(cacheDir.absolutePath + """/${video.title}##${video.downloadedType}""")
|
||||||
tempFileDir.delete()
|
// tempFileDir.delete()
|
||||||
tempFileDir.mkdir()
|
// tempFileDir.mkdir()
|
||||||
|
//
|
||||||
val sharedPreferences = context!!.getSharedPreferences("root_preferences", MODE_PRIVATE)
|
// val sharedPreferences = context!!.getSharedPreferences("root_preferences", MODE_PRIVATE)
|
||||||
val aria2 = sharedPreferences.getBoolean("aria2", false)
|
// val aria2 = sharedPreferences.getBoolean("aria2", false)
|
||||||
if (aria2) {
|
// if (aria2) {
|
||||||
request.addOption("--downloader", "libaria2c.so")
|
// request.addOption("--downloader", "libaria2c.so")
|
||||||
request.addOption("--external-downloader-args", "aria2c:\"--summary-interval=1\"")
|
// request.addOption("--external-downloader-args", "aria2c:\"--summary-interval=1\"")
|
||||||
} else {
|
// } else {
|
||||||
val concurrentFragments = sharedPreferences.getInt("concurrent_fragments", 1)
|
// val concurrentFragments = sharedPreferences.getInt("concurrent_fragments", 1)
|
||||||
if (concurrentFragments > 1) request.addOption("-N", concurrentFragments)
|
// if (concurrentFragments > 1) request.addOption("-N", concurrentFragments)
|
||||||
}
|
// }
|
||||||
val limitRate = sharedPreferences.getString("limit_rate", "")
|
// val limitRate = sharedPreferences.getString("limit_rate", "")
|
||||||
if (limitRate != "") request.addOption("-r", limitRate!!)
|
// if (limitRate != "") request.addOption("-r", limitRate!!)
|
||||||
val writeThumbnail = sharedPreferences.getBoolean("write_thumbnail", false)
|
// val writeThumbnail = sharedPreferences.getBoolean("write_thumbnail", false)
|
||||||
if (writeThumbnail) {
|
// if (writeThumbnail) {
|
||||||
request.addOption("--write-thumbnail")
|
// request.addOption("--write-thumbnail")
|
||||||
request.addOption("--convert-thumbnails", "png")
|
// request.addOption("--convert-thumbnails", "png")
|
||||||
}
|
// }
|
||||||
request.addOption("--no-mtime")
|
// request.addOption("--no-mtime")
|
||||||
val sponsorBlockFilters = sharedPreferences.getStringSet("sponsorblock_filters", emptySet())
|
// val sponsorBlockFilters = sharedPreferences.getStringSet("sponsorblock_filters", emptySet())
|
||||||
if (sponsorBlockFilters!!.isNotEmpty()) {
|
// if (sponsorBlockFilters!!.isNotEmpty()) {
|
||||||
val filters = java.lang.String.join(",", sponsorBlockFilters)
|
// val filters = java.lang.String.join(",", sponsorBlockFilters)
|
||||||
request.addOption("--sponsorblock-remove", filters)
|
// request.addOption("--sponsorblock-remove", filters)
|
||||||
}
|
// }
|
||||||
if (type == "audio") {
|
// if (type == "audio") {
|
||||||
if (downloadLocation.equals(getString(R.string.music_path))){
|
// if (downloadLocation.equals(getString(R.string.music_path))){
|
||||||
tempFileDir = File(getString(R.string.music_path))
|
// tempFileDir = File(getString(R.string.music_path))
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
request.addOption("-x")
|
// request.addOption("-x")
|
||||||
var format = video.audioFormat
|
// var format = video.audioFormat
|
||||||
if (format == null) format = sharedPreferences.getString("audio_format", "")
|
// if (format == null) format = sharedPreferences.getString("audio_format", "")
|
||||||
request.addOption("--audio-format", format!!)
|
// request.addOption("--audio-format", format!!)
|
||||||
request.addOption("--embed-metadata")
|
// request.addOption("--embed-metadata")
|
||||||
|
//
|
||||||
val embedThumb = sharedPreferences.getBoolean("embed_thumbnail", false)
|
// val embedThumb = sharedPreferences.getBoolean("embed_thumbnail", false)
|
||||||
if (embedThumb) {
|
// if (embedThumb) {
|
||||||
request.addOption("--embed-thumbnail")
|
// request.addOption("--embed-thumbnail")
|
||||||
request.addOption("--convert-thumbnails", "png")
|
// request.addOption("--convert-thumbnails", "png")
|
||||||
try {
|
// try {
|
||||||
val config = File(cacheDir, "config" + video.videoId + ".txt")
|
// val config = File(cacheDir, "config" + video.videoId + ".txt")
|
||||||
val config_data =
|
// val config_data =
|
||||||
"--ppa \"ffmpeg: -c:v png -vf crop=\\\"'if(gt(ih,iw),iw,ih)':'if(gt(iw,ih),ih,iw)'\\\"\""
|
// "--ppa \"ffmpeg: -c:v png -vf crop=\\\"'if(gt(ih,iw),iw,ih)':'if(gt(iw,ih),ih,iw)'\\\"\""
|
||||||
val stream = FileOutputStream(config)
|
// val stream = FileOutputStream(config)
|
||||||
stream.write(config_data.toByteArray())
|
// stream.write(config_data.toByteArray())
|
||||||
stream.close()
|
// stream.close()
|
||||||
request.addOption("--config", config.absolutePath)
|
// request.addOption("--config", config.absolutePath)
|
||||||
} catch (ignored: java.lang.Exception) {
|
// } catch (ignored: java.lang.Exception) {
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
request.addOption("--parse-metadata", "%(release_year,upload_date)s:%(meta_date)s")
|
// 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", "title", ".*.", video.title))
|
||||||
request.addCommands(Arrays.asList("--replace-in-metadata", "uploader", ".*.", video.author))
|
// request.addCommands(Arrays.asList("--replace-in-metadata", "uploader", ".*.", video.author))
|
||||||
|
//
|
||||||
if (!video.playlistTitle.isEmpty()) {
|
// if (!video.playlistTitle.isEmpty()) {
|
||||||
request.addOption("--parse-metadata", "%(album,playlist,title)s:%(meta_album)s")
|
// request.addOption("--parse-metadata", "%(album,playlist,title)s:%(meta_album)s")
|
||||||
request.addOption("--parse-metadata", "%(track_number,playlist_index)d:%(meta_track)s")
|
// request.addOption("--parse-metadata", "%(track_number,playlist_index)d:%(meta_track)s")
|
||||||
} else {
|
// } else {
|
||||||
request.addOption("--parse-metadata", "%(album,title)s:%(meta_album)s")
|
// request.addOption("--parse-metadata", "%(album,title)s:%(meta_album)s")
|
||||||
}
|
// }
|
||||||
request.addOption("-o", tempFileDir.absolutePath + "/%(uploader)s - %(title)s.%(ext)s")
|
// request.addOption("-o", tempFileDir.absolutePath + "/%(uploader)s - %(title)s.%(ext)s")
|
||||||
} else if (type == "video") {
|
// } else if (type == "video") {
|
||||||
if (downloadLocation.equals(getString(R.string.video_path))){
|
// if (downloadLocation.equals(getString(R.string.video_path))){
|
||||||
tempFileDir = File(getString(R.string.video_path))
|
// tempFileDir = File(getString(R.string.video_path))
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
val addChapters = sharedPreferences.getBoolean("add_chapters", false)
|
// val addChapters = sharedPreferences.getBoolean("add_chapters", false)
|
||||||
if (addChapters) {
|
// if (addChapters) {
|
||||||
request.addOption("--sponsorblock-mark", "all")
|
// request.addOption("--sponsorblock-mark", "all")
|
||||||
}
|
// }
|
||||||
val embedSubs = sharedPreferences.getBoolean("embed_subtitles", false)
|
// val embedSubs = sharedPreferences.getBoolean("embed_subtitles", false)
|
||||||
if (embedSubs) {
|
// if (embedSubs) {
|
||||||
request.addOption("--embed-subs", "")
|
// request.addOption("--embed-subs", "")
|
||||||
}
|
// }
|
||||||
var videoQuality = video.videoQuality
|
// var videoQuality = video.videoQuality
|
||||||
if (videoQuality == null) videoQuality =
|
// if (videoQuality == null) videoQuality =
|
||||||
sharedPreferences.getString("video_quality", "")
|
// sharedPreferences.getString("video_quality", "")
|
||||||
var formatArgument = "bestvideo+bestaudio/best"
|
// var formatArgument = "bestvideo+bestaudio/best"
|
||||||
if (videoQuality == "Worst Quality") {
|
// if (videoQuality == "Worst Quality") {
|
||||||
formatArgument = "worst"
|
// formatArgument = "worst"
|
||||||
} else if (!videoQuality!!.isEmpty() && videoQuality != "Best Quality") {
|
// } else if (!videoQuality!!.isEmpty() && videoQuality != "Best Quality") {
|
||||||
formatArgument = "bestvideo[height<=" + videoQuality.substring(
|
// formatArgument = "bestvideo[height<=" + videoQuality.substring(
|
||||||
0,
|
// 0,
|
||||||
videoQuality.length - 1
|
// videoQuality.length - 1
|
||||||
) + "]+bestaudio/best"
|
// ) + "]+bestaudio/best"
|
||||||
}
|
// }
|
||||||
request.addOption("-f", formatArgument)
|
// request.addOption("-f", formatArgument)
|
||||||
var format = video.videoFormat
|
// var format = video.videoFormat
|
||||||
if (format == null) format = sharedPreferences.getString("video_format", "")
|
// if (format == null) format = sharedPreferences.getString("video_format", "")
|
||||||
if (format != "DEFAULT") request.addOption("--merge-output-format", format!!)
|
// if (format != "DEFAULT") request.addOption("--merge-output-format", format!!)
|
||||||
if (format != "webm") {
|
// if (format != "webm") {
|
||||||
val embedThumb = sharedPreferences.getBoolean("embed_thumbnail", false)
|
// val embedThumb = sharedPreferences.getBoolean("embed_thumbnail", false)
|
||||||
if (embedThumb) {
|
// if (embedThumb) {
|
||||||
request.addOption("--embed-thumbnail")
|
// request.addOption("--embed-thumbnail")
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
request.addOption("-o", tempFileDir.absolutePath + "/%(uploader)s - %(title)s.%(ext)s")
|
// request.addOption("-o", tempFileDir.absolutePath + "/%(uploader)s - %(title)s.%(ext)s")
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
val disposable = Observable.fromCallable {
|
// val disposable = Observable.fromCallable {
|
||||||
YoutubeDL.getInstance().execute(request, downloadProcessID, callback)
|
// YoutubeDL.getInstance().execute(request, downloadProcessID, callback)
|
||||||
}
|
// }
|
||||||
.subscribeOn(Schedulers.newThread())
|
// .subscribeOn(Schedulers.newThread())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
// .observeOn(AndroidSchedulers.mainThread())
|
||||||
.subscribe({
|
// .subscribe({
|
||||||
val workTag = video.getURL()
|
// val workTag = video.getURL()
|
||||||
val workData = workDataOf(
|
// val workData = workDataOf(
|
||||||
originDir to tempFileDir.absolutePath,
|
// originDir to tempFileDir.absolutePath,
|
||||||
downLocation to downloadLocation,
|
// downLocation to downloadLocation,
|
||||||
title to video.title
|
// title to video.title
|
||||||
)
|
// )
|
||||||
val fileTransferWorkRequest = OneTimeWorkRequestBuilder<FileTransferWorker>()
|
// val fileTransferWorkRequest = OneTimeWorkRequestBuilder<FileTransferWorker>()
|
||||||
.addTag(workTag)
|
// .addTag(workTag)
|
||||||
.setInputData(workData)
|
// .setInputData(workData)
|
||||||
.build()
|
// .build()
|
||||||
workManager.enqueueUniqueWork(
|
// workManager.enqueueUniqueWork(
|
||||||
workTag,
|
// workTag,
|
||||||
ExistingWorkPolicy.KEEP,
|
// ExistingWorkPolicy.KEEP,
|
||||||
fileTransferWorkRequest
|
// fileTransferWorkRequest
|
||||||
)
|
// )
|
||||||
|
//
|
||||||
downloadInfo.downloadPath = fileUtil.formatPath(getDownloadLocation(type)!!)
|
// downloadInfo.downloadPath = fileUtil.formatPath(getDownloadLocation(type)!!)
|
||||||
Log.e(TAG, downloadInfo.downloadPath)
|
// Log.e(TAG, downloadInfo.downloadPath)
|
||||||
downloadInfo.downloadType = type
|
// downloadInfo.downloadType = type
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
try {
|
// try {
|
||||||
for (activity in activities.keys) {
|
// for (activity in activities.keys) {
|
||||||
activity.runOnUiThread {
|
// activity.runOnUiThread {
|
||||||
for (i in activities[activity]!!.indices) {
|
// for (i in activities[activity]!!.indices) {
|
||||||
val callback = activities[activity]!![i]
|
// val callback = activities[activity]!![i]
|
||||||
callback.onDownloadEnd(downloadInfo)
|
// callback.onDownloadEnd(downloadInfo)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
} catch (e: Exception) {
|
// } catch (e: Exception) {
|
||||||
Toast.makeText(context, e.message, Toast.LENGTH_LONG).show()
|
// Toast.makeText(context, e.message, Toast.LENGTH_LONG).show()
|
||||||
e.printStackTrace()
|
// e.printStackTrace()
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
// SCAN NEXT IN QUEUE
|
// // SCAN NEXT IN QUEUE
|
||||||
videos.remove()
|
// videos.remove()
|
||||||
downloadInfo.downloadQueue = videos
|
// downloadInfo.downloadQueue = videos
|
||||||
startDownload(videos)
|
// startDownload(videos)
|
||||||
}) { e: Throwable? ->
|
// }) { e: Throwable? ->
|
||||||
tempFileDir.delete()
|
// tempFileDir.delete()
|
||||||
if (BuildConfig.DEBUG) {
|
// if (BuildConfig.DEBUG) {
|
||||||
Toast.makeText(context, e!!.message, Toast.LENGTH_LONG).show()
|
// Toast.makeText(context, e!!.message, Toast.LENGTH_LONG).show()
|
||||||
Log.e(TAG, getString(R.string.failed_download), e)
|
// Log.e(TAG, getString(R.string.failed_download), e)
|
||||||
}
|
// }
|
||||||
notificationUtil.updateDownloadNotification(
|
// notificationUtil.updateDownloadNotification(
|
||||||
NotificationUtil.DOWNLOAD_NOTIFICATION_ID,
|
// NotificationUtil.DOWNLOAD_NOTIFICATION_ID,
|
||||||
getString(R.string.failed_download), 0, 0, downloadQueue.peek()?.title,
|
// getString(R.string.failed_download), 0, 0, downloadQueue.peek()?.title,
|
||||||
NotificationUtil.DOWNLOAD_SERVICE_CHANNEL_ID
|
// NotificationUtil.DOWNLOAD_SERVICE_CHANNEL_ID
|
||||||
)
|
// )
|
||||||
downloadInfo.downloadType = type
|
// downloadInfo.downloadType = type
|
||||||
try {
|
// try {
|
||||||
for (activity in activities.keys) {
|
// for (activity in activities.keys) {
|
||||||
activity.runOnUiThread {
|
// activity.runOnUiThread {
|
||||||
for (i in activities[activity]!!.indices) {
|
// for (i in activities[activity]!!.indices) {
|
||||||
val callback = activities[activity]!![i]
|
// val callback = activities[activity]!![i]
|
||||||
callback.onDownloadError(downloadInfo)
|
// callback.onDownloadError(downloadInfo)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
} catch (err: Exception) {
|
// } catch (err: Exception) {
|
||||||
err.printStackTrace()
|
// err.printStackTrace()
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
// SCAN NEXT IN QUEUE
|
// // SCAN NEXT IN QUEUE
|
||||||
videos.remove()
|
// videos.remove()
|
||||||
downloadInfo.downloadQueue = videos
|
// downloadInfo.downloadQueue = videos
|
||||||
startDownload(videos)
|
// startDownload(videos)
|
||||||
}
|
// }
|
||||||
compositeDisposable.add(disposable)
|
// compositeDisposable.add(disposable)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun startCommandDownload(text: String?) {
|
private fun startCommandDownload(text: String?) {
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.FragmentManager
|
import androidx.fragment.app.FragmentManager
|
||||||
import com.deniscerri.ytdlnis.DownloaderService.LocalBinder
|
import com.deniscerri.ytdlnis.DownloaderService.LocalBinder
|
||||||
import com.deniscerri.ytdlnis.database.DatabaseManager
|
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.databinding.ActivityMainBinding
|
||||||
import com.deniscerri.ytdlnis.ui.DownloadsFragment
|
import com.deniscerri.ytdlnis.ui.DownloadsFragment
|
||||||
import com.deniscerri.ytdlnis.ui.HomeFragment
|
import com.deniscerri.ytdlnis.ui.HomeFragment
|
||||||
|
|
@ -193,7 +193,6 @@ class MainActivity : AppCompatActivity() {
|
||||||
.commit()
|
.commit()
|
||||||
lastFragment = homeFragment
|
lastFragment = homeFragment
|
||||||
listeners = ArrayList()
|
listeners = ArrayList()
|
||||||
listeners.add(homeFragment.listener)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun replaceFragment(f: Fragment) {
|
private fun replaceFragment(f: Fragment) {
|
||||||
|
|
@ -202,37 +201,38 @@ class MainActivity : AppCompatActivity() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun startDownloadService(
|
fun startDownloadService(
|
||||||
downloadQueue: ArrayList<Video>,
|
downloadQueue: ArrayList<ResultItem>,
|
||||||
awaitingListener: IDownloaderListener
|
awaitingListener: IDownloaderListener
|
||||||
) {
|
) {
|
||||||
addQueueToDownloads(downloadQueue)
|
// addQueueToDownloads(downloadQueue)
|
||||||
if (isDownloadServiceRunning) {
|
// if (isDownloadServiceRunning) {
|
||||||
iDownloaderService?.updateQueue(downloadQueue)
|
// iDownloaderService?.updateQueue(downloadQueue)
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
if (!listeners.contains(awaitingListener)) listeners.add(awaitingListener)
|
// if (!listeners.contains(awaitingListener)) listeners.add(awaitingListener)
|
||||||
val serviceIntent = Intent(context, DownloaderService::class.java)
|
// val serviceIntent = Intent(context, DownloaderService::class.java)
|
||||||
serviceIntent.putParcelableArrayListExtra("queue", downloadQueue)
|
// serviceIntent.putParcelableArrayListExtra("queue", downloadQueue)
|
||||||
context.applicationContext.startService(serviceIntent)
|
// context.applicationContext.startService(serviceIntent)
|
||||||
context.applicationContext.bindService(serviceIntent, serviceConnection, BIND_AUTO_CREATE)
|
// context.applicationContext.bindService(serviceIntent, serviceConnection, BIND_AUTO_CREATE)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun addQueueToDownloads(downloadQueue: ArrayList<Video>) {
|
private fun addQueueToDownloads(downloadQueue: ArrayList<ResultItem>) {
|
||||||
try {
|
// try {
|
||||||
val sharedPreferences = context.getSharedPreferences("root_preferences", MODE_PRIVATE)
|
// val sharedPreferences = context.getSharedPreferences("root_preferences", MODE_PRIVATE)
|
||||||
if (!sharedPreferences.getBoolean("incognito", false)) {
|
// if (!sharedPreferences.getBoolean("incognito", false)) {
|
||||||
val databaseManager = DatabaseManager(context)
|
// val databaseManager = DatabaseManager(context)
|
||||||
for (i in downloadQueue.indices.reversed()) {
|
// for (i in downloadQueue.indices.reversed()) {
|
||||||
val v = downloadQueue[i]
|
// val v = downloadQueue[i]
|
||||||
v.isQueuedDownload = true
|
// v.isQueuedDownload = true
|
||||||
databaseManager.addToHistory(v)
|
// databaseManager.addToHistory(v)
|
||||||
}
|
// }
|
||||||
databaseManager.close()
|
// databaseManager.close()
|
||||||
//downloadsFragment.initCards()
|
// //downloadsFragment.initCards()
|
||||||
}
|
// }
|
||||||
} catch (e: Exception) {
|
// } catch (e: Exception) {
|
||||||
e.printStackTrace()
|
// e.printStackTrace()
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun stopDownloadService() {
|
fun stopDownloadService() {
|
||||||
|
|
@ -257,7 +257,7 @@ class MainActivity : AppCompatActivity() {
|
||||||
stopDownloadService()
|
stopDownloadService()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun removeItemFromDownloadQueue(video: Video?, type: String?) {
|
fun removeItemFromDownloadQueue(video: ResultItem?, type: String?) {
|
||||||
iDownloaderService!!.removeItemFromDownloadQueue(video, type)
|
iDownloaderService!!.removeItemFromDownloadQueue(video, type)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -84,7 +84,6 @@ public class HistoryAdapter extends ListAdapter<HistoryItem, HistoryAdapter.View
|
||||||
@Override
|
@Override
|
||||||
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
|
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
|
||||||
HistoryItem video = getItem(position);
|
HistoryItem video = getItem(position);
|
||||||
Log.e("AAA", String.valueOf(position));
|
|
||||||
MaterialCardView card = holder.cardView;
|
MaterialCardView card = holder.cardView;
|
||||||
// THUMBNAIL ----------------------------------
|
// THUMBNAIL ----------------------------------
|
||||||
ImageView thumbnail = card.findViewById(R.id.downloads_image_view);
|
ImageView thumbnail = card.findViewById(R.id.downloads_image_view);
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import android.app.Activity;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
|
import android.util.Log;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
@ -12,10 +13,12 @@ import android.widget.LinearLayout;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
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 androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
import com.deniscerri.ytdlnis.R;
|
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.button.MaterialButton;
|
||||||
import com.google.android.material.card.MaterialCardView;
|
import com.google.android.material.card.MaterialCardView;
|
||||||
import com.google.android.material.progressindicator.LinearProgressIndicator;
|
import com.google.android.material.progressindicator.LinearProgressIndicator;
|
||||||
|
|
@ -23,19 +26,33 @@ import com.squareup.picasso.Picasso;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
public class HomeAdapter extends RecyclerView.Adapter<HomeAdapter.ViewHolder> {
|
public class HomeAdapter extends ListAdapter<ResultItem, HomeAdapter.ViewHolder> {
|
||||||
private ArrayList<Video> videoList;
|
private final ArrayList<Integer> checkedVideos;
|
||||||
private ArrayList<Integer> checkedVideos;
|
|
||||||
private final OnItemClickListener onItemClickListener;
|
private final OnItemClickListener onItemClickListener;
|
||||||
private Activity activity;
|
private Activity activity;
|
||||||
|
|
||||||
public HomeAdapter(ArrayList<Video> videos, OnItemClickListener onItemClickListener, Activity activity){
|
public HomeAdapter(HomeAdapter.OnItemClickListener onItemClickListener, Activity activity){
|
||||||
this.videoList = videos;
|
super(DIFF_CALLBACK);
|
||||||
this.checkedVideos = new ArrayList<>();
|
this.checkedVideos = new ArrayList<>();
|
||||||
this.onItemClickListener = onItemClickListener;
|
this.onItemClickListener = onItemClickListener;
|
||||||
this.activity = activity;
|
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
|
@Override
|
||||||
public int getItemViewType(int position) {
|
public int getItemViewType(int position) {
|
||||||
return super.getItemViewType(position);
|
return super.getItemViewType(position);
|
||||||
|
|
@ -61,8 +78,8 @@ public class HomeAdapter extends RecyclerView.Adapter<HomeAdapter.ViewHolder> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
|
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;
|
MaterialCardView card = holder.cardView;
|
||||||
// THUMBNAIL ----------------------------------
|
// THUMBNAIL ----------------------------------
|
||||||
ImageView thumbnail = card.findViewById(R.id.result_image_view);
|
ImageView thumbnail = card.findViewById(R.id.result_image_view);
|
||||||
|
|
@ -97,7 +114,7 @@ public class HomeAdapter extends RecyclerView.Adapter<HomeAdapter.ViewHolder> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// BUTTONS ----------------------------------
|
// BUTTONS ----------------------------------
|
||||||
String videoID = video.getVideoId();
|
int videoID = video.getId();
|
||||||
|
|
||||||
LinearLayout buttonLayout = card.findViewById(R.id.download_button_layout);
|
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);
|
LinearProgressIndicator progressBar = card.findViewById(R.id.download_progress);
|
||||||
progressBar.setTag(videoID + "##progress");
|
progressBar.setTag(videoID + "##progress");
|
||||||
|
progressBar.setProgress(0);
|
||||||
|
progressBar.setIndeterminate(true);
|
||||||
|
progressBar.setVisibility(View.GONE);
|
||||||
|
|
||||||
if (video.isDownloading()){
|
// if (video.isDownloading()){
|
||||||
progressBar.setVisibility(View.VISIBLE);
|
// progressBar.setVisibility(View.VISIBLE);
|
||||||
}else {
|
// }else {
|
||||||
progressBar.setProgress(0);
|
// progressBar.setProgress(0);
|
||||||
progressBar.setIndeterminate(true);
|
// progressBar.setIndeterminate(true);
|
||||||
progressBar.setVisibility(View.GONE);
|
// progressBar.setVisibility(View.GONE);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
if (video.isDownloadingAudio()) {
|
// if (video.isDownloadingAudio()) {
|
||||||
musicBtn.setIcon(ContextCompat.getDrawable(activity, R.drawable.ic_cancel));
|
// musicBtn.setIcon(ContextCompat.getDrawable(activity, R.drawable.ic_cancel));
|
||||||
musicBtn.setTag(R.id.cancelDownload, "true");
|
// musicBtn.setTag(R.id.cancelDownload, "true");
|
||||||
}else{
|
// }else{
|
||||||
if(video.isAudioDownloaded() == 1){
|
// if(video.isAudioDownloaded() == 1){
|
||||||
musicBtn.setIcon(ContextCompat.getDrawable(activity, R.drawable.ic_music_downloaded));
|
// musicBtn.setIcon(ContextCompat.getDrawable(activity, R.drawable.ic_music_downloaded));
|
||||||
}else{
|
// }else{
|
||||||
musicBtn.setIcon(ContextCompat.getDrawable(activity, R.drawable.ic_music));
|
// musicBtn.setIcon(ContextCompat.getDrawable(activity, R.drawable.ic_music));
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
if (video.isDownloadingVideo()){
|
// if (video.isDownloadingVideo()){
|
||||||
videoBtn.setIcon(ContextCompat.getDrawable(activity, R.drawable.ic_cancel));
|
// videoBtn.setIcon(ContextCompat.getDrawable(activity, R.drawable.ic_cancel));
|
||||||
videoBtn.setTag(R.id.cancelDownload, "true");
|
// videoBtn.setTag(R.id.cancelDownload, "true");
|
||||||
}else{
|
// }else{
|
||||||
if(video.isVideoDownloaded() == 1){
|
// if(video.isVideoDownloaded() == 1){
|
||||||
videoBtn.setIcon(ContextCompat.getDrawable(activity, R.drawable.ic_video_downloaded));
|
// videoBtn.setIcon(ContextCompat.getDrawable(activity, R.drawable.ic_video_downloaded));
|
||||||
}else{
|
// }else{
|
||||||
videoBtn.setIcon(ContextCompat.getDrawable(activity, R.drawable.ic_video));
|
// videoBtn.setIcon(ContextCompat.getDrawable(activity, R.drawable.ic_video));
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
|
|
||||||
if(checkedVideos.contains(position)){
|
if(checkedVideos.contains(videoID)){
|
||||||
card.setChecked(true);
|
card.setChecked(true);
|
||||||
card.setStrokeWidth(5);
|
card.setStrokeWidth(5);
|
||||||
}else{
|
}else{
|
||||||
|
|
@ -158,41 +178,32 @@ public class HomeAdapter extends RecyclerView.Adapter<HomeAdapter.ViewHolder> {
|
||||||
|
|
||||||
card.setTag(videoID + "##card");
|
card.setTag(videoID + "##card");
|
||||||
card.setOnLongClickListener(view -> {
|
card.setOnLongClickListener(view -> {
|
||||||
checkCard(card, position);
|
checkCard(card, videoID);
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
card.setOnClickListener(view -> {
|
card.setOnClickListener(view -> {
|
||||||
if(checkedVideos.size() > 0){
|
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()){
|
if(card.isChecked()){
|
||||||
card.setStrokeWidth(0);
|
card.setStrokeWidth(0);
|
||||||
checkedVideos.remove(Integer.valueOf(position));
|
checkedVideos.remove(Integer.valueOf(videoID));
|
||||||
}else{
|
}else{
|
||||||
card.setStrokeWidth(5);
|
card.setStrokeWidth(5);
|
||||||
checkedVideos.add(position);
|
checkedVideos.add(videoID);
|
||||||
}
|
}
|
||||||
card.setChecked(!card.isChecked());
|
card.setChecked(!card.isChecked());
|
||||||
onItemClickListener.onCardClick(position, card.isChecked());
|
onItemClickListener.onCardClick(videoID, card.isChecked());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getItemCount() {
|
|
||||||
return videoList.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface OnItemClickListener {
|
public interface OnItemClickListener {
|
||||||
void onButtonClick(int position, String type);
|
void onButtonClick(int videoID, String type);
|
||||||
void onCardClick(int position, boolean add);
|
void onCardClick(int videoID, boolean add);
|
||||||
}
|
|
||||||
|
|
||||||
public void updateVideoListItem(Video v, int position){
|
|
||||||
videoList.set(position, v);
|
|
||||||
notifyItemChanged(position);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clearCheckedVideos(){
|
public void clearCheckedVideos(){
|
||||||
|
|
@ -203,16 +214,4 @@ public class HomeAdapter extends RecyclerView.Adapter<HomeAdapter.ViewHolder> {
|
||||||
}
|
}
|
||||||
checkedVideos.clear();
|
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 android.widget.Toast;
|
||||||
|
|
||||||
import com.deniscerri.ytdlnis.R;
|
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.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
@ -90,63 +92,63 @@ public class DatabaseManager extends SQLiteOpenHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("Range")
|
@SuppressLint("Range")
|
||||||
public void clearHistoryItem(Video video, boolean delete_file){
|
public void clearHistoryItem(HistoryItem video, boolean delete_file){
|
||||||
SQLiteDatabase db = this.getWritableDatabase();
|
// SQLiteDatabase db = this.getWritableDatabase();
|
||||||
|
//
|
||||||
if (delete_file){
|
// if (delete_file){
|
||||||
try{
|
// try{
|
||||||
Cursor cursor = db.rawQuery("SELECT * FROM " + history_table_name + " WHERE url='" +
|
// Cursor cursor = db.rawQuery("SELECT * FROM " + history_table_name + " WHERE url='" +
|
||||||
video.getURL() + "' AND type='"+video.getDownloadedType() + "' LIMIT 1", null);
|
// video.getURL() + "' AND type='"+video.getDownloadedType() + "' LIMIT 1", null);
|
||||||
|
//
|
||||||
if(cursor.moveToFirst()){
|
// if(cursor.moveToFirst()){
|
||||||
String path = cursor.getString(cursor.getColumnIndex(downloadPath));
|
// String path = cursor.getString(cursor.getColumnIndex(downloadPath));
|
||||||
File file = new File(path);
|
// File file = new File(path);
|
||||||
if(file.exists()){
|
// if(file.exists()){
|
||||||
file.delete();
|
// file.delete();
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}catch (Exception e){
|
// }catch (Exception e){
|
||||||
Toast.makeText(context, R.string.error_deleting_file, Toast.LENGTH_SHORT).show();
|
// Toast.makeText(context, R.string.error_deleting_file, Toast.LENGTH_SHORT).show();
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
|
//
|
||||||
db.execSQL("DELETE FROM " + history_table_name + " WHERE id=" + video.getId());
|
// db.execSQL("DELETE FROM " + history_table_name + " WHERE id=" + video.getId());
|
||||||
|
//
|
||||||
String where = "";
|
// String where = "";
|
||||||
switch(video.getDownloadedType()){
|
// switch(video.getDownloadedType()){
|
||||||
case "audio":
|
// case "audio":
|
||||||
where = " SET downloadedAudio=0 WHERE downloadedAudio=1 AND videoId='" + video.getVideoId()+"'";
|
// where = " SET downloadedAudio=0 WHERE downloadedAudio=1 AND videoId='" + video.getVideoId()+"'";
|
||||||
break;
|
// break;
|
||||||
case "video":
|
// case "video":
|
||||||
where = " SET downloadedVideo=0 WHERE downloadedVideo=1 AND videoId='" + video.getVideoId()+"'";
|
// where = " SET downloadedVideo=0 WHERE downloadedVideo=1 AND videoId='" + video.getVideoId()+"'";
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
//remove downloaded status from results
|
// //remove downloaded status from results
|
||||||
db.execSQL("UPDATE "+results_table_name+ where);
|
// db.execSQL("UPDATE "+results_table_name+ where);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clearDeletedHistory(){
|
public void clearDeletedHistory(){
|
||||||
ArrayList<Video> videos = getHistory("","","","");
|
// ArrayList<ResultItem> videos = getHistory("","","","");
|
||||||
for (int i = 0; i < videos.size(); i++){
|
// for (int i = 0; i < videos.size(); i++){
|
||||||
Video video = videos.get(i);
|
// ResultItem video = videos.get(i);
|
||||||
String path = video.getDownloadPath();
|
// String path = video.getDownloadPath();
|
||||||
File file = new File(path);
|
// File file = new File(path);
|
||||||
if(!file.exists() && !path.isEmpty()){
|
// if(!file.exists() && !path.isEmpty()){
|
||||||
clearHistoryItem(video, false);
|
// clearHistoryItem(video, false);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clearDownloadingHistory(){
|
public void clearDownloadingHistory(){
|
||||||
ArrayList<Video> videos = getHistory("","","","");
|
// ArrayList<ResultItem> videos = getHistory("","","","");
|
||||||
for (int i = 0; i < videos.size(); i++){
|
// for (int i = 0; i < videos.size(); i++){
|
||||||
Video video = videos.get(i);
|
// ResultItem video = videos.get(i);
|
||||||
if(video.isQueuedDownload()){
|
// if(video.isQueuedDownload()){
|
||||||
clearHistoryItem(video, false);
|
// clearHistoryItem(video, false);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clearDuplicateHistory(){
|
public void clearDuplicateHistory(){
|
||||||
|
|
@ -176,36 +178,36 @@ public class DatabaseManager extends SQLiteOpenHelper {
|
||||||
|
|
||||||
|
|
||||||
@SuppressLint("Range")
|
@SuppressLint("Range")
|
||||||
public ArrayList<Video> getResults(){
|
public ArrayList<ResultItem> getResults(){
|
||||||
SQLiteDatabase db = this.getReadableDatabase();
|
SQLiteDatabase db = this.getReadableDatabase();
|
||||||
Cursor cursor = db.rawQuery("SELECT * FROM " + results_table_name, null);
|
Cursor cursor = db.rawQuery("SELECT * FROM " + results_table_name, null);
|
||||||
ArrayList<Video> list = new ArrayList<>();
|
ArrayList<ResultItem> list = new ArrayList<>();
|
||||||
|
|
||||||
if(cursor.moveToFirst()){
|
// if(cursor.moveToFirst()){
|
||||||
do {
|
// do {
|
||||||
// on below line we are adding the data from cursor to our array list.
|
// // on below line we are adding the data from cursor to our array list.
|
||||||
list.add(new Video(cursor.getString(cursor.getColumnIndex(videoId)),
|
// list.add(new ResultItem(cursor.getString(cursor.getColumnIndex(videoId)),
|
||||||
cursor.getString(cursor.getColumnIndex(url)),
|
// cursor.getString(cursor.getColumnIndex(url)),
|
||||||
cursor.getString(cursor.getColumnIndex(title)),
|
// cursor.getString(cursor.getColumnIndex(title)),
|
||||||
cursor.getString(cursor.getColumnIndex(author)),
|
// cursor.getString(cursor.getColumnIndex(author)),
|
||||||
cursor.getString(cursor.getColumnIndex(duration)),
|
// cursor.getString(cursor.getColumnIndex(duration)),
|
||||||
cursor.getString(cursor.getColumnIndex(thumb)),
|
// cursor.getString(cursor.getColumnIndex(thumb)),
|
||||||
cursor.getInt(cursor.getColumnIndex(downloadedAudio)),
|
// cursor.getInt(cursor.getColumnIndex(downloadedAudio)),
|
||||||
cursor.getInt(cursor.getColumnIndex(downloadedVideo)),
|
// cursor.getInt(cursor.getColumnIndex(downloadedVideo)),
|
||||||
cursor.getInt(cursor.getColumnIndex(isPlaylistItem)),
|
// cursor.getInt(cursor.getColumnIndex(isPlaylistItem)),
|
||||||
cursor.getString(cursor.getColumnIndex(website)),
|
// cursor.getString(cursor.getColumnIndex(website)),
|
||||||
cursor.getInt(cursor.getColumnIndex(downloadedAudio)),
|
// cursor.getInt(cursor.getColumnIndex(downloadedAudio)),
|
||||||
cursor.getInt(cursor.getColumnIndex(downloadingVideo)),
|
// cursor.getInt(cursor.getColumnIndex(downloadingVideo)),
|
||||||
cursor.getString(cursor.getColumnIndex(playlistTitle))));
|
// cursor.getString(cursor.getColumnIndex(playlistTitle))));
|
||||||
} while (cursor.moveToNext());
|
// } while (cursor.moveToNext());
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
cursor.close();
|
// cursor.close();
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("Range")
|
@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();
|
SQLiteDatabase db = this.getReadableDatabase();
|
||||||
|
|
||||||
if (sort == null || sort.isEmpty()) sort = "DESC";
|
if (sort == null || sort.isEmpty()) sort = "DESC";
|
||||||
|
|
@ -215,91 +217,91 @@ public class DatabaseManager extends SQLiteOpenHelper {
|
||||||
" AND website LIKE '%"+site+"%'"+
|
" AND website LIKE '%"+site+"%'"+
|
||||||
" ORDER BY id "+sort,
|
" ORDER BY id "+sort,
|
||||||
null);
|
null);
|
||||||
ArrayList<Video> list = new ArrayList<>();
|
ArrayList<ResultItem> list = new ArrayList<>();
|
||||||
|
//
|
||||||
if(cursor.moveToFirst()){
|
// if(cursor.moveToFirst()){
|
||||||
do {
|
// do {
|
||||||
// on below line we are adding the data from cursor to our array list.
|
// // on below line we are adding the data from cursor to our array list.
|
||||||
list.add(new Video(cursor.getInt(cursor.getColumnIndex(id)),
|
// list.add(new ResultItem(cursor.getInt(cursor.getColumnIndex(id)),
|
||||||
cursor.getString(cursor.getColumnIndex(url)),
|
// cursor.getString(cursor.getColumnIndex(url)),
|
||||||
cursor.getString(cursor.getColumnIndex(title)),
|
// cursor.getString(cursor.getColumnIndex(title)),
|
||||||
cursor.getString(cursor.getColumnIndex(author)),
|
// cursor.getString(cursor.getColumnIndex(author)),
|
||||||
cursor.getString(cursor.getColumnIndex(duration)),
|
// cursor.getString(cursor.getColumnIndex(duration)),
|
||||||
cursor.getString(cursor.getColumnIndex(thumb)),
|
// cursor.getString(cursor.getColumnIndex(thumb)),
|
||||||
cursor.getString(cursor.getColumnIndex(type)),
|
// cursor.getString(cursor.getColumnIndex(type)),
|
||||||
cursor.getString(cursor.getColumnIndex(time)),
|
// cursor.getString(cursor.getColumnIndex(time)),
|
||||||
cursor.getString(cursor.getColumnIndex(downloadPath)),
|
// cursor.getString(cursor.getColumnIndex(downloadPath)),
|
||||||
cursor.getString(cursor.getColumnIndex(website)),
|
// cursor.getString(cursor.getColumnIndex(website)),
|
||||||
cursor.getInt(cursor.getColumnIndex(isQueuedDownload))));
|
// cursor.getInt(cursor.getColumnIndex(isQueuedDownload))));
|
||||||
} while (cursor.moveToNext());
|
// } while (cursor.moveToNext());
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
cursor.close();
|
// cursor.close();
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addToResults(ArrayList<Video> videot){
|
public void addToResults(ArrayList<ResultItem> videot){
|
||||||
SQLiteDatabase db = this.getWritableDatabase();
|
SQLiteDatabase db = this.getWritableDatabase();
|
||||||
ContentValues values = new ContentValues();
|
ContentValues values = new ContentValues();
|
||||||
|
|
||||||
for(Video v : videot){
|
// for(ResultItem v : videot){
|
||||||
values.put(videoId, v.getVideoId());
|
// values.put(videoId, v.getVideoId());
|
||||||
values.put(url, v.getURL());
|
// values.put(url, v.getURL());
|
||||||
values.put(title, v.getTitle());
|
// values.put(title, v.getTitle());
|
||||||
values.put(author, v.getAuthor());
|
// values.put(author, v.getAuthor());
|
||||||
values.put(duration, v.getDuration());
|
// values.put(duration, v.getDuration());
|
||||||
values.put(thumb, v.getThumb());
|
// values.put(thumb, v.getThumb());
|
||||||
values.put(downloadedAudio, v.isAudioDownloaded());
|
// values.put(downloadedAudio, v.isAudioDownloaded());
|
||||||
values.put(downloadedVideo, v.isVideoDownloaded());
|
// values.put(downloadedVideo, v.isVideoDownloaded());
|
||||||
values.put(isPlaylistItem, v.getIsPlaylistItem());
|
// values.put(isPlaylistItem, v.getIsPlaylistItem());
|
||||||
values.put(website, v.getWebsite());
|
// values.put(website, v.getWebsite());
|
||||||
values.put(downloadingAudio, 0);
|
// values.put(downloadingAudio, 0);
|
||||||
values.put(downloadingVideo, 0);
|
// values.put(downloadingVideo, 0);
|
||||||
values.put(playlistTitle, v.getPlaylistTitle());
|
// values.put(playlistTitle, v.getPlaylistTitle());
|
||||||
|
//
|
||||||
db.insert(results_table_name, null, values);
|
// db.insert(results_table_name, null, values);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
db.close();
|
// db.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addToHistory(Video v){
|
public void addToHistory(ResultItem v){
|
||||||
SQLiteDatabase db = this.getWritableDatabase();
|
SQLiteDatabase db = this.getWritableDatabase();
|
||||||
ContentValues values = new ContentValues();
|
ContentValues values = new ContentValues();
|
||||||
|
//
|
||||||
values.put(url, v.getURL());
|
// values.put(url, v.getURL());
|
||||||
values.put(title, v.getTitle());
|
// values.put(title, v.getTitle());
|
||||||
values.put(author, v.getAuthor());
|
// values.put(author, v.getAuthor());
|
||||||
values.put(duration, v.getDuration());
|
// values.put(duration, v.getDuration());
|
||||||
values.put(thumb, v.getThumb());
|
// values.put(thumb, v.getThumb());
|
||||||
values.put(type, v.getDownloadedType());
|
// values.put(type, v.getDownloadedType());
|
||||||
values.put(time, v.getDownloadedTime());
|
// values.put(time, v.getDownloadedTime());
|
||||||
values.put(downloadPath, v.getDownloadPath());
|
// values.put(downloadPath, v.getDownloadPath());
|
||||||
values.put(website, v.getWebsite());
|
// values.put(website, v.getWebsite());
|
||||||
values.put(isQueuedDownload, (v.isQueuedDownload()) ? 1 : 0);
|
// values.put(isQueuedDownload, (v.isQueuedDownload()) ? 1 : 0);
|
||||||
|
//
|
||||||
db.insert(history_table_name, null, values);
|
// db.insert(history_table_name, null, values);
|
||||||
db.close();
|
// db.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateHistoryItem(Video v){
|
public void updateHistoryItem(ResultItem v){
|
||||||
SQLiteDatabase db = this.getWritableDatabase();
|
SQLiteDatabase db = this.getWritableDatabase();
|
||||||
ContentValues values = new ContentValues();
|
ContentValues values = new ContentValues();
|
||||||
|
|
||||||
values.put(url, v.getURL());
|
// values.put(url, v.getURL());
|
||||||
values.put(title, v.getTitle());
|
// values.put(title, v.getTitle());
|
||||||
values.put(author, v.getAuthor());
|
// values.put(author, v.getAuthor());
|
||||||
values.put(duration, v.getDuration());
|
// values.put(duration, v.getDuration());
|
||||||
values.put(thumb, v.getThumb());
|
// values.put(thumb, v.getThumb());
|
||||||
values.put(type, v.getDownloadedType());
|
// values.put(type, v.getDownloadedType());
|
||||||
values.put(time, v.getDownloadedTime());
|
// values.put(time, v.getDownloadedTime());
|
||||||
values.put(downloadPath, v.getDownloadPath());
|
// values.put(downloadPath, v.getDownloadPath());
|
||||||
values.put(website, v.getWebsite());
|
// values.put(website, v.getWebsite());
|
||||||
values.put(isQueuedDownload, (v.isQueuedDownload()) ? 1 : 0);
|
// values.put(isQueuedDownload, (v.isQueuedDownload()) ? 1 : 0);
|
||||||
|
//
|
||||||
String where = url + "='"+v.getURL()+"' AND "+isQueuedDownload+"=1 AND "+type+"='"+v.getDownloadedType()+"'";
|
// String where = url + "='"+v.getURL()+"' AND "+isQueuedDownload+"=1 AND "+type+"='"+v.getDownloadedType()+"'";
|
||||||
db.update(history_table_name, values, where, null);
|
// db.update(history_table_name, values, where, null);
|
||||||
db.close();
|
// db.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateDownloadStatusOnResult(String id, String type, boolean downloaded){
|
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 {
|
interface DownloadDao {
|
||||||
|
|
||||||
@Query("SELECT * FROM downloads")
|
@Query("SELECT * FROM downloads")
|
||||||
fun getAllDownloads() : List<DownloadItem>
|
fun getAllDownloads() : LiveData<List<DownloadItem>>
|
||||||
|
|
||||||
@Query("SELECT * FROM downloads WHERE status='Queued'")
|
@Query("SELECT * FROM downloads WHERE status='Queued'")
|
||||||
fun getQueuedDownloads() : List<DownloadItem>
|
fun getQueuedDownloads() : List<DownloadItem>
|
||||||
|
|
|
||||||
|
|
@ -4,10 +4,11 @@ import androidx.room.ColumnInfo
|
||||||
import androidx.room.Entity
|
import androidx.room.Entity
|
||||||
import androidx.room.PrimaryKey
|
import androidx.room.PrimaryKey
|
||||||
|
|
||||||
@Entity(tableName = "downloads")
|
@Entity(tableName = "commandTemplates")
|
||||||
data class CommandTemplate(
|
data class CommandTemplate(
|
||||||
@PrimaryKey(autoGenerate = true)
|
|
||||||
val id: Int,
|
|
||||||
val title: String,
|
val title: String,
|
||||||
val content: String
|
val content: String
|
||||||
)
|
){
|
||||||
|
@PrimaryKey(autoGenerate = true)
|
||||||
|
var id: Int? = null
|
||||||
|
}
|
||||||
|
|
@ -6,8 +6,6 @@ import androidx.room.PrimaryKey
|
||||||
|
|
||||||
@Entity(tableName = "downloads")
|
@Entity(tableName = "downloads")
|
||||||
data class DownloadItem(
|
data class DownloadItem(
|
||||||
@PrimaryKey(autoGenerate = true)
|
|
||||||
val id: Int,
|
|
||||||
val url: String,
|
val url: String,
|
||||||
val title: String,
|
val title: String,
|
||||||
val author: String,
|
val author: String,
|
||||||
|
|
@ -28,4 +26,7 @@ data class DownloadItem(
|
||||||
val playlistTitle: String,
|
val playlistTitle: String,
|
||||||
@ColumnInfo(defaultValue = "Queued")
|
@ColumnInfo(defaultValue = "Queued")
|
||||||
var status: String
|
var status: String
|
||||||
)
|
){
|
||||||
|
@PrimaryKey(autoGenerate = true)
|
||||||
|
var id: Int? = null
|
||||||
|
}
|
||||||
|
|
@ -8,13 +8,14 @@ import com.yausername.youtubedl_android.mapper.VideoInfo
|
||||||
|
|
||||||
@Entity(tableName = "results")
|
@Entity(tableName = "results")
|
||||||
data class ResultItem(
|
data class ResultItem(
|
||||||
@PrimaryKey(autoGenerate = true)
|
|
||||||
val id: Int,
|
|
||||||
val url: String,
|
val url: String,
|
||||||
val title: String,
|
val title: String,
|
||||||
val author: String,
|
val author: String,
|
||||||
val duration: String,
|
val duration: String,
|
||||||
val thumb: String,
|
val thumb: String,
|
||||||
val website: 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
|
import com.deniscerri.ytdlnis.database.models.DownloadItem
|
||||||
|
|
||||||
class DownloadRepository(private val downloadDao: DownloadDao) {
|
class DownloadRepository(private val downloadDao: DownloadDao) {
|
||||||
|
val allDownloads : LiveData<List<DownloadItem>> = downloadDao.getAllDownloads()
|
||||||
|
|
||||||
suspend fun insert(item: DownloadItem){
|
suspend fun insert(item: DownloadItem){
|
||||||
downloadDao.insert(item)
|
downloadDao.insert(item)
|
||||||
|
|
@ -19,7 +20,7 @@ class DownloadRepository(private val downloadDao: DownloadDao) {
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun getQueuedDownloads() : List<DownloadItem>{
|
suspend fun getQueuedDownloads() : List<DownloadItem>{
|
||||||
var items = downloadDao.getQueuedDownloads();
|
val items = downloadDao.getQueuedDownloads()
|
||||||
for (i in items){
|
for (i in items){
|
||||||
i.status = "Downloading"
|
i.status = "Downloading"
|
||||||
downloadDao.update(i)
|
downloadDao.update(i)
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ class HistoryRepository(private val historyDao: HistoryDao) {
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun delete(item: HistoryItem, deleteFile: Boolean){
|
suspend fun delete(item: HistoryItem, deleteFile: Boolean){
|
||||||
historyDao.delete(item.id)
|
historyDao.delete(item.id!!)
|
||||||
if (deleteFile){
|
if (deleteFile){
|
||||||
val fileUtil = FileUtil()
|
val fileUtil = FileUtil()
|
||||||
fileUtil.deleteFile(item.downloadPath)
|
fileUtil.deleteFile(item.downloadPath)
|
||||||
|
|
@ -53,7 +53,7 @@ class HistoryRepository(private val historyDao: HistoryDao) {
|
||||||
val fileUtil = FileUtil()
|
val fileUtil = FileUtil()
|
||||||
items.value?.forEach { item ->
|
items.value?.forEach { item ->
|
||||||
if (!fileUtil.exists(item.downloadPath)){
|
if (!fileUtil.exists(item.downloadPath)){
|
||||||
historyDao.delete(item.id)
|
historyDao.delete(item.id!!)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,26 @@
|
||||||
package com.deniscerri.ytdlnis.database.repository
|
package com.deniscerri.ytdlnis.database.repository
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
import com.deniscerri.ytdlnis.database.dao.DownloadDao
|
import com.deniscerri.ytdlnis.database.dao.DownloadDao
|
||||||
import com.deniscerri.ytdlnis.database.dao.ResultDao
|
import com.deniscerri.ytdlnis.database.dao.ResultDao
|
||||||
import com.deniscerri.ytdlnis.database.models.DownloadItem
|
import com.deniscerri.ytdlnis.database.models.DownloadItem
|
||||||
import com.deniscerri.ytdlnis.database.models.ResultItem
|
import com.deniscerri.ytdlnis.database.models.ResultItem
|
||||||
|
import com.deniscerri.ytdlnis.util.InfoUtil
|
||||||
|
|
||||||
class ResultRepository(private val resultDao: ResultDao) {
|
class ResultRepository(private val resultDao: ResultDao) {
|
||||||
val allResults : LiveData<List<ResultItem>> = resultDao.getResults()
|
val allResults : LiveData<List<ResultItem>> = resultDao.getResults()
|
||||||
|
|
||||||
suspend fun insert(items: List<ResultItem>){
|
suspend fun insert(it: ResultItem){
|
||||||
items.forEach {
|
resultDao.insert(it)
|
||||||
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 android.app.Application
|
||||||
import androidx.lifecycle.AndroidViewModel
|
import androidx.lifecycle.AndroidViewModel
|
||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
|
import androidx.lifecycle.MediatorLiveData
|
||||||
|
import androidx.lifecycle.Observer
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import com.deniscerri.ytdlnis.database.DBManager
|
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.models.ResultItem
|
||||||
import com.deniscerri.ytdlnis.database.repository.DownloadRepository
|
|
||||||
import com.deniscerri.ytdlnis.database.repository.ResultRepository
|
import com.deniscerri.ytdlnis.database.repository.ResultRepository
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
class ResultViewModel(application: Application) : AndroidViewModel(application) {
|
class ResultViewModel(application: Application) : AndroidViewModel(application) {
|
||||||
private val repository : ResultRepository
|
private val repository : ResultRepository
|
||||||
private val allResults : LiveData<List<ResultItem>>
|
val items : LiveData<List<ResultItem>>
|
||||||
|
|
||||||
init {
|
init {
|
||||||
val dao = DBManager.getInstance(application).resultDao
|
val dao = DBManager.getInstance(application).resultDao
|
||||||
repository = ResultRepository(dao)
|
repository = ResultRepository(dao)
|
||||||
allResults = repository.allResults
|
items = repository.allResults
|
||||||
}
|
}
|
||||||
|
|
||||||
fun insert(items: List<ResultItem>) = viewModelScope.launch(Dispatchers.IO){
|
fun checkTrending() : Boolean{
|
||||||
repository.insert(items)
|
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) {
|
fun deleteAll() = viewModelScope.launch(Dispatchers.IO) {
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,13 @@
|
||||||
package com.deniscerri.ytdlnis.service;
|
package com.deniscerri.ytdlnis.service;
|
||||||
|
|
||||||
import com.deniscerri.ytdlnis.database.Video;
|
import com.deniscerri.ytdlnis.database.models.ResultItem;
|
||||||
|
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
|
|
||||||
public class DownloadInfo {
|
public class DownloadInfo {
|
||||||
private Video video;
|
private ResultItem video;
|
||||||
private int progress;
|
private int progress;
|
||||||
private LinkedList<Video> downloadQueue;
|
private LinkedList<ResultItem> downloadQueue;
|
||||||
private String outputLine;
|
private String outputLine;
|
||||||
private String downloadStatus;
|
private String downloadStatus;
|
||||||
private String downloadPath;
|
private String downloadPath;
|
||||||
|
|
@ -15,11 +15,11 @@ public class DownloadInfo {
|
||||||
|
|
||||||
public DownloadInfo(){}
|
public DownloadInfo(){}
|
||||||
|
|
||||||
public Video getVideo() {
|
public ResultItem getVideo() {
|
||||||
return video;
|
return video;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setVideo(Video video) {
|
public void setVideo(ResultItem video) {
|
||||||
this.video = video;
|
this.video = video;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -31,11 +31,11 @@ public class DownloadInfo {
|
||||||
this.progress = progress;
|
this.progress = progress;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LinkedList<Video> getDownloadQueue() {
|
public LinkedList<ResultItem> getDownloadQueue() {
|
||||||
return downloadQueue;
|
return downloadQueue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDownloadQueue(LinkedList<Video> downloadQueue) {
|
public void setDownloadQueue(LinkedList<ResultItem> downloadQueue) {
|
||||||
this.downloadQueue = downloadQueue;
|
this.downloadQueue = downloadQueue;
|
||||||
this.video = downloadQueue.peek();
|
this.video = downloadQueue.peek();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,5 @@
|
||||||
package com.deniscerri.ytdlnis.service;
|
package com.deniscerri.ytdlnis.service;
|
||||||
|
|
||||||
import com.deniscerri.ytdlnis.database.Video;
|
|
||||||
|
|
||||||
public interface IDownloaderListener {
|
public interface IDownloaderListener {
|
||||||
void onDownloadStart(DownloadInfo downloadInfo);
|
void onDownloadStart(DownloadInfo downloadInfo);
|
||||||
void onDownloadProgress(DownloadInfo downloadInfo);
|
void onDownloadProgress(DownloadInfo downloadInfo);
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,16 @@
|
||||||
package com.deniscerri.ytdlnis.service;
|
package com.deniscerri.ytdlnis.service;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import com.deniscerri.ytdlnis.database.Video;
|
|
||||||
|
import com.deniscerri.ytdlnis.database.models.ResultItem;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
public interface IDownloaderService {
|
public interface IDownloaderService {
|
||||||
DownloadInfo getInfo();
|
DownloadInfo getInfo();
|
||||||
void addActivity(Activity activity, ArrayList<IDownloaderListener> callback);
|
void addActivity(Activity activity, ArrayList<IDownloaderListener> callback);
|
||||||
void removeActivity(Activity activity);
|
void removeActivity(Activity activity);
|
||||||
void updateQueue(ArrayList<Video> queue);
|
void updateQueue(ArrayList<ResultItem> queue);
|
||||||
void cancelDownload(boolean cancelAll);
|
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.content.Context
|
||||||
import android.media.MediaScannerConnection
|
import android.media.MediaScannerConnection
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.FileUtils
|
|
||||||
import android.provider.DocumentsContract
|
import android.provider.DocumentsContract
|
||||||
import android.util.Log
|
|
||||||
import android.webkit.MimeTypeMap
|
import android.webkit.MimeTypeMap
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import com.deniscerri.ytdlnis.DownloaderService
|
|
||||||
import com.deniscerri.ytdlnis.R
|
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.File
|
||||||
import java.io.InputStream
|
|
||||||
import java.io.OutputStream
|
|
||||||
import java.net.URLDecoder
|
import java.net.URLDecoder
|
||||||
import java.nio.charset.StandardCharsets
|
import java.nio.charset.StandardCharsets
|
||||||
|
|
||||||
|
|
@ -55,7 +51,7 @@ class FileUtil() {
|
||||||
return formattedPath.toString()
|
return formattedPath.toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun scanMedia(video: Video, context: Context) : String {
|
fun scanMedia(video: DownloadItem, context: Context) : String {
|
||||||
val files = ArrayList<File>()
|
val files = ArrayList<File>()
|
||||||
val title: String = video.title.replace("[^a-zA-Z0-9]".toRegex(), "")
|
val title: String = video.title.replace("[^a-zA-Z0-9]".toRegex(), "")
|
||||||
var pathTmp: String
|
var pathTmp: String
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import android.content.Context
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import com.deniscerri.ytdlnis.R
|
import com.deniscerri.ytdlnis.R
|
||||||
import com.deniscerri.ytdlnis.database.DatabaseManager
|
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.YoutubeDL
|
||||||
import com.yausername.youtubedl_android.YoutubeDLRequest
|
import com.yausername.youtubedl_android.YoutubeDLRequest
|
||||||
import org.json.JSONArray
|
import org.json.JSONArray
|
||||||
|
|
@ -16,9 +16,10 @@ import java.io.InputStreamReader
|
||||||
import java.net.HttpURLConnection
|
import java.net.HttpURLConnection
|
||||||
import java.net.URL
|
import java.net.URL
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
import kotlin.collections.ArrayList
|
||||||
|
|
||||||
class InfoUtil(context: Context) {
|
class InfoUtil(context: Context) {
|
||||||
private var videos: ArrayList<Video?>
|
private var items: ArrayList<ResultItem?>
|
||||||
private var key: String? = null
|
private var key: String? = null
|
||||||
private var useInvidous = false
|
private var useInvidous = false
|
||||||
private var databaseManager: DatabaseManager? = null
|
private var databaseManager: DatabaseManager? = null
|
||||||
|
|
@ -32,7 +33,7 @@ class InfoUtil(context: Context) {
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
}
|
}
|
||||||
videos = ArrayList()
|
items = ArrayList()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun init(){
|
private fun init(){
|
||||||
|
|
@ -51,16 +52,16 @@ class InfoUtil(context: Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Throws(JSONException::class)
|
@Throws(JSONException::class)
|
||||||
fun search(query: String): ArrayList<Video?> {
|
fun search(query: String): ArrayList<ResultItem?> {
|
||||||
init()
|
init()
|
||||||
videos = ArrayList()
|
items = ArrayList()
|
||||||
return if (key!!.isEmpty()) {
|
return if (key!!.isEmpty()) {
|
||||||
if (useInvidous) searchFromInvidous(query) else getFromYTDL(query)
|
if (useInvidous) searchFromInvidous(query) else getFromYTDL(query)
|
||||||
} else searchFromKey(query)
|
} else searchFromKey(query)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Throws(JSONException::class)
|
@Throws(JSONException::class)
|
||||||
fun searchFromKey(query: String): ArrayList<Video?> {
|
fun searchFromKey(query: String): ArrayList<ResultItem?> {
|
||||||
//short data
|
//short data
|
||||||
val res =
|
val res =
|
||||||
genericRequest("https://youtube.googleapis.com/youtube/v3/search?part=snippet&q=$query&maxResults=25®ionCode=$countryCODE&key=$key")
|
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()) {
|
if (v == null || v.thumb.isEmpty()) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
videos.add(createVideofromJSON(snippet))
|
items.add(createVideofromJSON(snippet))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return videos
|
return items
|
||||||
}
|
}
|
||||||
|
|
||||||
@Throws(JSONException::class)
|
@Throws(JSONException::class)
|
||||||
fun searchFromInvidous(query: String): ArrayList<Video?> {
|
fun searchFromInvidous(query: String): ArrayList<ResultItem?> {
|
||||||
val dataArray = genericArrayRequest(invidousURL + "search?q=" + query + "?type=video")
|
val dataArray = genericArrayRequest(invidousURL + "search?q=" + query + "?type=video")
|
||||||
if (dataArray.length() == 0) return getFromYTDL(query)
|
if (dataArray.length() == 0) return getFromYTDL(query)
|
||||||
for (i in 0 until dataArray.length()) {
|
for (i in 0 until dataArray.length()) {
|
||||||
|
|
@ -128,15 +129,15 @@ class InfoUtil(context: Context) {
|
||||||
if (v == null || v.thumb.isEmpty()) {
|
if (v == null || v.thumb.isEmpty()) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
videos.add(v)
|
items.add(v)
|
||||||
}
|
}
|
||||||
return videos
|
return items
|
||||||
}
|
}
|
||||||
|
|
||||||
@Throws(JSONException::class)
|
@Throws(JSONException::class)
|
||||||
fun getPlaylist(id: String, nextPageToken: String): PlaylistTuple {
|
fun getPlaylist(id: String, nextPageToken: String): PlaylistTuple {
|
||||||
init()
|
init()
|
||||||
videos = ArrayList()
|
items = ArrayList()
|
||||||
if (key!!.isEmpty()) {
|
if (key!!.isEmpty()) {
|
||||||
return if (useInvidous) getPlaylistFromInvidous(id) else PlaylistTuple(
|
return if (useInvidous) getPlaylistFromInvidous(id) else PlaylistTuple(
|
||||||
"",
|
"",
|
||||||
|
|
@ -186,12 +187,12 @@ class InfoUtil(context: Context) {
|
||||||
} else {
|
} else {
|
||||||
j++
|
j++
|
||||||
}
|
}
|
||||||
v.isPlaylistItem = 1
|
v.playlistTitle = "YTDLnis"
|
||||||
videos.add(v)
|
items.add(v)
|
||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
val next = res.optString("nextPageToken")
|
val next = res.optString("nextPageToken")
|
||||||
return PlaylistTuple(next, videos)
|
return PlaylistTuple(next, items)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getPlaylistFromInvidous(id: String): PlaylistTuple {
|
private fun getPlaylistFromInvidous(id: String): PlaylistTuple {
|
||||||
|
|
@ -208,17 +209,16 @@ class InfoUtil(context: Context) {
|
||||||
val v = createVideofromInvidiousJSON(element)
|
val v = createVideofromInvidiousJSON(element)
|
||||||
if (v == null || v.thumb.isEmpty()) continue
|
if (v == null || v.thumb.isEmpty()) continue
|
||||||
v.playlistTitle = res.getString("title")
|
v.playlistTitle = res.getString("title")
|
||||||
v.isPlaylistItem = 1
|
items.add(v)
|
||||||
videos.add(v)
|
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
}
|
}
|
||||||
return PlaylistTuple("", videos)
|
return PlaylistTuple("", items)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Throws(JSONException::class)
|
@Throws(JSONException::class)
|
||||||
fun getVideo(id: String): Video? {
|
fun getVideo(id: String): ResultItem? {
|
||||||
init()
|
init()
|
||||||
if (key!!.isEmpty()) {
|
if (key!!.isEmpty()) {
|
||||||
return if (useInvidous) {
|
return if (useInvidous) {
|
||||||
|
|
@ -245,8 +245,8 @@ class InfoUtil(context: Context) {
|
||||||
return createVideofromJSON(res)
|
return createVideofromJSON(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createVideofromJSON(obj: JSONObject): Video? {
|
private fun createVideofromJSON(obj: JSONObject): ResultItem? {
|
||||||
var video: Video? = null
|
var video: ResultItem? = null
|
||||||
try {
|
try {
|
||||||
val id = obj.getString("videoID")
|
val id = obj.getString("videoID")
|
||||||
val title = obj.getString("title").toString()
|
val title = obj.getString("title").toString()
|
||||||
|
|
@ -257,20 +257,14 @@ class InfoUtil(context: Context) {
|
||||||
val downloadedAudio = databaseManager!!.checkDownloaded(url, "audio")
|
val downloadedAudio = databaseManager!!.checkDownloaded(url, "audio")
|
||||||
val downloadedVideo = databaseManager!!.checkDownloaded(url, "video")
|
val downloadedVideo = databaseManager!!.checkDownloaded(url, "video")
|
||||||
val isPlaylist = 0
|
val isPlaylist = 0
|
||||||
video = Video(
|
video = ResultItem(
|
||||||
id,
|
id,
|
||||||
url,
|
url,
|
||||||
title,
|
title,
|
||||||
author,
|
author,
|
||||||
duration,
|
duration,
|
||||||
thumb,
|
thumb,
|
||||||
downloadedAudio,
|
"youtube"
|
||||||
downloadedVideo,
|
|
||||||
isPlaylist,
|
|
||||||
"youtube",
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
""
|
|
||||||
)
|
)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.e(TAG, e.toString())
|
Log.e(TAG, e.toString())
|
||||||
|
|
@ -278,8 +272,8 @@ class InfoUtil(context: Context) {
|
||||||
return video
|
return video
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createVideofromInvidiousJSON(obj: JSONObject): Video? {
|
private fun createVideofromInvidiousJSON(obj: JSONObject): ResultItem? {
|
||||||
var video: Video? = null
|
var video: ResultItem? = null
|
||||||
try {
|
try {
|
||||||
val id = obj.getString("videoId")
|
val id = obj.getString("videoId")
|
||||||
val title = obj.getString("title").toString()
|
val title = obj.getString("title").toString()
|
||||||
|
|
@ -290,20 +284,14 @@ class InfoUtil(context: Context) {
|
||||||
val downloadedAudio = databaseManager!!.checkDownloaded(url, "audio")
|
val downloadedAudio = databaseManager!!.checkDownloaded(url, "audio")
|
||||||
val downloadedVideo = databaseManager!!.checkDownloaded(url, "video")
|
val downloadedVideo = databaseManager!!.checkDownloaded(url, "video")
|
||||||
val isPlaylist = 0
|
val isPlaylist = 0
|
||||||
video = Video(
|
video = ResultItem(
|
||||||
id,
|
id,
|
||||||
url,
|
url,
|
||||||
title,
|
title,
|
||||||
author,
|
author,
|
||||||
duration,
|
duration,
|
||||||
thumb,
|
thumb,
|
||||||
downloadedAudio,
|
"youtube"
|
||||||
downloadedVideo,
|
|
||||||
isPlaylist,
|
|
||||||
"youtube",
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
""
|
|
||||||
)
|
)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.e(TAG, e.toString())
|
Log.e(TAG, e.toString())
|
||||||
|
|
@ -395,16 +383,16 @@ class InfoUtil(context: Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Throws(JSONException::class)
|
@Throws(JSONException::class)
|
||||||
fun getTrending(context: Context): ArrayList<Video?> {
|
fun getTrending(context: Context): ArrayList<ResultItem?> {
|
||||||
init()
|
init()
|
||||||
videos = ArrayList()
|
items = ArrayList()
|
||||||
return if (key!!.isEmpty()) {
|
return if (key!!.isEmpty()) {
|
||||||
if (useInvidous) getTrendingFromInvidous(context) else ArrayList()
|
if (useInvidous) getTrendingFromInvidous(context) else ArrayList()
|
||||||
} else getTrendingFromKey(context)
|
} else getTrendingFromKey(context)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Throws(JSONException::class)
|
@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"
|
val url = "https://www.googleapis.com/youtube/v3/videos?part=snippet&chart=mostPopular&videoCategoryId=10®ionCode=$countryCODE&maxResults=25&key=$key"
|
||||||
//short data
|
//short data
|
||||||
val res = genericRequest(url)
|
val res = genericRequest(url)
|
||||||
|
|
@ -428,12 +416,12 @@ class InfoUtil(context: Context) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
v.playlistTitle = context.getString(R.string.trendingPlaylist)
|
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 url = invidousURL + "trending?type=music®ion=" + countryCODE
|
||||||
val res = genericArrayRequest(url)
|
val res = genericArrayRequest(url)
|
||||||
try {
|
try {
|
||||||
|
|
@ -443,17 +431,17 @@ class InfoUtil(context: Context) {
|
||||||
val v = createVideofromInvidiousJSON(element)
|
val v = createVideofromInvidiousJSON(element)
|
||||||
if (v == null || v.thumb.isEmpty()) continue
|
if (v == null || v.thumb.isEmpty()) continue
|
||||||
v.playlistTitle = context.getString(R.string.trendingPlaylist)
|
v.playlistTitle = context.getString(R.string.trendingPlaylist)
|
||||||
videos.add(v)
|
items.add(v)
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
}
|
}
|
||||||
return videos
|
return items
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getFromYTDL(query: String): ArrayList<Video?> {
|
fun getFromYTDL(query: String): ArrayList<ResultItem?> {
|
||||||
init()
|
init()
|
||||||
videos = ArrayList()
|
items = ArrayList()
|
||||||
try {
|
try {
|
||||||
val request = YoutubeDLRequest(query)
|
val request = YoutubeDLRequest(query)
|
||||||
request.addOption("--flat-playlist")
|
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")
|
val website = if (jsonObject.has("ie_key")) jsonObject.getString("ie_key") else jsonObject.getString("extractor")
|
||||||
var playlistTitle: String? = ""
|
var playlistTitle: String? = ""
|
||||||
if (jsonObject.has("playlist")) playlistTitle = jsonObject.getString("playlist")
|
if (jsonObject.has("playlist")) playlistTitle = jsonObject.getString("playlist")
|
||||||
videos.add(
|
items.add(
|
||||||
Video(
|
ResultItem(
|
||||||
jsonObject.getString("id"),
|
|
||||||
url,
|
url,
|
||||||
title,
|
title,
|
||||||
author,
|
author!!,
|
||||||
duration,
|
duration,
|
||||||
thumb,
|
thumb!!,
|
||||||
databaseManager!!.checkDownloaded(url, "audio"),
|
|
||||||
databaseManager!!.checkDownloaded(url, "video"),
|
|
||||||
isPlaylist,
|
|
||||||
website,
|
website,
|
||||||
0,
|
playlistTitle!!
|
||||||
0,
|
|
||||||
playlistTitle
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
}
|
}
|
||||||
return videos
|
return items
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getSearchSuggestions(query: String): ArrayList<String> {
|
fun getSearchSuggestions(query: String): ArrayList<String> {
|
||||||
|
|
@ -598,7 +580,7 @@ class InfoUtil(context: Context) {
|
||||||
|
|
||||||
class PlaylistTuple internal constructor(
|
class PlaylistTuple internal constructor(
|
||||||
var nextPageToken: String,
|
var nextPageToken: String,
|
||||||
var videos: ArrayList<Video?>
|
var videos: ArrayList<ResultItem?>
|
||||||
)
|
)
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ class DownloadWorker(
|
||||||
setForeground(foregroundInfo)
|
setForeground(foregroundInfo)
|
||||||
|
|
||||||
while (queue.isNotEmpty()){
|
while (queue.isNotEmpty()){
|
||||||
val item = dao.getDownloadById(queue[0].id)
|
val item = dao.getDownloadById(queue[0].id!!)
|
||||||
queue.removeFirst()
|
queue.removeFirst()
|
||||||
val url = item.url
|
val url = item.url
|
||||||
val request = YoutubeDLRequest(url)
|
val request = YoutubeDLRequest(url)
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:id="@+id/recycler_view_home"
|
android:id="@+id/recyclerViewHome"
|
||||||
android:nestedScrollingEnabled="false"
|
android:nestedScrollingEnabled="false"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
|
|
||||||
|
|
@ -36,8 +36,8 @@ buildscript {
|
||||||
}
|
}
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id 'com.android.application' version '7.3.1' apply false
|
id 'com.android.application' version '7.4.0' apply false
|
||||||
id 'com.android.library' version '7.3.1' apply false
|
id 'com.android.library' version '7.4.0' apply false
|
||||||
id 'org.jetbrains.kotlin.android' version '1.7.20' apply false
|
id 'org.jetbrains.kotlin.android' version '1.7.20' apply false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue