mirror of
https://github.com/Shabinder/SpotiFlyer.git
synced 2024-11-22 09:04:32 +01:00
Freezing Fixes, Database Adding in Background.
This commit is contained in:
parent
d8415b52ca
commit
7a3a299aa2
@ -17,6 +17,7 @@
|
|||||||
package com.shabinder.common.di
|
package com.shabinder.common.di
|
||||||
|
|
||||||
import co.touchlab.kermit.Kermit
|
import co.touchlab.kermit.Kermit
|
||||||
|
import co.touchlab.stately.ensureNeverFrozen
|
||||||
import com.shabinder.common.database.databaseModule
|
import com.shabinder.common.database.databaseModule
|
||||||
import com.shabinder.common.database.getLogger
|
import com.shabinder.common.database.getLogger
|
||||||
import com.shabinder.common.di.providers.GaanaProvider
|
import com.shabinder.common.di.providers.GaanaProvider
|
||||||
@ -37,6 +38,7 @@ import org.koin.core.context.startKoin
|
|||||||
import org.koin.dsl.KoinAppDeclaration
|
import org.koin.dsl.KoinAppDeclaration
|
||||||
import org.koin.dsl.module
|
import org.koin.dsl.module
|
||||||
import kotlin.native.concurrent.SharedImmutable
|
import kotlin.native.concurrent.SharedImmutable
|
||||||
|
import kotlin.native.concurrent.ThreadLocal
|
||||||
|
|
||||||
fun initKoin(enableNetworkLogs: Boolean = false, appDeclaration: KoinAppDeclaration = {}) =
|
fun initKoin(enableNetworkLogs: Boolean = false, appDeclaration: KoinAppDeclaration = {}) =
|
||||||
startKoin {
|
startKoin {
|
||||||
@ -60,7 +62,7 @@ fun commonModule(enableNetworkLogs: Boolean) = module {
|
|||||||
single { FetchPlatformQueryResult(get(), get(), get(), get(), get(), get()) }
|
single { FetchPlatformQueryResult(get(), get(), get(), get(), get(), get()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@SharedImmutable
|
@ThreadLocal
|
||||||
val kotlinxSerializer = KotlinxSerializer(
|
val kotlinxSerializer = KotlinxSerializer(
|
||||||
Json {
|
Json {
|
||||||
isLenient = true
|
isLenient = true
|
||||||
@ -68,10 +70,16 @@ val kotlinxSerializer = KotlinxSerializer(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
fun createHttpClient(enableNetworkLogs: Boolean = false, serializer: KotlinxSerializer = kotlinxSerializer) = HttpClient {
|
fun createHttpClient(enableNetworkLogs: Boolean = false) = HttpClient {
|
||||||
install(JsonFeature) {
|
// https://github.com/Kotlin/kotlinx.serialization/issues/1450
|
||||||
this.serializer = serializer
|
/*install(JsonFeature) {
|
||||||
}
|
serializer = KotlinxSerializer(
|
||||||
|
Json {
|
||||||
|
isLenient = true
|
||||||
|
ignoreUnknownKeys = true
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}*/
|
||||||
// Timeout
|
// Timeout
|
||||||
install(HttpTimeout) {
|
install(HttpTimeout) {
|
||||||
requestTimeoutMillis = 15000L
|
requestTimeoutMillis = 15000L
|
||||||
|
@ -43,7 +43,7 @@ expect val currentPlatform: AllPlatforms
|
|||||||
suspend fun isInternetAccessible(): Boolean {
|
suspend fun isInternetAccessible(): Boolean {
|
||||||
return withContext(dispatcherIO) {
|
return withContext(dispatcherIO) {
|
||||||
try {
|
try {
|
||||||
ktorHttpClient.head<String>("http://google.com")
|
ktorHttpClient.head<String>("https://google.com")
|
||||||
true
|
true
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
|
@ -23,6 +23,10 @@ import com.shabinder.common.di.providers.YoutubeMp3
|
|||||||
import com.shabinder.common.di.providers.YoutubeMusic
|
import com.shabinder.common.di.providers.YoutubeMusic
|
||||||
import com.shabinder.common.models.PlatformQueryResult
|
import com.shabinder.common.models.PlatformQueryResult
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.GlobalScope
|
||||||
|
import kotlinx.coroutines.async
|
||||||
|
import kotlinx.coroutines.coroutineScope
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
class FetchPlatformQueryResult(
|
class FetchPlatformQueryResult(
|
||||||
@ -54,13 +58,19 @@ class FetchPlatformQueryResult(
|
|||||||
null
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result?.run {
|
if (result != null) {
|
||||||
withContext(Dispatchers.Default) {
|
addToDatabaseAsync(
|
||||||
db?.add(
|
link,
|
||||||
folderType, title, link, coverUrl, trackList.size.toLong()
|
result.copy() // Send a copy in order to not to freeze Result itself
|
||||||
)
|
)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
private fun addToDatabaseAsync(link: String, result: PlatformQueryResult) {
|
||||||
|
GlobalScope.launch(dispatcherIO) {
|
||||||
|
db?.add(
|
||||||
|
result.folderType, result.title, link, result.coverUrl, result.trackList.size.toLong()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
package com.shabinder.common.di.gaana
|
package com.shabinder.common.di.gaana
|
||||||
|
|
||||||
import com.shabinder.common.di.currentPlatform
|
import com.shabinder.common.di.currentPlatform
|
||||||
|
import com.shabinder.common.di.utils.getData
|
||||||
import com.shabinder.common.models.AllPlatforms
|
import com.shabinder.common.models.AllPlatforms
|
||||||
import com.shabinder.common.models.corsProxy
|
import com.shabinder.common.models.corsProxy
|
||||||
import com.shabinder.common.models.gaana.GaanaAlbum
|
import com.shabinder.common.models.gaana.GaanaAlbum
|
||||||
@ -52,7 +53,7 @@ interface GaanaRequests {
|
|||||||
format: String = "JSON",
|
format: String = "JSON",
|
||||||
limit: Int = 2000
|
limit: Int = 2000
|
||||||
): GaanaPlaylist {
|
): GaanaPlaylist {
|
||||||
return httpClient.get(
|
return httpClient.getData(
|
||||||
"$BASE_URL/?type=$type&subtype=$subtype&seokey=$seokey&token=$TOKEN&format=$format&limit=$limit"
|
"$BASE_URL/?type=$type&subtype=$subtype&seokey=$seokey&token=$TOKEN&format=$format&limit=$limit"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -69,7 +70,7 @@ interface GaanaRequests {
|
|||||||
format: String = "JSON",
|
format: String = "JSON",
|
||||||
limit: Int = 2000
|
limit: Int = 2000
|
||||||
): GaanaAlbum {
|
): GaanaAlbum {
|
||||||
return httpClient.get(
|
return httpClient.getData(
|
||||||
"$BASE_URL/?type=$type&subtype=$subtype&seokey=$seokey&token=$TOKEN&format=$format&limit=$limit"
|
"$BASE_URL/?type=$type&subtype=$subtype&seokey=$seokey&token=$TOKEN&format=$format&limit=$limit"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -85,7 +86,7 @@ interface GaanaRequests {
|
|||||||
seokey: String,
|
seokey: String,
|
||||||
format: String = "JSON",
|
format: String = "JSON",
|
||||||
): GaanaSong {
|
): GaanaSong {
|
||||||
return httpClient.get(
|
return httpClient.getData(
|
||||||
"$BASE_URL/?type=$type&subtype=$subtype&seokey=$seokey&token=$TOKEN&format=$format"
|
"$BASE_URL/?type=$type&subtype=$subtype&seokey=$seokey&token=$TOKEN&format=$format"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -101,7 +102,7 @@ interface GaanaRequests {
|
|||||||
seokey: String,
|
seokey: String,
|
||||||
format: String = "JSON",
|
format: String = "JSON",
|
||||||
): GaanaArtistDetails {
|
): GaanaArtistDetails {
|
||||||
return httpClient.get(
|
return httpClient.getData(
|
||||||
"$BASE_URL/?type=$type&subtype=$subtype&seokey=$seokey&token=$TOKEN&format=$format"
|
"$BASE_URL/?type=$type&subtype=$subtype&seokey=$seokey&token=$TOKEN&format=$format"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -118,7 +119,7 @@ interface GaanaRequests {
|
|||||||
format: String = "JSON",
|
format: String = "JSON",
|
||||||
limit: Int = 50
|
limit: Int = 50
|
||||||
): GaanaArtistTracks {
|
): GaanaArtistTracks {
|
||||||
return httpClient.get(
|
return httpClient.getData(
|
||||||
"$BASE_URL/?type=$type&subtype=$subtype&seokey=$seokey&token=$TOKEN&format=$format&limit=$limit"
|
"$BASE_URL/?type=$type&subtype=$subtype&seokey=$seokey&token=$TOKEN&format=$format&limit=$limit"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -79,7 +79,7 @@ class GaanaProvider(
|
|||||||
it.updateStatusIfPresent(folderType, subFolder)
|
it.updateStatusIfPresent(folderType, subFolder)
|
||||||
trackList = listOf(it).toTrackDetailsList(folderType, subFolder)
|
trackList = listOf(it).toTrackDetailsList(folderType, subFolder)
|
||||||
title = it.track_title
|
title = it.track_title
|
||||||
coverUrl = it.artworkLink
|
coverUrl = it.artworkLink.replace("http:","https:")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"album" -> {
|
"album" -> {
|
||||||
@ -91,7 +91,7 @@ class GaanaProvider(
|
|||||||
}
|
}
|
||||||
trackList = it.tracks?.toTrackDetailsList(folderType, subFolder) ?: emptyList()
|
trackList = it.tracks?.toTrackDetailsList(folderType, subFolder) ?: emptyList()
|
||||||
title = link
|
title = link
|
||||||
coverUrl = it.custom_artworks.size_480p
|
coverUrl = it.custom_artworks.size_480p.replace("http:","https:")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"playlist" -> {
|
"playlist" -> {
|
||||||
@ -114,7 +114,7 @@ class GaanaProvider(
|
|||||||
getGaanaArtistDetails(seokey = link).artist.firstOrNull()
|
getGaanaArtistDetails(seokey = link).artist.firstOrNull()
|
||||||
?.also {
|
?.also {
|
||||||
title = it.name
|
title = it.name
|
||||||
coverUrl = it.artworkLink ?: gaanaPlaceholderImageUrl
|
coverUrl = it.artworkLink?.replace("http:","https:") ?: gaanaPlaceholderImageUrl
|
||||||
}
|
}
|
||||||
getGaanaArtistTracks(seokey = link).also {
|
getGaanaArtistTracks(seokey = link).also {
|
||||||
it.tracks?.forEach { track ->
|
it.tracks?.forEach { track ->
|
||||||
@ -143,7 +143,7 @@ class GaanaProvider(
|
|||||||
trackUrl = it.lyrics_url,
|
trackUrl = it.lyrics_url,
|
||||||
downloaded = it.downloaded ?: DownloadStatus.NotDownloaded,
|
downloaded = it.downloaded ?: DownloadStatus.NotDownloaded,
|
||||||
source = Source.Gaana,
|
source = Source.Gaana,
|
||||||
albumArtURL = it.artworkLink,
|
albumArtURL = it.artworkLink.replace("http:","https:"),
|
||||||
outputFilePath = dir.finalOutputDir(it.track_title, type, subFolder, dir.defaultDir()/*,".m4a"*/)
|
outputFilePath = dir.finalOutputDir(it.track_title, type, subFolder, dir.defaultDir()/*,".m4a"*/)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -17,9 +17,11 @@
|
|||||||
package com.shabinder.common.di.providers
|
package com.shabinder.common.di.providers
|
||||||
|
|
||||||
import co.touchlab.kermit.Kermit
|
import co.touchlab.kermit.Kermit
|
||||||
|
import co.touchlab.stately.ensureNeverFrozen
|
||||||
import co.touchlab.stately.freeze
|
import co.touchlab.stately.freeze
|
||||||
import com.shabinder.common.di.Dir
|
import com.shabinder.common.di.Dir
|
||||||
import com.shabinder.common.di.TokenStore
|
import com.shabinder.common.di.TokenStore
|
||||||
|
import com.shabinder.common.di.createHttpClient
|
||||||
import com.shabinder.common.di.finalOutputDir
|
import com.shabinder.common.di.finalOutputDir
|
||||||
import com.shabinder.common.di.kotlinxSerializer
|
import com.shabinder.common.di.kotlinxSerializer
|
||||||
import com.shabinder.common.di.ktorHttpClient
|
import com.shabinder.common.di.ktorHttpClient
|
||||||
@ -33,9 +35,12 @@ import com.shabinder.common.models.spotify.Image
|
|||||||
import com.shabinder.common.models.spotify.Source
|
import com.shabinder.common.models.spotify.Source
|
||||||
import com.shabinder.common.models.spotify.Track
|
import com.shabinder.common.models.spotify.Track
|
||||||
import io.ktor.client.HttpClient
|
import io.ktor.client.HttpClient
|
||||||
|
import io.ktor.client.features.auth.*
|
||||||
|
import io.ktor.client.features.auth.providers.*
|
||||||
import io.ktor.client.features.defaultRequest
|
import io.ktor.client.features.defaultRequest
|
||||||
import io.ktor.client.features.json.JsonFeature
|
import io.ktor.client.features.json.JsonFeature
|
||||||
import io.ktor.client.request.header
|
import io.ktor.client.request.header
|
||||||
|
import kotlin.native.concurrent.SharedImmutable
|
||||||
|
|
||||||
class SpotifyProvider(
|
class SpotifyProvider(
|
||||||
private val tokenStore: TokenStore,
|
private val tokenStore: TokenStore,
|
||||||
@ -62,14 +67,14 @@ class SpotifyProvider(
|
|||||||
defaultRequest {
|
defaultRequest {
|
||||||
header("Authorization", "Bearer ${token.access_token}")
|
header("Authorization", "Bearer ${token.access_token}")
|
||||||
}
|
}
|
||||||
install(JsonFeature) {
|
/*install(JsonFeature) {
|
||||||
serializer = kotlinxSerializer
|
serializer = kotlinxSerializer
|
||||||
}
|
}*/
|
||||||
}.also { httpClientRef.value = it.freeze() }
|
}.also { httpClientRef.value = it }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override val httpClientRef = NativeAtomicReference(ktorHttpClient)
|
override val httpClientRef = NativeAtomicReference(createHttpClient(true))
|
||||||
|
|
||||||
suspend fun query(fullLink: String): PlatformQueryResult? {
|
suspend fun query(fullLink: String): PlatformQueryResult? {
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@ package com.shabinder.common.di.providers
|
|||||||
|
|
||||||
import co.touchlab.kermit.Kermit
|
import co.touchlab.kermit.Kermit
|
||||||
import com.shabinder.common.di.gaana.corsApi
|
import com.shabinder.common.di.gaana.corsApi
|
||||||
|
import com.shabinder.common.di.utils.postData
|
||||||
import com.shabinder.common.models.TrackDetails
|
import com.shabinder.common.models.TrackDetails
|
||||||
import com.shabinder.common.models.YoutubeTrack
|
import com.shabinder.common.models.YoutubeTrack
|
||||||
import com.shabinder.fuzzywuzzy.diffutils.FuzzySearch
|
import com.shabinder.fuzzywuzzy.diffutils.FuzzySearch
|
||||||
@ -283,7 +284,7 @@ class YoutubeMusic constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun getYoutubeMusicResponse(query: String): String {
|
private suspend fun getYoutubeMusicResponse(query: String): String {
|
||||||
return httpClient.post("${corsApi}https://music.youtube.com/youtubei/v1/search?alt=json&key=$apiKey") {
|
return httpClient.postData("${corsApi}https://music.youtube.com/youtubei/v1/search?alt=json&key=$apiKey") {
|
||||||
contentType(ContentType.Application.Json)
|
contentType(ContentType.Application.Json)
|
||||||
headers {
|
headers {
|
||||||
append("referer", "https://music.youtube.com/search")
|
append("referer", "https://music.youtube.com/search")
|
||||||
|
@ -17,25 +17,33 @@
|
|||||||
package com.shabinder.common.di.spotify
|
package com.shabinder.common.di.spotify
|
||||||
|
|
||||||
import com.shabinder.common.di.gaana.corsApi
|
import com.shabinder.common.di.gaana.corsApi
|
||||||
|
import com.shabinder.common.di.utils.getData
|
||||||
import com.shabinder.common.models.NativeAtomicReference
|
import com.shabinder.common.models.NativeAtomicReference
|
||||||
import com.shabinder.common.models.spotify.Album
|
import com.shabinder.common.models.spotify.Album
|
||||||
import com.shabinder.common.models.spotify.PagingObjectPlaylistTrack
|
import com.shabinder.common.models.spotify.PagingObjectPlaylistTrack
|
||||||
import com.shabinder.common.models.spotify.Playlist
|
import com.shabinder.common.models.spotify.Playlist
|
||||||
import com.shabinder.common.models.spotify.Track
|
import com.shabinder.common.models.spotify.Track
|
||||||
import io.ktor.client.HttpClient
|
import io.ktor.client.HttpClient
|
||||||
import io.ktor.client.request.get
|
import io.ktor.client.request.*
|
||||||
|
import io.ktor.client.statement.*
|
||||||
|
import io.ktor.http.*
|
||||||
|
import kotlinx.serialization.DeserializationStrategy
|
||||||
|
import kotlinx.serialization.InternalSerializationApi
|
||||||
|
import kotlinx.serialization.descriptors.ClassSerialDescriptorBuilder
|
||||||
|
import kotlinx.serialization.json.Json
|
||||||
|
import kotlinx.serialization.serializer
|
||||||
|
|
||||||
private val BASE_URL get() = "${corsApi}https://api.spotify.com/v1"
|
private val BASE_URL get() = "${corsApi}https://api.spotify.com/v1"
|
||||||
|
|
||||||
interface SpotifyRequests {
|
interface SpotifyRequests {
|
||||||
|
|
||||||
val httpClientRef: NativeAtomicReference<HttpClient>
|
val httpClientRef: NativeAtomicReference<HttpClient>
|
||||||
val httpClient get() = httpClientRef.value
|
val httpClient:HttpClient get() = httpClientRef.value
|
||||||
|
|
||||||
suspend fun authenticateSpotifyClient(override: Boolean = false)
|
suspend fun authenticateSpotifyClient(override: Boolean = false)
|
||||||
|
|
||||||
suspend fun getPlaylist(playlistID: String): Playlist {
|
suspend fun getPlaylist(playlistID: String): Playlist {
|
||||||
return httpClient.get("$BASE_URL/playlists/$playlistID")
|
return httpClient.getData("$BASE_URL/playlists/$playlistID")
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun getPlaylistTracks(
|
suspend fun getPlaylistTracks(
|
||||||
@ -43,26 +51,26 @@ interface SpotifyRequests {
|
|||||||
offset: Int = 0,
|
offset: Int = 0,
|
||||||
limit: Int = 100
|
limit: Int = 100
|
||||||
): PagingObjectPlaylistTrack {
|
): PagingObjectPlaylistTrack {
|
||||||
return httpClient.get("$BASE_URL/playlists/$playlistID/tracks?offset=$offset&limit=$limit")
|
return httpClient.getData("$BASE_URL/playlists/$playlistID/tracks?offset=$offset&limit=$limit")
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun getTrack(id: String?): Track {
|
suspend fun getTrack(id: String?): Track {
|
||||||
return httpClient.get("$BASE_URL/tracks/$id")
|
return httpClient.getData("$BASE_URL/tracks/$id")
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun getEpisode(id: String?): Track {
|
suspend fun getEpisode(id: String?): Track {
|
||||||
return httpClient.get("$BASE_URL/episodes/$id")
|
return httpClient.getData("$BASE_URL/episodes/$id")
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun getShow(id: String?): Track {
|
suspend fun getShow(id: String?): Track {
|
||||||
return httpClient.get("$BASE_URL/shows/$id")
|
return httpClient.getData("$BASE_URL/shows/$id")
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun getAlbum(id: String): Album {
|
suspend fun getAlbum(id: String): Album {
|
||||||
return httpClient.get("$BASE_URL/albums/$id")
|
return httpClient.getData("$BASE_URL/albums/$id")
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun getResponse(url: String): String {
|
suspend fun getResponse(url: String): String {
|
||||||
return httpClient.get(url)
|
return httpClient.getData(url)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,51 @@
|
|||||||
|
|
||||||
package com.shabinder.common.di.utils
|
package com.shabinder.common.di.utils
|
||||||
|
|
||||||
|
import io.ktor.client.*
|
||||||
|
import io.ktor.client.request.*
|
||||||
|
import io.ktor.client.statement.*
|
||||||
|
import io.ktor.http.*
|
||||||
|
import kotlinx.serialization.InternalSerializationApi
|
||||||
|
import kotlinx.serialization.json.Json
|
||||||
|
import kotlinx.serialization.serializer
|
||||||
|
import kotlin.native.concurrent.SharedImmutable
|
||||||
|
import kotlin.native.concurrent.ThreadLocal
|
||||||
|
|
||||||
|
/*
|
||||||
|
* WorkAround: https://github.com/Kotlin/kotlinx.serialization/issues/1450
|
||||||
|
* */
|
||||||
|
@OptIn(InternalSerializationApi::class)
|
||||||
|
suspend inline fun <reified T: Any> HttpClient.getData(
|
||||||
|
urlString: String,
|
||||||
|
block: HttpRequestBuilder.() -> Unit = {}
|
||||||
|
): T {
|
||||||
|
val response = get<HttpResponse> {
|
||||||
|
url.takeFrom(urlString)
|
||||||
|
block()
|
||||||
|
}
|
||||||
|
val jsonBody = response.readText()
|
||||||
|
return json.decodeFromString(T::class.serializer(),jsonBody)
|
||||||
|
}
|
||||||
|
|
||||||
|
@OptIn(InternalSerializationApi::class)
|
||||||
|
suspend inline fun <reified T: Any> HttpClient.postData(
|
||||||
|
urlString: String,
|
||||||
|
block: HttpRequestBuilder.() -> Unit = {}
|
||||||
|
): T {
|
||||||
|
val response = post<HttpResponse> {
|
||||||
|
url.takeFrom(urlString)
|
||||||
|
block()
|
||||||
|
}
|
||||||
|
val jsonBody = response.readText()
|
||||||
|
return json.decodeFromString(T::class.serializer(),jsonBody)
|
||||||
|
}
|
||||||
|
|
||||||
|
@ThreadLocal
|
||||||
|
val json by lazy { Json {
|
||||||
|
isLenient = true
|
||||||
|
ignoreUnknownKeys = true
|
||||||
|
} }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removing Illegal Chars from File Name
|
* Removing Illegal Chars from File Name
|
||||||
* **/
|
* **/
|
||||||
|
@ -18,6 +18,7 @@ package com.shabinder.common.di.youtubeMp3
|
|||||||
|
|
||||||
import co.touchlab.kermit.Kermit
|
import co.touchlab.kermit.Kermit
|
||||||
import com.shabinder.common.di.gaana.corsApi
|
import com.shabinder.common.di.gaana.corsApi
|
||||||
|
import com.shabinder.common.di.utils.postData
|
||||||
import io.ktor.client.HttpClient
|
import io.ktor.client.HttpClient
|
||||||
import io.ktor.client.request.forms.FormDataContent
|
import io.ktor.client.request.forms.FormDataContent
|
||||||
import io.ktor.client.request.post
|
import io.ktor.client.request.post
|
||||||
@ -44,7 +45,7 @@ interface Yt1sMp3 {
|
|||||||
* Body Form= q:yt video link ,vt:format=mp3
|
* Body Form= q:yt video link ,vt:format=mp3
|
||||||
* */
|
* */
|
||||||
private suspend fun getKey(videoID: String): String {
|
private suspend fun getKey(videoID: String): String {
|
||||||
val response: JsonObject? = httpClient.post("${corsApi}https://yt1s.com/api/ajaxSearch/index") {
|
val response: JsonObject? = httpClient.postData("${corsApi}https://yt1s.com/api/ajaxSearch/index") {
|
||||||
body = FormDataContent(
|
body = FormDataContent(
|
||||||
Parameters.build {
|
Parameters.build {
|
||||||
append("q", "https://www.youtube.com/watch?v=$videoID")
|
append("q", "https://www.youtube.com/watch?v=$videoID")
|
||||||
@ -56,7 +57,7 @@ interface Yt1sMp3 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun getConvertedMp3Link(videoID: String, key: String): JsonObject? {
|
private suspend fun getConvertedMp3Link(videoID: String, key: String): JsonObject? {
|
||||||
return httpClient.post("${corsApi}https://yt1s.com/api/ajaxConvert/convert") {
|
return httpClient.postData("${corsApi}https://yt1s.com/api/ajaxConvert/convert") {
|
||||||
body = FormDataContent(
|
body = FormDataContent(
|
||||||
Parameters.build {
|
Parameters.build {
|
||||||
append("vid", videoID)
|
append("vid", videoID)
|
||||||
|
@ -31,18 +31,16 @@ actual class Dir actual constructor(
|
|||||||
actual fun fileSeparator(): String = "/"
|
actual fun fileSeparator(): String = "/"
|
||||||
|
|
||||||
// TODO Error Handling
|
// TODO Error Handling
|
||||||
actual fun defaultDir(): String = defaultDirURL.path!!
|
actual fun defaultDir(): String = defaultDirURL.path!! + fileSeparator()
|
||||||
|
|
||||||
val defaultDirURL: NSURL by lazy {
|
private val defaultDirURL: NSURL by lazy {
|
||||||
createDirectories()
|
|
||||||
val musicDir = NSFileManager.defaultManager.URLForDirectory(NSMusicDirectory, NSUserDomainMask,null,true,null)!!
|
val musicDir = NSFileManager.defaultManager.URLForDirectory(NSMusicDirectory, NSUserDomainMask,null,true,null)!!
|
||||||
musicDir.URLByAppendingPathComponent("SpotiFlyer",true)!!
|
musicDir.URLByAppendingPathComponent("SpotiFlyer",true)!!
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun imageCacheDir(): String = imageCacheURL.path!!
|
actual fun imageCacheDir(): String = imageCacheURL.path!! + fileSeparator()
|
||||||
|
|
||||||
val imageCacheURL: NSURL by lazy {
|
private val imageCacheURL: NSURL by lazy {
|
||||||
createDirectories()
|
|
||||||
val cacheDir = NSFileManager.defaultManager.URLForDirectory(NSCachesDirectory, NSUserDomainMask,null,true,null)
|
val cacheDir = NSFileManager.defaultManager.URLForDirectory(NSCachesDirectory, NSUserDomainMask,null,true,null)
|
||||||
cacheDir?.URLByAppendingPathComponent("SpotiFlyer",true)!!
|
cacheDir?.URLByAppendingPathComponent("SpotiFlyer",true)!!
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@ import com.arkivanov.mvikotlin.extensions.coroutines.SuspendExecutor
|
|||||||
import com.shabinder.common.database.getLogger
|
import com.shabinder.common.database.getLogger
|
||||||
import com.shabinder.common.di.Dir
|
import com.shabinder.common.di.Dir
|
||||||
import com.shabinder.common.di.FetchPlatformQueryResult
|
import com.shabinder.common.di.FetchPlatformQueryResult
|
||||||
|
import com.shabinder.common.di.dispatcherIO
|
||||||
import com.shabinder.common.di.downloadTracks
|
import com.shabinder.common.di.downloadTracks
|
||||||
import com.shabinder.common.list.SpotiFlyerList.State
|
import com.shabinder.common.list.SpotiFlyerList.State
|
||||||
import com.shabinder.common.list.store.SpotiFlyerListStore.Intent
|
import com.shabinder.common.list.store.SpotiFlyerListStore.Intent
|
||||||
@ -33,6 +34,7 @@ import com.shabinder.common.models.TrackDetails
|
|||||||
import com.shabinder.common.models.methods
|
import com.shabinder.common.models.methods
|
||||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||||
import kotlinx.coroutines.flow.collectLatest
|
import kotlinx.coroutines.flow.collectLatest
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
internal class SpotiFlyerListStoreProvider(
|
internal class SpotiFlyerListStoreProvider(
|
||||||
private val dir: Dir,
|
private val dir: Dir,
|
||||||
@ -85,6 +87,7 @@ internal class SpotiFlyerListStoreProvider(
|
|||||||
throw Exception("An Error Occurred, Check your Link / Connection")
|
throw Exception("An Error Occurred, Check your Link / Connection")
|
||||||
}
|
}
|
||||||
} catch (e:Exception) {
|
} catch (e:Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
dispatch(Result.ErrorOccurred(e))
|
dispatch(Result.ErrorOccurred(e))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit f218336b5b31b365bbf34503b79f2c4f2b703d7d
|
Subproject commit 41c6aca4938d13cc7364b1200bf6987c852dfdc2
|
Loading…
Reference in New Issue
Block a user