mirror of
https://github.com/Shabinder/SpotiFlyer.git
synced 2024-11-22 01:04:31 +01:00
Desktop Analytics, CORS Fixes , Deps Update
This commit is contained in:
parent
cab7213c0e
commit
477536981f
@ -79,8 +79,7 @@ class MainActivity : ComponentActivity() {
|
|||||||
private val fetcher: FetchPlatformQueryResult by inject()
|
private val fetcher: FetchPlatformQueryResult by inject()
|
||||||
private val dir: Dir by inject()
|
private val dir: Dir by inject()
|
||||||
private lateinit var root: SpotiFlyerRoot
|
private lateinit var root: SpotiFlyerRoot
|
||||||
private val callBacks: SpotiFlyerRootCallBacks
|
private val callBacks: SpotiFlyerRootCallBacks get() = root.callBacks
|
||||||
get() = root.callBacks
|
|
||||||
private val trackStatusFlow = MutableSharedFlow<HashMap<String, DownloadStatus>>(1)
|
private val trackStatusFlow = MutableSharedFlow<HashMap<String, DownloadStatus>>(1)
|
||||||
private var permissionGranted = mutableStateOf(true)
|
private var permissionGranted = mutableStateOf(true)
|
||||||
private lateinit var updateUIReceiver: BroadcastReceiver
|
private lateinit var updateUIReceiver: BroadcastReceiver
|
||||||
|
@ -35,7 +35,7 @@ object Versions {
|
|||||||
const val kermit = "0.1.9"
|
const val kermit = "0.1.9"
|
||||||
|
|
||||||
// Internet
|
// Internet
|
||||||
const val ktor = "1.5.4"
|
const val ktor = "1.6.0"
|
||||||
|
|
||||||
const val kotlinxSerialization = "1.2.1"
|
const val kotlinxSerialization = "1.2.1"
|
||||||
|
|
||||||
@ -135,7 +135,7 @@ object Ktor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
object Extras {
|
object Extras {
|
||||||
const val youtubeDownloader = "io.github.shabinder:youtube-api-dl:1.0"
|
const val youtubeDownloader = "io.github.shabinder:youtube-api-dl:1.2"
|
||||||
const val fuzzyWuzzy = "io.github.shabinder:fuzzywuzzy:1.1"
|
const val fuzzyWuzzy = "io.github.shabinder:fuzzywuzzy:1.1"
|
||||||
const val mp3agic = "com.mpatric:mp3agic:0.9.0"
|
const val mp3agic = "com.mpatric:mp3agic:0.9.0"
|
||||||
const val jaudioTagger = "com.github.Shabinder:JAudioTagger-Android:1.0"
|
const val jaudioTagger = "com.github.Shabinder:JAudioTagger-Android:1.0"
|
||||||
|
@ -31,8 +31,8 @@ kotlin {
|
|||||||
implementation(project(":common:data-models"))
|
implementation(project(":common:data-models"))
|
||||||
implementation(project(":common:database"))
|
implementation(project(":common:database"))
|
||||||
implementation("org.jetbrains.kotlinx:atomicfu:0.16.1")
|
implementation("org.jetbrains.kotlinx:atomicfu:0.16.1")
|
||||||
implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.2.0")
|
implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.2.1")
|
||||||
implementation("com.russhwolf:multiplatform-settings-no-arg:0.7.6")
|
implementation("com.russhwolf:multiplatform-settings-no-arg:0.7.7")
|
||||||
implementation(Extras.youtubeDownloader)
|
implementation(Extras.youtubeDownloader)
|
||||||
implementation(Extras.fuzzyWuzzy)
|
implementation(Extras.fuzzyWuzzy)
|
||||||
implementation(MVIKotlin.rx)
|
implementation(MVIKotlin.rx)
|
||||||
|
@ -78,7 +78,11 @@ fun createHttpClient(enableNetworkLogs: Boolean = false) = HttpClient {
|
|||||||
install(JsonFeature) {
|
install(JsonFeature) {
|
||||||
serializer = KotlinxSerializer(globalJson)
|
serializer = KotlinxSerializer(globalJson)
|
||||||
}
|
}
|
||||||
install(HttpTimeout)
|
install(HttpTimeout) {
|
||||||
|
socketTimeoutMillis = 520_000
|
||||||
|
requestTimeoutMillis = 360_000
|
||||||
|
connectTimeoutMillis = 360_000
|
||||||
|
}
|
||||||
// WorkAround for Freezing
|
// WorkAround for Freezing
|
||||||
// Use httpClient.getData / httpClient.postData Extensions
|
// Use httpClient.getData / httpClient.postData Extensions
|
||||||
/*install(JsonFeature) {
|
/*install(JsonFeature) {
|
||||||
|
@ -76,12 +76,14 @@ fun Dir.firstLaunchDone() {
|
|||||||
* Call this function at startup!
|
* Call this function at startup!
|
||||||
* */
|
* */
|
||||||
fun Dir.createDirectories() {
|
fun Dir.createDirectories() {
|
||||||
createDirectory(defaultDir())
|
try {
|
||||||
createDirectory(imageCacheDir())
|
createDirectory(defaultDir())
|
||||||
createDirectory(defaultDir() + "Tracks/")
|
createDirectory(imageCacheDir())
|
||||||
createDirectory(defaultDir() + "Albums/")
|
createDirectory(defaultDir() + "Tracks/")
|
||||||
createDirectory(defaultDir() + "Playlists/")
|
createDirectory(defaultDir() + "Albums/")
|
||||||
createDirectory(defaultDir() + "YT_Downloads/")
|
createDirectory(defaultDir() + "Playlists/")
|
||||||
|
createDirectory(defaultDir() + "YT_Downloads/")
|
||||||
|
} catch (e:Exception){}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Dir.finalOutputDir(itemName: String, type: String, subFolder: String, defaultDir: String, extension: String = ".mp3"): String =
|
fun Dir.finalOutputDir(itemName: String, type: String, subFolder: String, defaultDir: String, extension: String = ".mp3"): String =
|
||||||
|
@ -18,10 +18,8 @@ package com.shabinder.common.di.providers
|
|||||||
|
|
||||||
import co.touchlab.kermit.Kermit
|
import co.touchlab.kermit.Kermit
|
||||||
import com.shabinder.common.di.Dir
|
import com.shabinder.common.di.Dir
|
||||||
import com.shabinder.common.di.currentPlatform
|
|
||||||
import com.shabinder.common.di.finalOutputDir
|
import com.shabinder.common.di.finalOutputDir
|
||||||
import com.shabinder.common.di.utils.removeIllegalChars
|
import com.shabinder.common.di.utils.removeIllegalChars
|
||||||
import com.shabinder.common.models.AllPlatforms
|
|
||||||
import com.shabinder.common.models.DownloadStatus
|
import com.shabinder.common.models.DownloadStatus
|
||||||
import com.shabinder.common.models.PlatformQueryResult
|
import com.shabinder.common.models.PlatformQueryResult
|
||||||
import com.shabinder.common.models.TrackDetails
|
import com.shabinder.common.models.TrackDetails
|
||||||
@ -37,8 +35,10 @@ class YoutubeProvider(
|
|||||||
private val logger: Kermit,
|
private val logger: Kermit,
|
||||||
private val dir: Dir,
|
private val dir: Dir,
|
||||||
) {
|
) {
|
||||||
// Youtube Downloader isn't fully compatible with JS Yet
|
val ytDownloader: YoutubeDownloader = YoutubeDownloader(
|
||||||
val ytDownloader: YoutubeDownloader? = if (currentPlatform == AllPlatforms.Js) null else YoutubeDownloader()
|
enableCORSProxy = true,
|
||||||
|
CORSProxyAddress = "https://kind-grasshopper-73.telebit.io/cors/"
|
||||||
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* YT Album Art Schema
|
* YT Album Art Schema
|
||||||
@ -95,7 +95,7 @@ class YoutubeProvider(
|
|||||||
)
|
)
|
||||||
result.apply {
|
result.apply {
|
||||||
try {
|
try {
|
||||||
val playlist = ytDownloader?.getPlaylist(searchId) ?: return null
|
val playlist = ytDownloader.getPlaylist(searchId)
|
||||||
val playlistDetails = playlist.details
|
val playlistDetails = playlist.details
|
||||||
val name = playlistDetails.title
|
val name = playlistDetails.title
|
||||||
subFolder = removeIllegalChars(name)
|
subFolder = removeIllegalChars(name)
|
||||||
@ -154,7 +154,7 @@ class YoutubeProvider(
|
|||||||
).apply {
|
).apply {
|
||||||
try {
|
try {
|
||||||
logger.i { searchId }
|
logger.i { searchId }
|
||||||
val video = ytDownloader?.getVideo(searchId) ?: return null
|
val video = ytDownloader.getVideo(searchId)
|
||||||
coverUrl = "https://i.ytimg.com/vi/$searchId/hqdefault.jpg"
|
coverUrl = "https://i.ytimg.com/vi/$searchId/hqdefault.jpg"
|
||||||
val detail = video.videoDetails
|
val detail = video.videoDetails
|
||||||
val name = detail.title?.replace(detail.author?.toUpperCase() ?: "", "", true)
|
val name = detail.title?.replace(detail.author?.toUpperCase() ?: "", "", true)
|
||||||
|
@ -2,6 +2,7 @@ package com.shabinder.common.di.saavn
|
|||||||
|
|
||||||
import co.touchlab.kermit.Kermit
|
import co.touchlab.kermit.Kermit
|
||||||
import com.shabinder.common.di.audioToMp3.AudioToMp3
|
import com.shabinder.common.di.audioToMp3.AudioToMp3
|
||||||
|
import com.shabinder.common.di.gaana.corsApi
|
||||||
import com.shabinder.common.di.globalJson
|
import com.shabinder.common.di.globalJson
|
||||||
import com.shabinder.common.models.saavn.SaavnAlbum
|
import com.shabinder.common.models.saavn.SaavnAlbum
|
||||||
import com.shabinder.common.models.saavn.SaavnPlaylist
|
import com.shabinder.common.models.saavn.SaavnPlaylist
|
||||||
@ -282,10 +283,10 @@ interface JioSaavnRequests {
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
// EndPoints
|
// EndPoints
|
||||||
const val search_base_url = "https://www.jiosaavn.com/api.php?__call=autocomplete.get&_format=json&_marker=0&cc=in&includeMetaTags=1&query="
|
val search_base_url = "${corsApi}https://www.jiosaavn.com/api.php?__call=autocomplete.get&_format=json&_marker=0&cc=in&includeMetaTags=1&query="
|
||||||
const val song_details_base_url = "https://www.jiosaavn.com/api.php?__call=song.getDetails&cc=in&_marker=0%3F_marker%3D0&_format=json&pids="
|
val song_details_base_url = "${corsApi}https://www.jiosaavn.com/api.php?__call=song.getDetails&cc=in&_marker=0%3F_marker%3D0&_format=json&pids="
|
||||||
const val album_details_base_url = "https://www.jiosaavn.com/api.php?__call=content.getAlbumDetails&_format=json&cc=in&_marker=0%3F_marker%3D0&albumid="
|
val album_details_base_url = "${corsApi}https://www.jiosaavn.com/api.php?__call=content.getAlbumDetails&_format=json&cc=in&_marker=0%3F_marker%3D0&albumid="
|
||||||
const val playlist_details_base_url = "https://www.jiosaavn.com/api.php?__call=playlist.getDetails&_format=json&cc=in&_marker=0%3F_marker%3D0&listid="
|
val playlist_details_base_url = "${corsApi}https://www.jiosaavn.com/api.php?__call=playlist.getDetails&_format=json&cc=in&_marker=0%3F_marker%3D0&listid="
|
||||||
const val lyrics_base_url = "https://www.jiosaavn.com/api.php?__call=lyrics.getLyrics&ctx=web6dot0&api_version=4&_format=json&_marker=0%3F_marker%3D0&lyrics_id="
|
val lyrics_base_url = "${corsApi}https://www.jiosaavn.com/api.php?__call=lyrics.getLyrics&ctx=web6dot0&api_version=4&_format=json&_marker=0%3F_marker%3D0&lyrics_id="
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,7 +53,7 @@ actual class Dir actual constructor(
|
|||||||
actual fun imageCacheDir(): String = System.getProperty("user.home") +
|
actual fun imageCacheDir(): String = System.getProperty("user.home") +
|
||||||
fileSeparator() + "SpotiFlyer/.images" + fileSeparator()
|
fileSeparator() + "SpotiFlyer/.images" + fileSeparator()
|
||||||
|
|
||||||
private val defaultBaseDir = System.getProperty("user.home")!!
|
private val defaultBaseDir = System.getProperty("user.home")
|
||||||
|
|
||||||
actual fun defaultDir(): String = (settings.getStringOrNull(DirKey) ?: defaultBaseDir) + fileSeparator() +
|
actual fun defaultDir(): String = (settings.getStringOrNull(DirKey) ?: defaultBaseDir) + fileSeparator() +
|
||||||
"SpotiFlyer" + fileSeparator()
|
"SpotiFlyer" + fileSeparator()
|
||||||
|
@ -52,6 +52,9 @@ kotlin {
|
|||||||
|
|
||||||
// Koin
|
// Koin
|
||||||
implementation(Koin.core)
|
implementation(Koin.core)
|
||||||
|
|
||||||
|
// Matomo
|
||||||
|
implementation("org.piwik.java.tracking:matomo-java-tracker:1.6")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val jvmTest by getting
|
val jvmTest by getting
|
||||||
|
@ -31,8 +31,10 @@ import com.shabinder.common.di.Dir
|
|||||||
import com.shabinder.common.di.DownloadProgressFlow
|
import com.shabinder.common.di.DownloadProgressFlow
|
||||||
import com.shabinder.common.di.FetchPlatformQueryResult
|
import com.shabinder.common.di.FetchPlatformQueryResult
|
||||||
import com.shabinder.common.di.initKoin
|
import com.shabinder.common.di.initKoin
|
||||||
|
import com.shabinder.common.di.isFirstLaunch
|
||||||
import com.shabinder.common.di.isInternetAccessible
|
import com.shabinder.common.di.isInternetAccessible
|
||||||
import com.shabinder.common.di.setDownloadDirectory
|
import com.shabinder.common.di.setDownloadDirectory
|
||||||
|
import com.shabinder.common.di.toggleAnalytics
|
||||||
import com.shabinder.common.models.Actions
|
import com.shabinder.common.models.Actions
|
||||||
import com.shabinder.common.models.PlatformActions
|
import com.shabinder.common.models.PlatformActions
|
||||||
import com.shabinder.common.models.TrackDetails
|
import com.shabinder.common.models.TrackDetails
|
||||||
@ -44,6 +46,9 @@ import com.shabinder.common.uikit.SpotiFlyerTypography
|
|||||||
import com.shabinder.common.uikit.colorOffWhite
|
import com.shabinder.common.uikit.colorOffWhite
|
||||||
import com.shabinder.database.Database
|
import com.shabinder.database.Database
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
|
import org.piwik.java.tracking.PiwikTracker
|
||||||
|
import utils.trackAsync
|
||||||
|
import utils.trackScreenAsync
|
||||||
import java.awt.Desktop
|
import java.awt.Desktop
|
||||||
import java.net.URI
|
import java.net.URI
|
||||||
import javax.swing.JFileChooser
|
import javax.swing.JFileChooser
|
||||||
@ -51,12 +56,15 @@ import javax.swing.JFileChooser.APPROVE_OPTION
|
|||||||
|
|
||||||
private val koin = initKoin(enableNetworkLogs = true).koin
|
private val koin = initKoin(enableNetworkLogs = true).koin
|
||||||
private lateinit var showToast: (String)->Unit
|
private lateinit var showToast: (String)->Unit
|
||||||
|
private lateinit var tracker: PiwikTracker
|
||||||
|
|
||||||
fun main() {
|
fun main() {
|
||||||
|
|
||||||
val lifecycle = LifecycleRegistry()
|
val lifecycle = LifecycleRegistry()
|
||||||
lifecycle.resume()
|
lifecycle.resume()
|
||||||
|
|
||||||
|
tracker = PiwikTracker("https://kind-grasshopper-73.telebit.io/matomo/matomo.php")
|
||||||
|
|
||||||
Window("SpotiFlyer",size = IntSize(450,800)) {
|
Window("SpotiFlyer",size = IntSize(450,800)) {
|
||||||
Surface(
|
Surface(
|
||||||
modifier = Modifier.fillMaxSize(),
|
modifier = Modifier.fillMaxSize(),
|
||||||
@ -73,6 +81,8 @@ fun main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Download Tracking for Desktop Apps for Now will be measured using `Github Releases`
|
||||||
|
// https://tooomm.github.io/github-release-stats/?username=Shabinder&repository=SpotiFlyer
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun spotiFlyerRoot(componentContext: ComponentContext): SpotiFlyerRoot =
|
private fun spotiFlyerRoot(componentContext: ComponentContext): SpotiFlyerRoot =
|
||||||
@ -137,13 +147,38 @@ private fun spotiFlyerRoot(componentContext: ComponentContext): SpotiFlyerRoot =
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
override val analytics = object: SpotiFlyerRoot.Analytics {
|
override val analytics = object: SpotiFlyerRoot.Analytics {
|
||||||
override fun appLaunchEvent() {}
|
override fun appLaunchEvent() {
|
||||||
|
// Enable Analytics
|
||||||
|
directories.toggleAnalytics(true)
|
||||||
|
tracker.trackAsync {
|
||||||
|
eventName = "App Launch"
|
||||||
|
eventAction = "App_Launch"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun homeScreenVisit() {}
|
override fun homeScreenVisit() {
|
||||||
|
tracker.trackScreenAsync(
|
||||||
|
screenAddress = "/main_activity/home_screen"
|
||||||
|
) {
|
||||||
|
actionName = "HomeScreen"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun listScreenVisit() {}
|
override fun listScreenVisit() {
|
||||||
|
tracker.trackScreenAsync(
|
||||||
|
screenAddress = "/main_activity/list_screen"
|
||||||
|
) {
|
||||||
|
actionName = "ListScreen"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun donationDialogVisit() {}
|
override fun donationDialogVisit() {
|
||||||
|
tracker.trackScreenAsync(
|
||||||
|
screenAddress = "/main_activity/donation_dialog"
|
||||||
|
) {
|
||||||
|
actionName = "DonationDialog"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
30
desktop/src/jvmMain/kotlin/utils/AnalyticsExt.kt
Normal file
30
desktop/src/jvmMain/kotlin/utils/AnalyticsExt.kt
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
package utils
|
||||||
|
|
||||||
|
import org.piwik.java.tracking.PiwikRequest
|
||||||
|
import org.piwik.java.tracking.PiwikTracker
|
||||||
|
import java.net.URL
|
||||||
|
|
||||||
|
|
||||||
|
fun PiwikTracker.trackAsync(
|
||||||
|
baseURL:String = "https://com.shabinder.spotiflyer/",
|
||||||
|
requestBuilder: PiwikRequest.() -> Unit = {}
|
||||||
|
) {
|
||||||
|
val req = PiwikRequest(
|
||||||
|
1,
|
||||||
|
URL(baseURL)
|
||||||
|
).apply { requestBuilder() }
|
||||||
|
// Send Request
|
||||||
|
sendRequestAsync(req)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun PiwikTracker.trackScreenAsync(
|
||||||
|
screenAddress:String,
|
||||||
|
requestBuilder: PiwikRequest.() -> Unit = {}
|
||||||
|
) {
|
||||||
|
val req = PiwikRequest(
|
||||||
|
1,
|
||||||
|
URL("https://com.shabinder.spotiflyer/" + screenAddress.removeSurrounding("/"))
|
||||||
|
).apply { requestBuilder() }
|
||||||
|
// Send Request
|
||||||
|
sendRequestAsync(req)
|
||||||
|
}
|
@ -49,6 +49,7 @@ dependencies {
|
|||||||
implementation(project(":common:dependency-injection"))
|
implementation(project(":common:dependency-injection"))
|
||||||
implementation("co.touchlab:stately-common:1.1.7")
|
implementation("co.touchlab:stately-common:1.1.7")
|
||||||
implementation("dev.icerock.moko:parcelize:0.6.1")
|
implementation("dev.icerock.moko:parcelize:0.6.1")
|
||||||
|
// implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.2.1")
|
||||||
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.1.0") {
|
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.1.0") {
|
||||||
// https://youtrack.jetbrains.com/issue/KTOR-2670
|
// https://youtrack.jetbrains.com/issue/KTOR-2670
|
||||||
isForce = true
|
isForce = true
|
||||||
|
Loading…
Reference in New Issue
Block a user