diff --git a/THIRDPARTY b/THIRDPARTY index 2178ef8..b0eaae5 100644 --- a/THIRDPARTY +++ b/THIRDPARTY @@ -228,4 +228,12 @@ https://github.com/JetBrains/xodus/blob/master/LICENSE.txt jediterm Apache License 2.0 -https://github.com/JetBrains/jediterm/blob/master/LICENSE-APACHE-2.0.txt \ No newline at end of file +https://github.com/JetBrains/jediterm/blob/master/LICENSE-APACHE-2.0.txt + +mixpanel-java 1.5.3 +Apache License 2.0 +https://github.com/mixpanel/mixpanel-java/blob/master/LICENSE + +json-20231013 +Public Domain. +https://github.com/stleary/JSON-java/blob/master/LICENSE \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index f0d9328..9c70eee 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -75,6 +75,7 @@ dependencies { implementation(libs.xodus.environment) implementation(libs.bip39) implementation(libs.colorpicker) + implementation(libs.mixpanel) } application { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 0649ae0..2db0493 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -40,6 +40,7 @@ colorpicker = "2.0.1" rhino = "1.7.15" delight-rhino-sandbox = "0.0.17" testcontainers = "1.20.4" +mixpanel = "1.5.3" [libraries] kotlinx-coroutines-swing = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-swing", version.ref = "kotlinx-coroutines" } @@ -95,6 +96,7 @@ bip39 = { module = "cash.z.ecc.android:kotlin-bip39-jvm", version.ref = "bip39" rhino = { module = "org.mozilla:rhino", version.ref = "rhino" } delight-rhino-sandbox = { module = "org.javadelight:delight-rhino-sandbox", version.ref = "delight-rhino-sandbox" } colorpicker = { module = "org.drjekyll:colorpicker", version.ref = "colorpicker" } +mixpanel = { module = "com.mixpanel:mixpanel-java", version.ref = "mixpanel" } [plugins] kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } diff --git a/src/main/kotlin/app/termora/ApplicationRunner.kt b/src/main/kotlin/app/termora/ApplicationRunner.kt index 945da7c..5624ff3 100644 --- a/src/main/kotlin/app/termora/ApplicationRunner.kt +++ b/src/main/kotlin/app/termora/ApplicationRunner.kt @@ -6,20 +6,26 @@ import com.formdev.flatlaf.FlatSystemProperties import com.formdev.flatlaf.extras.FlatInspector import com.formdev.flatlaf.util.SystemInfo import com.jthemedetecor.OsThemeDetector +import com.mixpanel.mixpanelapi.ClientDelivery +import com.mixpanel.mixpanelapi.MessageBuilder +import com.mixpanel.mixpanelapi.MixpanelAPI import com.sun.jna.platform.WindowUtils import com.sun.jna.platform.win32.User32 import com.sun.jna.ptr.IntByReference +import kotlinx.coroutines.DelicateCoroutinesApi +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.launch import org.apache.commons.io.FileUtils import org.apache.commons.lang3.LocaleUtils import org.apache.commons.lang3.SystemUtils import org.apache.commons.lang3.math.NumberUtils +import org.json.JSONObject import org.slf4j.LoggerFactory import org.tinylog.configuration.Configuration import java.io.File import java.io.RandomAccessFile -import java.nio.channels.FileChannel import java.nio.channels.FileLock -import java.nio.file.StandardOpenOption import java.util.* import javax.swing.* import javax.swing.WindowConstants.DISPOSE_ON_CLOSE @@ -51,6 +57,9 @@ class ApplicationRunner { // 加载设置 loadSettings() + // 统计 + enableAnalytics() + // 设置 LAF setupLaf() @@ -251,4 +260,48 @@ class ApplicationRunner { } } + /** + * 统计 https://mixpanel.com + */ + @OptIn(DelicateCoroutinesApi::class) + private fun enableAnalytics() { + if (Application.isUnknownVersion()) { + return + } + + GlobalScope.launch(Dispatchers.IO) { + try { + val properties = JSONObject() + properties.put("os", SystemUtils.OS_NAME) + if (SystemInfo.isLinux) { + properties.put("platform", "Linux") + } else if (SystemInfo.isWindows) { + properties.put("platform", "Windows") + } else if (SystemInfo.isMacOS) { + properties.put("platform", "macOS") + } + properties.put("version", Application.getVersion()) + properties.put("language", Locale.getDefault().toString()) + val message = MessageBuilder("0871335f59ee6d0eb246b008a20f9d1c") + .event(getAnalyticsUserID(), "launch", properties) + val delivery = ClientDelivery() + delivery.addMessage(message) + MixpanelAPI().deliver(delivery, true) + } catch (e: Exception) { + if (log.isErrorEnabled) { + log.error(e.message, e) + } + } + } + } + + private fun getAnalyticsUserID(): String { + var id = Database.instance.properties.getString("AnalyticsUserID") + if (id.isNullOrBlank()) { + id = UUID.randomUUID().toSimpleString() + Database.instance.properties.putString("AnalyticsUserID", id) + } + return id + } + } \ No newline at end of file