Changed search suggestions provider & more

Replaced invidious dependency with googles
added ability to toggle thumbnail embedding for audio on the download card
pull/44/head
Denis Çerri 3 years ago
parent 5ea0c4654f
commit 48cc4f3f75
No known key found for this signature in database
GPG Key ID: 95C43D517D830350

@ -320,7 +320,7 @@
<PersistentState>
<option name="values">
<map>
<entry key="url" value="file:/$USER_HOME$/AppData/Local/Android/Sdk/icons/material/materialicons/nights_stay/baseline_nights_stay_24.xml" />
<entry key="url" value="file:/$USER_HOME$/AppData/Local/Android/Sdk/icons/material/materialicons/text_format/baseline_text_format_24.xml" />
</map>
</option>
</PersistentState>
@ -330,7 +330,7 @@
</option>
<option name="values">
<map>
<entry key="outputName" value="ic_nightly" />
<entry key="outputName" value="ic_textformat" />
<entry key="sourceFile" value="C:\Users\denis\Desktop\adaptiveproduct_youtube_foreground_color_108 (1).svg" />
</map>
</option>

@ -120,7 +120,7 @@ dependencies {
implementation "androidx.appcompat:appcompat:$appCompatVer"
implementation "androidx.constraintlayout:constraintlayout:2.1.4"
implementation 'com.google.android.material:material:1.8.0'
implementation 'com.google.android.material:material:1.7.0'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'androidx.core:core:1.9.0'
implementation 'androidx.recyclerview:recyclerview:1.2.1'

@ -2,7 +2,7 @@
"formatVersion": 1,
"database": {
"version": 1,
"identityHash": "9197d2ce894417365b9012ace8bcf284",
"identityHash": "ae6989cdbd101bb25c22cc38d8ec456d",
"entities": [
{
"tableName": "results",
@ -160,7 +160,7 @@
},
{
"tableName": "downloads",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `url` TEXT NOT NULL, `title` TEXT NOT NULL, `author` TEXT NOT NULL, `thumb` TEXT NOT NULL, `duration` TEXT NOT NULL, `type` TEXT NOT NULL, `format` TEXT NOT NULL, `downloadPath` TEXT NOT NULL, `website` TEXT NOT NULL, `downloadSize` TEXT NOT NULL, `playlistTitle` TEXT NOT NULL, `embedSubs` INTEGER NOT NULL, `addChapters` INTEGER NOT NULL, `SaveThumb` INTEGER NOT NULL, `status` TEXT NOT NULL DEFAULT 'Queued', `downloadStartTime` INTEGER NOT NULL DEFAULT 0)",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `url` TEXT NOT NULL, `title` TEXT NOT NULL, `author` TEXT NOT NULL, `thumb` TEXT NOT NULL, `duration` TEXT NOT NULL, `type` TEXT NOT NULL, `format` TEXT NOT NULL, `downloadPath` TEXT NOT NULL, `website` TEXT NOT NULL, `downloadSize` TEXT NOT NULL, `playlistTitle` TEXT NOT NULL, `audioPreferences` TEXT NOT NULL, `videoPreferences` TEXT NOT NULL, `customFileNameTemplate` TEXT NOT NULL, `SaveThumb` INTEGER NOT NULL, `status` TEXT NOT NULL DEFAULT 'Queued', `downloadStartTime` INTEGER NOT NULL DEFAULT 0)",
"fields": [
{
"fieldPath": "id",
@ -235,15 +235,21 @@
"notNull": true
},
{
"fieldPath": "embedSubs",
"columnName": "embedSubs",
"affinity": "INTEGER",
"fieldPath": "audioPreferences",
"columnName": "audioPreferences",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "addChapters",
"columnName": "addChapters",
"affinity": "INTEGER",
"fieldPath": "videoPreferences",
"columnName": "videoPreferences",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "customFileNameTemplate",
"columnName": "customFileNameTemplate",
"affinity": "TEXT",
"notNull": true
},
{
@ -312,7 +318,7 @@
"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, '9197d2ce894417365b9012ace8bcf284')"
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'ae6989cdbd101bb25c22cc38d8ec456d')"
]
}
}

@ -1,7 +1,9 @@
package com.deniscerri.ytdlnis.database
import androidx.room.TypeConverter
import com.deniscerri.ytdlnis.database.models.AudioPreferences
import com.deniscerri.ytdlnis.database.models.Format
import com.deniscerri.ytdlnis.database.models.VideoPreferences
import com.deniscerri.ytdlnis.database.viewmodel.DownloadViewModel
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
@ -39,4 +41,14 @@ class Converters {
else -> DownloadViewModel.Type.command
}
}
@TypeConverter
fun audioPreferencesToString(audioPreferences: AudioPreferences): String = Gson().toJson(audioPreferences)
@TypeConverter
fun stringToAudioPreferences(string: String): AudioPreferences = Gson().fromJson(string, AudioPreferences::class.java)
@TypeConverter
fun videoPreferencesToString(videoPreferences: VideoPreferences): String = Gson().toJson(videoPreferences)
@TypeConverter
fun stringToVideoPreferences(string: String): VideoPreferences = Gson().fromJson(string, VideoPreferences::class.java)
}

@ -16,6 +16,9 @@ interface CommandTemplateDao {
@Query("SELECT * FROM commandTemplates WHERE id=:id LIMIT 1")
fun getTemplate(id: Long) : CommandTemplate
@Query("SELECT * FROM commandTemplates LIMIT 1")
fun getFirst() : CommandTemplate
@Insert(onConflict = OnConflictStrategy.IGNORE)
suspend fun insert(item: CommandTemplate)

@ -0,0 +1,5 @@
package com.deniscerri.ytdlnis.database.models
data class AudioPreferences(
var embedThumb: Boolean = true,
)

@ -21,8 +21,9 @@ data class DownloadItem(
val website: String,
val downloadSize: String,
val playlistTitle: String,
var embedSubs: Boolean,
var addChapters: Boolean,
val audioPreferences : AudioPreferences,
val videoPreferences: VideoPreferences,
var customFileNameTemplate: String,
var SaveThumb: Boolean,
@ColumnInfo(defaultValue = "Queued")
var status: String,

@ -0,0 +1,6 @@
package com.deniscerri.ytdlnis.database.models
data class VideoPreferences (
var embedSubs: Boolean = true,
var addChapters: Boolean = true,
)

@ -15,9 +15,8 @@ import androidx.work.WorkManager
import com.deniscerri.ytdlnis.App
import com.deniscerri.ytdlnis.R
import com.deniscerri.ytdlnis.database.DBManager
import com.deniscerri.ytdlnis.database.models.DownloadItem
import com.deniscerri.ytdlnis.database.models.Format
import com.deniscerri.ytdlnis.database.models.ResultItem
import com.deniscerri.ytdlnis.database.dao.CommandTemplateDao
import com.deniscerri.ytdlnis.database.models.*
import com.deniscerri.ytdlnis.database.repository.DownloadRepository
import com.deniscerri.ytdlnis.work.DownloadWorker
import com.google.gson.Gson
@ -29,6 +28,7 @@ import java.util.concurrent.TimeUnit
class DownloadViewModel(application: Application) : AndroidViewModel(application) {
private val repository : DownloadRepository
private val sharedPreferences: SharedPreferences
private val commandTemplateDao: CommandTemplateDao
val allDownloads : LiveData<List<DownloadItem>>
val queuedDownloads : LiveData<List<DownloadItem>>
val activeDownloads : LiveData<List<DownloadItem>>
@ -45,6 +45,7 @@ class DownloadViewModel(application: Application) : AndroidViewModel(application
repository = DownloadRepository(dao)
sharedPreferences =
getApplication<App>().getSharedPreferences("root_preferences", Activity.MODE_PRIVATE)
commandTemplateDao = DBManager.getInstance(application).commandTemplateDao
allDownloads = repository.allDownloads
queuedDownloads = repository.queuedDownloads
@ -82,9 +83,14 @@ class DownloadViewModel(application: Application) : AndroidViewModel(application
}
fun createDownloadItemFromResult(resultItem: ResultItem, type: Type) : DownloadItem {
val embedSubs = sharedPreferences.getBoolean("embed_subtitles", false)
val embedSubs = sharedPreferences.getBoolean("embed_subtitles", false)
val addChapters = sharedPreferences.getBoolean("add_chapters", false)
val saveThumb = sharedPreferences.getBoolean("write_thumbnail", false)
val embedThumb = sharedPreferences.getBoolean("embed_thumbnail", false)
val customFileNameTemplate = sharedPreferences.getString("file_name_template", "%(uploader)s - %(title)s")
val audioPreferences = AudioPreferences(embedThumb)
val videoPreferences = VideoPreferences(embedSubs, addChapters)
return DownloadItem(0,
resultItem.url,
@ -94,7 +100,7 @@ class DownloadViewModel(application: Application) : AndroidViewModel(application
resultItem.duration,
type,
getFormat(resultItem, type),
"", resultItem.website, "", resultItem.playlistTitle, embedSubs, addChapters, saveThumb, DownloadRepository.Status.Processing.toString(), 0
"", resultItem.website, "", resultItem.playlistTitle, audioPreferences, videoPreferences,customFileNameTemplate!!, saveThumb, DownloadRepository.Status.Processing.toString(), 0
)
}

@ -25,6 +25,7 @@ import com.deniscerri.ytdlnis.database.viewmodel.DownloadViewModel
import com.deniscerri.ytdlnis.database.viewmodel.DownloadViewModel.Type
import com.deniscerri.ytdlnis.databinding.FragmentHomeBinding
import com.deniscerri.ytdlnis.util.FileUtil
import com.google.android.material.chip.Chip
import com.google.android.material.textfield.TextInputLayout
import kotlinx.coroutines.launch
@ -190,6 +191,12 @@ class DownloadAudioFragment(private var resultItem: ResultItem) : Fragment() {
downloadItem.format.container = containers[index]
}
val embedThumb = view.findViewById<Chip>(R.id.embed_thumb)
embedThumb!!.isChecked = downloadItem.audioPreferences.embedThumb
embedThumb.setOnClickListener {
downloadItem.audioPreferences.embedThumb = embedThumb.isChecked
}
}catch (e : Exception){
e.printStackTrace()
}

@ -121,24 +121,24 @@ class DownloadCommandFragment(private val resultItem: ResultItem) : Fragment() {
commandPathResultLauncher.launch(intent)
}
val embedSubs = view.findViewById<Chip>(R.id.embed_subtitles)
embedSubs!!.isChecked = embedSubs.isChecked
embedSubs.setOnClickListener {
downloadItem.embedSubs = embedSubs.isChecked
}
val addChapters = view.findViewById<Chip>(R.id.add_chapters)
addChapters!!.isChecked = addChapters.isChecked
addChapters.setOnClickListener{
downloadItem.addChapters = addChapters.isChecked
}
val saveThumbnail = view.findViewById<Chip>(R.id.save_thumbnail)
saveThumbnail!!.isChecked = saveThumbnail.isChecked
saveThumbnail.setOnClickListener {
downloadItem.SaveThumb = saveThumbnail.isChecked
}
//
// val embedSubs = view.findViewById<Chip>(R.id.embed_subtitles)
// embedSubs!!.isChecked = embedSubs.isChecked
// embedSubs.setOnClickListener {
// downloadItem.embedSubs = embedSubs.isChecked
// }
//
// val addChapters = view.findViewById<Chip>(R.id.add_chapters)
// addChapters!!.isChecked = addChapters.isChecked
// addChapters.setOnClickListener{
// downloadItem.addChapters = addChapters.isChecked
// }
//
// val saveThumbnail = view.findViewById<Chip>(R.id.save_thumbnail)
// saveThumbnail!!.isChecked = saveThumbnail.isChecked
// saveThumbnail.setOnClickListener {
// downloadItem.SaveThumb = saveThumbnail.isChecked
// }
} catch (e: Exception) {
e.printStackTrace()

@ -174,15 +174,15 @@ class DownloadVideoFragment(private val resultItem: ResultItem) : Fragment() {
val embedSubs = view.findViewById<Chip>(R.id.embed_subtitles)
embedSubs!!.isChecked = downloadItem.embedSubs
embedSubs!!.isChecked = downloadItem.videoPreferences.embedSubs
embedSubs.setOnClickListener {
downloadItem.embedSubs = embedSubs.isChecked
downloadItem.videoPreferences.embedSubs = embedSubs.isChecked
}
val addChapters = view.findViewById<Chip>(R.id.add_chapters)
addChapters!!.isChecked = downloadItem.addChapters
addChapters!!.isChecked = downloadItem.videoPreferences.addChapters
addChapters.setOnClickListener{
downloadItem.addChapters = addChapters.isChecked
downloadItem.videoPreferences.addChapters = addChapters.isChecked
}
val saveThumbnail = view.findViewById<Chip>(R.id.save_thumbnail)

@ -24,6 +24,7 @@ class SettingsFragment : PreferenceFragmentCompat() {
private var limitRate: EditTextPreference? = null
private var aria2: SwitchPreferenceCompat? = null
private var sponsorblockFilters: MultiSelectListPreference? = null
private var filenameTemplate: EditTextPreference? = null
private var embedSubtitles: SwitchPreferenceCompat? = null
private var embedThumbnail: SwitchPreferenceCompat? = null
private var addChapters: SwitchPreferenceCompat? = null
@ -62,6 +63,7 @@ class SettingsFragment : PreferenceFragmentCompat() {
aria2 = findPreference("aria2")
sponsorblockFilters = findPreference("sponsorblock_filter")
embedSubtitles = findPreference("embed_subtitles")
filenameTemplate = findPreference("file_name_template")
embedThumbnail = findPreference("embed_thumbnail")
addChapters = findPreference("add_chapters")
writeThumbnail = findPreference("write_thumbnail")
@ -91,6 +93,7 @@ class SettingsFragment : PreferenceFragmentCompat() {
editor.putString("limit_rate", limitRate!!.text)
editor.putBoolean("aria2", aria2!!.isChecked)
editor.putStringSet("sponsorblock_filters", sponsorblockFilters!!.values)
editor.putString("file_name_template", filenameTemplate!!.text)
editor.putBoolean("embed_subtitles", embedSubtitles!!.isChecked)
editor.putBoolean("embed_thumbnail", embedThumbnail!!.isChecked)
editor.putBoolean("add_chapters", addChapters!!.isChecked)
@ -192,6 +195,12 @@ class SettingsFragment : PreferenceFragmentCompat() {
editor.apply()
true
}
filenameTemplate!!.onPreferenceChangeListener =
Preference.OnPreferenceChangeListener { _: Preference?, newValue: Any ->
editor.putString("file_name_template", newValue.toString())
editor.apply()
true
}
embedSubtitles!!.onPreferenceChangeListener =
Preference.OnPreferenceChangeListener { _: Preference?, newValue: Any ->
val embed = newValue as Boolean

@ -525,16 +525,17 @@ class InfoUtil(context: Context) {
}
fun getSearchSuggestions(query: String): ArrayList<String> {
val url = invidousURL + "search/suggestions?q=" + query
val res = genericRequest(url)
val url = "https://suggestqueries.google.com/complete/search?client=youtube&ds=yt&client=firefox&q=$query"
// invidousURL + "search/suggestions?q=" + query
val res = genericArrayRequest(url)
if (res.length() == 0) return ArrayList()
val suggestionList = ArrayList<String>()
try {
val suggestions = res.getJSONArray("suggestions")
for (i in 0 until suggestions.length()) {
suggestionList.add(suggestions.getString(i))
for (i in 0 until res.getJSONArray(1).length()) {
suggestionList.add(res.getJSONArray(1).getString(i))
}
} catch (ignored: Exception) {
ignored.printStackTrace()
}
return suggestionList
}

@ -57,7 +57,9 @@ class UpdateUtil(var context: Context) {
} catch (ignored: JSONException) {
return false
}
if (version == "v" + BuildConfig.VERSION_NAME) {
val versionNameInt = version.split("v")[1].replace(".","").toInt()
val currentVersionNameInt = BuildConfig.VERSION_NAME.replace(".","").toInt()
if (currentVersionNameInt > versionNameInt) {
return false
}
val updateDialog = MaterialAlertDialogBuilder(context)

@ -90,8 +90,7 @@ class DownloadWorker(
}
val limitRate = sharedPreferences.getString("limit_rate", "")
if (limitRate != "") request.addOption("-r", limitRate!!)
val writeThumbnail = sharedPreferences.getBoolean("write_thumbnail", false)
if (writeThumbnail) {
if (downloadItem.SaveThumb) {
request.addOption("--write-thumbnail")
request.addOption("--convert-thumbnails", "png")
}
@ -108,6 +107,8 @@ class DownloadWorker(
if (downloadItem.author.isNotEmpty()){
request.addCommands(listOf("--replace-in-metadata","uploader",".*.",downloadItem.author));
}
if (downloadItem.customFileNameTemplate.isEmpty()) downloadItem.customFileNameTemplate = "%(uploader)s - %(title)s"
when(type){
DownloadViewModel.Type.audio -> {
@ -124,8 +125,7 @@ class DownloadWorker(
}
request.addOption("--embed-metadata")
val embedThumb = sharedPreferences.getBoolean("embed_thumbnail", false)
if (embedThumb) {
if (downloadItem.audioPreferences.embedThumb) {
request.addOption("--embed-thumbnail")
request.addOption("--convert-thumbnails", "png")
try {
@ -137,8 +137,6 @@ class DownloadWorker(
} catch (ignored: Exception) {}
}
request.addOption("--parse-metadata", "%(release_year,upload_date)s:%(meta_date)s")
request.addCommands(listOf("--replace-in-metadata", "title", ".*.", downloadItem.title))
request.addCommands(listOf("--replace-in-metadata", "uploader", ".*.", downloadItem.author))
if (downloadItem.playlistTitle.isNotEmpty()) {
request.addOption("--parse-metadata", "%(album,playlist,title)s:%(meta_album)s")
@ -146,15 +144,13 @@ class DownloadWorker(
} else {
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 + "/${downloadItem.customFileNameTemplate}.%(ext)s")
}
DownloadViewModel.Type.video -> {
val addChapters = sharedPreferences.getBoolean("add_chapters", false)
if (addChapters) {
if (downloadItem.videoPreferences.addChapters) {
request.addOption("--sponsorblock-mark", "all")
}
val embedSubs = sharedPreferences.getBoolean("embed_subtitles", false)
if (embedSubs) {
if (downloadItem.videoPreferences.embedSubs) {
request.addOption("--embed-subs", "")
}
val defaultFormats = context.resources.getStringArray(R.array.video_formats)
@ -180,7 +176,7 @@ class DownloadWorker(
request.addOption("--embed-thumbnail")
}
}
request.addOption("-o", tempFileDir.absolutePath + "/%(uploader)s - %(title)s.%(ext)s")
request.addOption("-o", tempFileDir.absolutePath + "/${downloadItem.customFileNameTemplate}.%(ext)s")
}
DownloadViewModel.Type.command -> {
val commandRegex = "\"([^\"]*)\"|(\\S+)"

@ -0,0 +1,5 @@
<vector android:height="24dp"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="?android:colorAccent" android:pathData="M5,17v2h14v-2L5,17zM9.5,12.8h5l0.9,2.2h2.1L12.75,4h-1.5L6.5,15h2.1l0.9,-2.2zM12,5.98L13.87,11h-3.74L12,5.98z"/>
</vector>

@ -156,7 +156,45 @@
</com.google.android.material.textfield.TextInputLayout>
<LinearLayout
android:id="@+id/adjust_audio"
android:layout_width="match_parent"
android:padding="10dp"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<TextView
android:layout_width="wrap_content"
android:paddingBottom="5dp"
android:textSize="15sp"
android:layout_height="wrap_content"
android:text="@string/adjust_audio" />
<HorizontalScrollView
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<com.google.android.material.chip.ChipGroup
android:id="@+id/chipGroup"
android:layout_width="wrap_content"
app:singleLine="false"
android:layout_height="wrap_content">
<com.google.android.material.chip.Chip
android:id="@+id/embed_thumb"
style="@style/Widget.Material3.Chip.Filter.Elevated"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="false"
android:text="@string/embed_thumb"/>
</com.google.android.material.chip.ChipGroup>
</HorizontalScrollView>
</LinearLayout>
</LinearLayout>

@ -77,7 +77,6 @@
<string name="remove_non_music">Remove non-music parts</string>
<string name="remove_non_music_summary">Strips non-music parts of audio files with SponsorBlock</string>
<string name="processing">Processing</string>
<string name="embed_subs">Subtitles in Videos</string>
<string name="embed_subs_summary">Adds subtitles in the video</string>
<string name="embed_thumb">Thumbnail Covers</string>
<string name="embed_thumb_summary">Uses the thumbnail as cover art</string>
@ -167,4 +166,6 @@
<string name="commands">Commands</string>
<string name="date_added">Date added</string>
<string name="update_ytdl_nightly">Download Nightly Version of yt-dlp</string>
<string name="adjust_audio">Adjust Audio</string>
<string name="file_name_template">Filename Template</string>
</resources>

@ -63,7 +63,6 @@
app:key="concurrent_downloads"
app:min="1"
app:showSeekBarValue="true"
android:dependency="aria2"
app:summary="@string/concurrent_downloads_summary"
app:title="@string/concurrent_downloads" />
@ -95,12 +94,18 @@
app:summary="@string/select_sponsorblock_filtering"
app:title="SponsorBlock" />
<EditTextPreference
android:icon="@drawable/ic_textformat"
app:key="file_name_template"
app:defaultValue="%(uploader)s - %(title)s"
app:title="@string/file_name_template" />
<SwitchPreferenceCompat
app:defaultValue="true"
app:icon="@drawable/ic_subtitles"
app:key="embed_subtitles"
app:summary="@string/embed_subs_summary"
app:title="@string/embed_subs" />
app:title="@string/embed_subtitles" />
<SwitchPreferenceCompat
app:defaultValue="true"

Loading…
Cancel
Save