Desktop Analytics, CORS Fixes , Deps Update

This commit is contained in:
Shabinder Singh 2021-05-31 20:32:10 +05:30
parent cab7213c0e
commit 477536981f
12 changed files with 104 additions and 29 deletions

View File

@ -79,8 +79,7 @@ class MainActivity : ComponentActivity() {
private val fetcher: FetchPlatformQueryResult by inject()
private val dir: Dir by inject()
private lateinit var root: SpotiFlyerRoot
private val callBacks: SpotiFlyerRootCallBacks
get() = root.callBacks
private val callBacks: SpotiFlyerRootCallBacks get() = root.callBacks
private val trackStatusFlow = MutableSharedFlow<HashMap<String, DownloadStatus>>(1)
private var permissionGranted = mutableStateOf(true)
private lateinit var updateUIReceiver: BroadcastReceiver

View File

@ -35,7 +35,7 @@ object Versions {
const val kermit = "0.1.9"
// Internet
const val ktor = "1.5.4"
const val ktor = "1.6.0"
const val kotlinxSerialization = "1.2.1"
@ -135,7 +135,7 @@ object Ktor {
}
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 mp3agic = "com.mpatric:mp3agic:0.9.0"
const val jaudioTagger = "com.github.Shabinder:JAudioTagger-Android:1.0"

View File

@ -31,8 +31,8 @@ kotlin {
implementation(project(":common:data-models"))
implementation(project(":common:database"))
implementation("org.jetbrains.kotlinx:atomicfu:0.16.1")
implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.2.0")
implementation("com.russhwolf:multiplatform-settings-no-arg:0.7.6")
implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.2.1")
implementation("com.russhwolf:multiplatform-settings-no-arg:0.7.7")
implementation(Extras.youtubeDownloader)
implementation(Extras.fuzzyWuzzy)
implementation(MVIKotlin.rx)

View File

@ -78,7 +78,11 @@ fun createHttpClient(enableNetworkLogs: Boolean = false) = HttpClient {
install(JsonFeature) {
serializer = KotlinxSerializer(globalJson)
}
install(HttpTimeout)
install(HttpTimeout) {
socketTimeoutMillis = 520_000
requestTimeoutMillis = 360_000
connectTimeoutMillis = 360_000
}
// WorkAround for Freezing
// Use httpClient.getData / httpClient.postData Extensions
/*install(JsonFeature) {

View File

@ -76,12 +76,14 @@ fun Dir.firstLaunchDone() {
* Call this function at startup!
* */
fun Dir.createDirectories() {
try {
createDirectory(defaultDir())
createDirectory(imageCacheDir())
createDirectory(defaultDir() + "Tracks/")
createDirectory(defaultDir() + "Albums/")
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 =

View File

@ -18,10 +18,8 @@ package com.shabinder.common.di.providers
import co.touchlab.kermit.Kermit
import com.shabinder.common.di.Dir
import com.shabinder.common.di.currentPlatform
import com.shabinder.common.di.finalOutputDir
import com.shabinder.common.di.utils.removeIllegalChars
import com.shabinder.common.models.AllPlatforms
import com.shabinder.common.models.DownloadStatus
import com.shabinder.common.models.PlatformQueryResult
import com.shabinder.common.models.TrackDetails
@ -37,8 +35,10 @@ class YoutubeProvider(
private val logger: Kermit,
private val dir: Dir,
) {
// Youtube Downloader isn't fully compatible with JS Yet
val ytDownloader: YoutubeDownloader? = if (currentPlatform == AllPlatforms.Js) null else YoutubeDownloader()
val ytDownloader: YoutubeDownloader = YoutubeDownloader(
enableCORSProxy = true,
CORSProxyAddress = "https://kind-grasshopper-73.telebit.io/cors/"
)
/*
* YT Album Art Schema
@ -95,7 +95,7 @@ class YoutubeProvider(
)
result.apply {
try {
val playlist = ytDownloader?.getPlaylist(searchId) ?: return null
val playlist = ytDownloader.getPlaylist(searchId)
val playlistDetails = playlist.details
val name = playlistDetails.title
subFolder = removeIllegalChars(name)
@ -154,7 +154,7 @@ class YoutubeProvider(
).apply {
try {
logger.i { searchId }
val video = ytDownloader?.getVideo(searchId) ?: return null
val video = ytDownloader.getVideo(searchId)
coverUrl = "https://i.ytimg.com/vi/$searchId/hqdefault.jpg"
val detail = video.videoDetails
val name = detail.title?.replace(detail.author?.toUpperCase() ?: "", "", true)

View File

@ -2,6 +2,7 @@ package com.shabinder.common.di.saavn
import co.touchlab.kermit.Kermit
import com.shabinder.common.di.audioToMp3.AudioToMp3
import com.shabinder.common.di.gaana.corsApi
import com.shabinder.common.di.globalJson
import com.shabinder.common.models.saavn.SaavnAlbum
import com.shabinder.common.models.saavn.SaavnPlaylist
@ -282,10 +283,10 @@ interface JioSaavnRequests {
companion object {
// EndPoints
const val search_base_url = "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="
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="
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="
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 search_base_url = "${corsApi}https://www.jiosaavn.com/api.php?__call=autocomplete.get&_format=json&_marker=0&cc=in&includeMetaTags=1&query="
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="
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="
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="
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="
}
}

View File

@ -53,7 +53,7 @@ actual class Dir actual constructor(
actual fun imageCacheDir(): String = System.getProperty("user.home") +
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() +
"SpotiFlyer" + fileSeparator()

View File

@ -52,6 +52,9 @@ kotlin {
// Koin
implementation(Koin.core)
// Matomo
implementation("org.piwik.java.tracking:matomo-java-tracker:1.6")
}
}
val jvmTest by getting

View File

@ -31,8 +31,10 @@ import com.shabinder.common.di.Dir
import com.shabinder.common.di.DownloadProgressFlow
import com.shabinder.common.di.FetchPlatformQueryResult
import com.shabinder.common.di.initKoin
import com.shabinder.common.di.isFirstLaunch
import com.shabinder.common.di.isInternetAccessible
import com.shabinder.common.di.setDownloadDirectory
import com.shabinder.common.di.toggleAnalytics
import com.shabinder.common.models.Actions
import com.shabinder.common.models.PlatformActions
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.database.Database
import kotlinx.coroutines.runBlocking
import org.piwik.java.tracking.PiwikTracker
import utils.trackAsync
import utils.trackScreenAsync
import java.awt.Desktop
import java.net.URI
import javax.swing.JFileChooser
@ -51,12 +56,15 @@ import javax.swing.JFileChooser.APPROVE_OPTION
private val koin = initKoin(enableNetworkLogs = true).koin
private lateinit var showToast: (String)->Unit
private lateinit var tracker: PiwikTracker
fun main() {
val lifecycle = LifecycleRegistry()
lifecycle.resume()
tracker = PiwikTracker("https://kind-grasshopper-73.telebit.io/matomo/matomo.php")
Window("SpotiFlyer",size = IntSize(450,800)) {
Surface(
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 =
@ -137,13 +147,38 @@ private fun spotiFlyerRoot(componentContext: ComponentContext): SpotiFlyerRoot =
}
}
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"
}
}
}
}
)

View 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)
}

View File

@ -49,6 +49,7 @@ dependencies {
implementation(project(":common:dependency-injection"))
implementation("co.touchlab:stately-common:1.1.7")
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") {
// https://youtrack.jetbrains.com/issue/KTOR-2670
isForce = true