From 05968d5bad0a79a0ea8067a9c40336167ce5ec76 Mon Sep 17 00:00:00 2001 From: Xerus <27jf@web.de> Date: Thu, 6 Sep 2018 23:46:44 +0200 Subject: [PATCH 1/7] Improve DiscordRPC & activeTrack in Player --- src/main/xerus/monstercat/MonsterUtilities.kt | 2 +- src/main/xerus/monstercat/api/DiscordRPC.kt | 27 +++++----- src/main/xerus/monstercat/api/Player.kt | 53 +++++++++---------- 3 files changed, 38 insertions(+), 44 deletions(-) diff --git a/src/main/xerus/monstercat/MonsterUtilities.kt b/src/main/xerus/monstercat/MonsterUtilities.kt index 51a79c0..8a922de 100644 --- a/src/main/xerus/monstercat/MonsterUtilities.kt +++ b/src/main/xerus/monstercat/MonsterUtilities.kt @@ -91,7 +91,7 @@ class MonsterUtilities : VBox(), JFXMessageDisplay { fill(tabPane) if (checkUpdate) checkForUpdate() - DiscordRPC.connectDelayed(5000) + DiscordRPC.connect() } inline fun tabsByClass() = tabs.mapNotNull { it as? T } diff --git a/src/main/xerus/monstercat/api/DiscordRPC.kt b/src/main/xerus/monstercat/api/DiscordRPC.kt index e4ddc7d..c80388b 100644 --- a/src/main/xerus/monstercat/api/DiscordRPC.kt +++ b/src/main/xerus/monstercat/api/DiscordRPC.kt @@ -22,22 +22,18 @@ object DiscordRPC { } } - fun connect(apiKey: String = this.apiKey) { - if (!RPCHandler.connected.get()) { - RPCHandler.onReady = { logger.fine("Discord Rich Presence ready!") } - RPCHandler.onErrored = { errorCode, message -> logger.warning("Discord RPC API failed to execute. Error #$errorCode, $message") } - RPCHandler.connect(apiKey) - logger.config("Connecting Discord RPC") - App.stage.setOnHiding { disconnect() } - } - } - - fun connectDelayed(millis: Long, apiKey: String = this.apiKey) { + fun connect(delay: Int = 0) { launch { - delay(millis) + delay(delay) if (!RPCHandler.connected.get()) { - connect(apiKey) - updatePresence(idlePresence) + RPCHandler.onReady = { + logger.fine("Discord Rich Presence ready!") + RPCHandler.updatePresence(idlePresence) + } + RPCHandler.onErrored = { errorCode, message -> logger.warning("Discord RPC Error #$errorCode, $message") } + RPCHandler.connect(apiKey) + logger.config("Connecting Discord RPC") + App.stage.setOnHiding { disconnect() } } } } @@ -47,6 +43,7 @@ object DiscordRPC { logger.config("Disconnecting Discord RPC") RPCHandler.disconnect() RPCHandler.finishPending() + logger.finer("Disconnected Discord RPC") } } @@ -54,7 +51,7 @@ object DiscordRPC { RPCHandler.ifConnectedOrLater { RPCHandler.updatePresence(presence) if (presence != idlePresence) - logger.finer("Changed Discord presence to '${presence.details} ${presence.state}'") + logger.finer("Changed Discord RPC to '${presence.details} - ${presence.state}'") } } diff --git a/src/main/xerus/monstercat/api/Player.kt b/src/main/xerus/monstercat/api/Player.kt index f0a1ae7..31a5aa3 100644 --- a/src/main/xerus/monstercat/api/Player.kt +++ b/src/main/xerus/monstercat/api/Player.kt @@ -110,38 +110,35 @@ object Player : FadingHBox(true, targetHeight = 25) { init { box.visibleProperty().listen { visible -> if (!visible) disposePlayer() } - - activeTrack.listen { track -> - disposePlayer() - if (track != null) { - val hash = track.streamHash ?: run { - showBack("$track is currently not available for streaming!") - return@listen - } - logger.finer("Loading $track from $hash") - activePlayer.value = MediaPlayer(Media("https://s3.amazonaws.com/data.monstercat.com/blobs/$hash")) - updateVolume() - playing("Loading $track") - player?.run { - play() - setOnReady { - label.text = "Now Playing: $track" - val total = totalDuration.toMillis() - seekBar.progressProperty().dependOn(currentTimeProperty()) { it.toMillis() / total } - seekBar.transitionToHeight(Settings.PLAYERSEEKBARHEIGHT(), 1.0) - } - setOnError { - logger.log(Level.WARNING, "Error loading $track: $error", error) - showBack("Error loading $track: ${error.message?.substringAfter(": ")}") - } - } - } - } } /** Plays the given [track] in the Player, stopping the previous MediaPlayer if necessary */ fun playTrack(track: Track) { - activeTrack.value = track + activeTrack.value = null + val hash = track.streamHash ?: run { + showBack("$track is currently not available for streaming!") + return + } + logger.finer("Loading $track from $hash") + activePlayer.value = MediaPlayer(Media("https://s3.amazonaws.com/data.monstercat.com/blobs/$hash")) + updateVolume() + playing("Loading $track") + player?.run { + play() + setOnReady { + label.text = "Now Playing: $track" + val total = totalDuration.toMillis() + seekBar.progressProperty().dependOn(currentTimeProperty()) { it.toMillis() / total } + seekBar.transitionToHeight(Settings.PLAYERSEEKBARHEIGHT(), 1.0) + onFx { + activeTrack.value = track + } + } + setOnError { + logger.log(Level.WARNING, "Error loading $track: $error", error) + showBack("Error loading $track: ${error.message?.substringAfter(": ")}") + } + } } /** Stops playing, disposes the active MediaPlayer and calls [resetNotification] */ From 0bf87c6ae8275d05cc774cb369d0e6a9633149d7 Mon Sep 17 00:00:00 2001 From: Xerus <27jf@web.de> Date: Fri, 7 Sep 2018 19:54:15 +0200 Subject: [PATCH 2/7] Improve Player --- src/main/xerus/monstercat/api/Player.kt | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/src/main/xerus/monstercat/api/Player.kt b/src/main/xerus/monstercat/api/Player.kt index 31a5aa3..b875e88 100644 --- a/src/main/xerus/monstercat/api/Player.kt +++ b/src/main/xerus/monstercat/api/Player.kt @@ -64,7 +64,7 @@ object Player : FadingHBox(true, targetHeight = 25) { init { box.alignment = Pos.CENTER maxHeight = Double.MAX_VALUE - resetNotification() + reset() } private val label = Label() @@ -77,19 +77,19 @@ object Player : FadingHBox(true, targetHeight = 25) { } } - /** Shows [text] in the [label] and adds a back Button that calls [resetNotification] when clicked */ + /** Shows [text] in the [label] and adds a back Button that calls [reset] when clicked */ private fun showBack(text: String) { checkFx { showText(text) - addButton { resetNotification() }.id("back") + addButton { reset() }.id("back") fill(pos = 0) fill() add(closeButton) } } - /** hides the Player and appears again with the latest Release */ - fun resetNotification() { + /** hides the Player and appears again displaying the latest Release */ + fun reset() { fadeOut() launch { val latest = Releases.getReleases().lastOrNull() ?: return@launch @@ -141,22 +141,18 @@ object Player : FadingHBox(true, targetHeight = 25) { } } - /** Stops playing, disposes the active MediaPlayer and calls [resetNotification] */ - fun stopPlaying() { - activeTrack.value = null - resetNotification() - } - + /** Disposes the [activePlayer] and hides the [seekBar] */ private fun disposePlayer() { player?.dispose() activePlayer.value = null + activeTrack.value = null checkFx { seekBar.transitionToHeight(0.0) } } private val pauseButton = ToggleButton().id("play-pause").onClick { if (isSelected) player?.pause() else player?.play() } - private val stopButton = buttonWithId("stop") { stopPlaying() } + private val stopButton = buttonWithId("stop") { reset() } private val volumeSlider = Slider(0.0, 1.0, Settings.PLAYERVOLUME()).scrollable(0.05).apply { prefWidth = 100.0 valueProperty().addListener { _ -> updateVolume() } @@ -190,7 +186,7 @@ object Player : FadingHBox(true, targetHeight = 25) { return@launch } playTrack(track) - player?.setOnEndOfMedia { stopPlaying() } + player?.setOnEndOfMedia { reset() } } } @@ -216,7 +212,7 @@ object Player : FadingHBox(true, targetHeight = 25) { if (index < tracks.lastIndex) children.add(children.size - 3, buttonWithId("skip") { playTracks(tracks, index + 1) }) } - player?.setOnEndOfMedia { if (tracks.lastIndex > index) playTracks(tracks, index + 1) else stopPlaying() } + player?.setOnEndOfMedia { if (tracks.lastIndex > index) playTracks(tracks, index + 1) else reset() } } } From 57c9043000327d5b1cdb79c634becc4a708bdd20 Mon Sep 17 00:00:00 2001 From: Xerus <27jf@web.de> Date: Fri, 7 Sep 2018 23:01:14 +0200 Subject: [PATCH 3/7] Add troubleshooting section to Readme Fixes #21 --- Readme.md | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/Readme.md b/Readme.md index b561012..ccf9d70 100644 --- a/Readme.md +++ b/Readme.md @@ -6,7 +6,7 @@ Browse, stream and download Monstercat Songs, powered by the Monstercat API and ## Usage -[Download](http://monsterutilities.bplaced.net/downloads?download) +[Download](http://monsterutilities.bplaced.net/downloads?download) or use the GitHub releases. > This is a pre-Release, you may encounter bugs. If you do, open an issue here or send feedback from inside the application. @@ -14,13 +14,37 @@ The latter will automatically include logs, which reside in `TEMP/monsterutiliti To run it, you need to have Java 8 by Oracle installed on your computer. -Read the initial guide and follow the tooltips. Improved user-friendliness is in development ;) +Read the initial guide and follow the tooltips. +Improved user-friendliness is in development ;) + +### Troubleshooting + +#### connect.sid + +For downloading and listening to the latest Track, your `connect.sid` +needs to be entered in the bottom of the Downloader. It is a cookie that +identifies your Monstercat Account. Here's how to obtain it: + +1) Log in on [monstercat.com](https://monstercat.com) and ensure that you have a valid Monstercat Gold subscription +2) Go to your browser cookies and search for `connect.monstercat.com` + [Quick link for Chrome](chrome://settings/cookies/detail?site=connect.monstercat.com) +3) Find the content of `connect.sid`. It is a string starting with `s%3A` and has around 90 characters. +4) Copy that string into the `connect.sid` Textfield at the bottom of the Downloader. + +#### Downloader + +Sometimes, the cache runs into issues and that may contribute to issues in the Downloader. +Simply disable the cache, restart the application and enable it again. + +> If you still have issues - no problem! +> Hit me up on [Discord](https://discord.gg/ZEusvHS) or send Feedback directly from the application! ## Screenshots ### Catalog -The Catalog provides an overview of all Tracks ever released on the label and extensive possibilities of filtering them. +The Catalog provides an overview of all Tracks ever released on the label and +extensive possibilities of filtering them. > Tip: You can customize which columns to show by clicking on the `+` in the top right ![Catalog](assets/screenshots/catalog.png) @@ -28,9 +52,9 @@ The Catalog provides an overview of all Tracks ever released on the label and ex ### Streaming -In case you missed it in the other Screenshots: There's a player on top that can stream any Monstercat track, -just like the website. Double-click on any piece in the Catalog or Downloader to load it into the Player! - +In case you missed it in the other Screenshots: +There's a player on top that can stream any Monstercat track, just like the website. +Double-click on any piece in the Catalog or Downloader to load it into the Player! ![Player](assets/screenshots/player.png) ### Downloader From 0f6798e69f6367072f89f7718466ab333bd94e67 Mon Sep 17 00:00:00 2001 From: Xerus <27jf@web.de> Date: Thu, 13 Sep 2018 16:06:16 +0200 Subject: [PATCH 4/7] Update Coroutines --- build.gradle.kts | 8 +++----- src/archive/Downloader.kt | 2 +- src/main/xerus/monstercat/Main.kt | 8 +++----- src/main/xerus/monstercat/MonsterUtilities.kt | 7 ++++--- src/main/xerus/monstercat/api/DiscordRPC.kt | 3 ++- src/main/xerus/monstercat/api/Player.kt | 7 ++++--- src/main/xerus/monstercat/downloader/SongViews.kt | 3 ++- .../xerus/monstercat/downloader/TabDownloader.kt | 12 ++++++------ 8 files changed, 25 insertions(+), 25 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index a6b8e83..287cadb 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -47,14 +47,12 @@ repositories { } dependencies { - compile("com.github.Xerus2000", "util", "master-SNAPSHOT") - compile(kotlin("stdlib-jdk8")) compile(kotlin("reflect")) + compile("com.github.Xerus2000.util", "javafx", "-SNAPSHOT") compile("org.controlsfx", "controlsfx", "8.40.14") - compile("be.bluexin", "drpc4k", "0.6-SNAPSHOT") - + compile("com.github.Bluexin", "drpc4k", "-SNAPSHOT") compile("org.apache.httpcomponents", "httpmime", "4.5.5") compile("com.google.apis", "google-api-services-sheets", "v4-rev527-1.23.0") @@ -112,7 +110,7 @@ tasks { setDelete(file(".").listFiles { f -> f.name.run { startsWith("MonsterUtilities-") && endsWith("jar") && this != file } }) } - "test"(Test::class) { + withType { useJUnitPlatform() } diff --git a/src/archive/Downloader.kt b/src/archive/Downloader.kt index f0d6150..5e7a533 100644 --- a/src/archive/Downloader.kt +++ b/src/archive/Downloader.kt @@ -44,7 +44,7 @@ class DownloaderSwing : BasePanel() { } init { - launch { + GlobalScope.launch { logger.fine("DownloadWorker started") var limit = LIMIT.int diff --git a/src/main/xerus/monstercat/Main.kt b/src/main/xerus/monstercat/Main.kt index 1608abb..c2584d2 100644 --- a/src/main/xerus/monstercat/Main.kt +++ b/src/main/xerus/monstercat/Main.kt @@ -4,9 +4,7 @@ import com.google.api.client.googleapis.auth.oauth2.GoogleCredential import com.google.api.services.sheets.v4.SheetsScopes import javafx.scene.Scene import javafx.scene.image.Image -import kotlinx.coroutines.experimental.asCoroutineDispatcher -import kotlinx.coroutines.experimental.delay -import kotlinx.coroutines.experimental.launch +import kotlinx.coroutines.experimental.* import xerus.ktutil.* import xerus.ktutil.javafx.applySkin import xerus.ktutil.javafx.ui.App @@ -44,7 +42,7 @@ fun main(args: Array) { try { XerusLogger.logToFile(logfile) logger.config("Logging to $logfile") - launch { + GlobalScope.launch { val logs = logDir.listFiles() if (logs.size > 10) { logs.asSequence().sortedByDescending { it.name }.drop(5).filter { @@ -82,7 +80,7 @@ fun main(args: Array) { } fun showErrorSafe(error: Throwable, title: String = "Error") { - launch { + GlobalScope.launch { var i = 0 while (i < 100 && !::monsterUtilities.isInitialized) { delay(200) diff --git a/src/main/xerus/monstercat/MonsterUtilities.kt b/src/main/xerus/monstercat/MonsterUtilities.kt index 8a922de..0b66314 100644 --- a/src/main/xerus/monstercat/MonsterUtilities.kt +++ b/src/main/xerus/monstercat/MonsterUtilities.kt @@ -6,6 +6,7 @@ import javafx.scene.control.* import javafx.scene.image.Image import javafx.scene.image.ImageView import javafx.scene.layout.VBox +import kotlinx.coroutines.experimental.GlobalScope import kotlinx.coroutines.experimental.launch import org.controlsfx.dialog.ExceptionDialog import xerus.ktutil.* @@ -42,7 +43,7 @@ class MonsterUtilities : VBox(), JFXMessageDisplay { fun addTab(tabClass: KClass) { try { - val baseTab = tabClass.java.newInstance() + val baseTab = tabClass.java.getDeclaredConstructor().newInstance() logger.finer("New Tab: $baseTab") tabs.add(baseTab) val tab = Tab(baseTab.tabName, baseTab.asNode()) @@ -65,7 +66,7 @@ class MonsterUtilities : VBox(), JFXMessageDisplay { showIntro() Settings.LASTVERSION.put(VERSION) } else { - launch { + GlobalScope.launch { logger.fine("New version! Now running $VERSION, previously " + Settings.LASTVERSION()) val f = Settings.DELETE() if (f.exists()) { @@ -97,7 +98,7 @@ class MonsterUtilities : VBox(), JFXMessageDisplay { inline fun tabsByClass() = tabs.mapNotNull { it as? T } fun checkForUpdate(userControlled: Boolean = false, unstable: Boolean = isUnstable) { - launch { + GlobalScope.launch { try { val latestVersion = URL("http://monsterutilities.bplaced.net/downloads/" + if (unstable) "unstable" else "latest").openConnection().getInputStream().reader().readLines().firstOrNull() logger.fine("Latest version: $latestVersion") diff --git a/src/main/xerus/monstercat/api/DiscordRPC.kt b/src/main/xerus/monstercat/api/DiscordRPC.kt index c80388b..5da8168 100644 --- a/src/main/xerus/monstercat/api/DiscordRPC.kt +++ b/src/main/xerus/monstercat/api/DiscordRPC.kt @@ -2,6 +2,7 @@ package xerus.monstercat.api import be.bluexin.drpc4k.jna.DiscordRichPresence import be.bluexin.drpc4k.jna.RPCHandler +import kotlinx.coroutines.experimental.GlobalScope import kotlinx.coroutines.experimental.delay import kotlinx.coroutines.experimental.launch import xerus.ktutil.getResource @@ -23,7 +24,7 @@ object DiscordRPC { } fun connect(delay: Int = 0) { - launch { + GlobalScope.launch { delay(delay) if (!RPCHandler.connected.get()) { RPCHandler.onReady = { diff --git a/src/main/xerus/monstercat/api/Player.kt b/src/main/xerus/monstercat/api/Player.kt index b875e88..bff6a28 100644 --- a/src/main/xerus/monstercat/api/Player.kt +++ b/src/main/xerus/monstercat/api/Player.kt @@ -9,6 +9,7 @@ import javafx.scene.layout.VBox import javafx.scene.media.Media import javafx.scene.media.MediaPlayer import javafx.util.Duration +import kotlinx.coroutines.experimental.GlobalScope import kotlinx.coroutines.experimental.delay import kotlinx.coroutines.experimental.launch import xerus.ktutil.javafx.* @@ -91,7 +92,7 @@ object Player : FadingHBox(true, targetHeight = 25) { /** hides the Player and appears again displaying the latest Release */ fun reset() { fadeOut() - launch { + GlobalScope.launch { val latest = Releases.getReleases().lastOrNull() ?: return@launch while (fading) delay(50) showText("Latest Release: $latest") @@ -177,7 +178,7 @@ object Player : FadingHBox(true, targetHeight = 25) { /** Finds the best match for the given [title] and [artists] and starts playing it */ fun play(title: String, artists: String) { - launch { + GlobalScope.launch { showText("Searching for \"$title\"...") disposePlayer() val track = API.find(title, artists) @@ -193,7 +194,7 @@ object Player : FadingHBox(true, targetHeight = 25) { /** Plays this [release], creating an internal playlist when it has multiple Tracks */ fun play(release: Release) { checkFx { showText("Searching for $release") } - launch { + GlobalScope.launch { val results = APIConnection("catalog", "release", release.id, "tracks").getTracks()?.takeUnless { it.isEmpty() } ?: run { showBack("No tracks found for Release $release") diff --git a/src/main/xerus/monstercat/downloader/SongViews.kt b/src/main/xerus/monstercat/downloader/SongViews.kt index 5c92a31..78f927f 100644 --- a/src/main/xerus/monstercat/downloader/SongViews.kt +++ b/src/main/xerus/monstercat/downloader/SongViews.kt @@ -1,5 +1,6 @@ package xerus.monstercat.downloader +import kotlinx.coroutines.experimental.GlobalScope import kotlinx.coroutines.experimental.launch import xerus.ktutil.javafx.controlsfx.FilterableCheckTreeView import xerus.ktutil.javafx.onFx @@ -31,7 +32,7 @@ abstract class SongView(root: T) : FilterableCheckTreeView(roo } fun load() { - launch { + GlobalScope.launch { fetchItems() onFx { onReady() diff --git a/src/main/xerus/monstercat/downloader/TabDownloader.kt b/src/main/xerus/monstercat/downloader/TabDownloader.kt index 6832ef4..5c339c7 100644 --- a/src/main/xerus/monstercat/downloader/TabDownloader.kt +++ b/src/main/xerus/monstercat/downloader/TabDownloader.kt @@ -205,7 +205,7 @@ class TabDownloader : VTab() { .also { it.selectedProperty().listen { if (it) { - launch { + GlobalScope.launch { awaitReady() releaseView.roots.forEach { it.value.internalChildren.removeIf { @@ -218,7 +218,7 @@ class TabDownloader : VTab() { releaseView.root.internalChildren.clear() releaseView.roots.clear() trackView.root.internalChildren.clear() - launch { + GlobalScope.launch { releaseView.load() trackView.load() } @@ -236,7 +236,7 @@ class TabDownloader : VTab() { val dont = arrayOf("Album", "EP", "Single") val deferred = (albums.flatMap { it.children } + releaseView.roots.filterNot { it.value.value.title in dont }.flatMap { it.value.internalChildren }.filterNot { it.value.isMulti }) .map { - async(context) { + GlobalScope.async(context) { if (!isActive) return@async null APIConnection("catalog", "release", it.value.id, "tracks").getTracks()?.map { it.toString().normalised } } @@ -284,7 +284,7 @@ class TabDownloader : VTab() { private fun refreshDownloadButton(button: Button) { button.text = "Checking..." - launch { + GlobalScope.launch { var valid = false val text = when (APIConnection.checkCookie()) { CookieValidity.NOCONNECTION -> "No connection" @@ -359,7 +359,7 @@ class TabDownloader : VTab() { if (done == total) progressLabel.text = "$done / $total Errors: $e" else - counter = launch { + counter = GlobalScope.launch { val estimate = ((estimatedLength / lengths.sum() + total / done - 2) * timer.time() / 1000).roundToLong() time = if (time > 0) (time * 9 + estimate) / 10 else estimate logger.finest("Estimate: ${formatTimeDynamic(estimate, estimate.coerceAtLeast(60))} Weighed: ${formatTimeDynamic(time, time.coerceAtLeast(60))}") @@ -398,7 +398,7 @@ class TabDownloader : VTab() { private val success = SimpleIntegerProperty() private val errors = SimpleIntegerProperty() private fun startDownload() { - downloader = launch { + downloader = GlobalScope.launch { log("Download started") for (item in items) { val download = item.downloadTask() From 6f11f04a85846579ab19f19b0a20850eb8fc50a1 Mon Sep 17 00:00:00 2001 From: Xerus <27jf@web.de> Date: Sat, 15 Sep 2018 14:55:42 +0200 Subject: [PATCH 5/7] Update dependencies & adapt to util changes --- build.gradle.kts | 21 ++++++++++--------- src/main/xerus/monstercat/Main.kt | 7 ++++--- .../xerus/monstercat/api/APIConnection.kt | 4 ++-- src/main/xerus/monstercat/api/Cache.kt | 1 - .../monstercat/downloader/ReleaseFile.kt | 4 ++-- src/main/xerus/monstercat/tabs/BaseTab.kt | 1 - src/main/xerus/monstercat/tabs/FetchTab.kt | 8 +++---- 7 files changed, 23 insertions(+), 23 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 287cadb..49b8443 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -12,10 +12,10 @@ version = "dev" + Scanner(Runtime.getRuntime().exec("git rev-list --count HEAD") file("src/resources/version").writeText(version as String) plugins { - kotlin("jvm") version "1.2.61" + kotlin("jvm") version "1.2.70" application id("com.github.johnrengelman.shadow") version "2.0.4" - id("com.github.ben-manes.versions") version "0.19.0" + id("com.github.ben-manes.versions") version "0.20.0" } // source directories @@ -47,17 +47,18 @@ repositories { } dependencies { - compile(kotlin("reflect")) + implementation(kotlin("reflect")) - compile("com.github.Xerus2000.util", "javafx", "-SNAPSHOT") - compile("org.controlsfx", "controlsfx", "8.40.14") + implementation("com.github.Xerus2000.util", "javafx", "-SNAPSHOT") + implementation("org.controlsfx", "controlsfx", "8.40.14") - compile("com.github.Bluexin", "drpc4k", "-SNAPSHOT") - compile("org.apache.httpcomponents", "httpmime", "4.5.5") - compile("com.google.apis", "google-api-services-sheets", "v4-rev527-1.23.0") + implementation("com.github.Bluexin", "drpc4k", "-SNAPSHOT") + implementation("org.apache.httpcomponents", "httpmime", "4.5.+") + implementation("com.google.apis", "google-api-services-sheets", "v4-rev542-1.25.0") - testCompile("org.junit.jupiter", "junit-jupiter-api", "5.2.0") - testRuntimeOnly("org.junit.jupiter", "junit-jupiter-engine", "5.2.0") + val junitVersion = "5.3.1" + testCompile("org.junit.jupiter", "junit-jupiter-api", junitVersion) + testRuntimeOnly("org.junit.jupiter", "junit-jupiter-engine", junitVersion) } val file diff --git a/src/main/xerus/monstercat/Main.kt b/src/main/xerus/monstercat/Main.kt index c2584d2..b9b9598 100644 --- a/src/main/xerus/monstercat/Main.kt +++ b/src/main/xerus/monstercat/Main.kt @@ -6,6 +6,7 @@ import javafx.scene.Scene import javafx.scene.image.Image import kotlinx.coroutines.experimental.* import xerus.ktutil.* +import xerus.ktutil.helpers.XerusLogger import xerus.ktutil.javafx.applySkin import xerus.ktutil.javafx.ui.App import xerus.ktutil.ui.SimpleFrame @@ -58,11 +59,11 @@ fun main(args: Array) { } catch (t: Throwable) { showErrorSafe(t, "Can't log to $logfile!") } - if (!javaVersion().startsWith("1.8")) { - SimpleFrame { add(JTextArea("Please install and use Java 8!\nThe current version is ${javaVersion()}").apply { isEditable = false }) } + if (!SystemUtils.javaVersion.startsWith("1.8")) { + SimpleFrame { add(JTextArea("Please install and use Java 8!\nThe current version is ${SystemUtils.javaVersion}").apply { isEditable = false }) } return } - logger.info("Version: $VERSION, Java version: ${javaVersion()}") + logger.info("Version: $VERSION, Java version: ${SystemUtils.javaVersion}") logger.config("Initializing Google Sheets API Service") Sheets.initService("MonsterUtilities", GoogleCredential().createScoped(listOf(SheetsScopes.SPREADSHEETS_READONLY))) App.launch("MonsterUtilities $VERSION", { stage -> diff --git a/src/main/xerus/monstercat/api/APIConnection.kt b/src/main/xerus/monstercat/api/APIConnection.kt index 0b61601..76b6a94 100644 --- a/src/main/xerus/monstercat/api/APIConnection.kt +++ b/src/main/xerus/monstercat/api/APIConnection.kt @@ -9,12 +9,12 @@ import org.apache.http.client.methods.HttpGet import org.apache.http.impl.client.BasicCookieStore import org.apache.http.impl.client.HttpClientBuilder import org.apache.http.impl.cookie.BasicClientCookie -import xerus.ktutil.XerusLogger import xerus.ktutil.helpers.HTTPQuery import xerus.monstercat.Sheets import xerus.monstercat.api.response.* import xerus.monstercat.downloader.CONNECTSID import xerus.monstercat.downloader.QUALITY +import xerus.monstercat.logger import java.io.IOException import java.io.InputStream import java.net.URI @@ -59,7 +59,7 @@ class APIConnection(vararg path: String) : HTTPQuery() { private var httpGet: HttpGet? = null fun execute() { httpGet = HttpGet(uri) - XerusLogger.finest("$this connecting") + logger.finest("$this connecting") val conf = RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD).build() response = HttpClientBuilder.create().setDefaultRequestConfig(conf).setDefaultCookieStore(cookies()).build().execute(httpGet) } diff --git a/src/main/xerus/monstercat/api/Cache.kt b/src/main/xerus/monstercat/api/Cache.kt index 56327ac..1b19cef 100644 --- a/src/main/xerus/monstercat/api/Cache.kt +++ b/src/main/xerus/monstercat/api/Cache.kt @@ -1,6 +1,5 @@ package xerus.monstercat.api -import xerus.ktutil.XerusLogger import xerus.ktutil.currentSeconds import xerus.ktutil.helpers.Refresher import xerus.monstercat.Settings diff --git a/src/main/xerus/monstercat/downloader/ReleaseFile.kt b/src/main/xerus/monstercat/downloader/ReleaseFile.kt index 7000dbe..2849795 100644 --- a/src/main/xerus/monstercat/downloader/ReleaseFile.kt +++ b/src/main/xerus/monstercat/downloader/ReleaseFile.kt @@ -1,7 +1,7 @@ package xerus.monstercat.downloader -import xerus.ktutil.helpers.Masker import xerus.ktutil.helpers.ParserException +import xerus.ktutil.helpers.StringMasker import xerus.ktutil.replaceIllegalFileChars import xerus.monstercat.api.response.Artist import xerus.monstercat.api.response.Track @@ -9,7 +9,7 @@ import java.util.regex.Pattern val delimiters = arrayOf(" & ", ", ", " and ", " x ") val exceptions = arrayOf("Slips & Slurs", "Case & Point", "Gent & Jawns") -val artistMasker = Masker("artist", *exceptions) +val artistMasker = StringMasker("artist", *exceptions) /** artists - tracknumber title */ val namePattern: Pattern = Pattern.compile("([^-]+) - (.+ - )?(\\d+) (.+)") diff --git a/src/main/xerus/monstercat/tabs/BaseTab.kt b/src/main/xerus/monstercat/tabs/BaseTab.kt index 56dd07e..542bc6b 100644 --- a/src/main/xerus/monstercat/tabs/BaseTab.kt +++ b/src/main/xerus/monstercat/tabs/BaseTab.kt @@ -4,7 +4,6 @@ import javafx.scene.control.Control import javafx.scene.layout.Pane import javafx.scene.layout.VBox import org.controlsfx.validation.decoration.GraphicValidationDecoration -import xerus.ktutil.XerusLogger val minimalValidationDecorator = object : GraphicValidationDecoration() { override fun applyRequiredDecoration(target: Control?) {} diff --git a/src/main/xerus/monstercat/tabs/FetchTab.kt b/src/main/xerus/monstercat/tabs/FetchTab.kt index 0db8bea..84d19fe 100644 --- a/src/main/xerus/monstercat/tabs/FetchTab.kt +++ b/src/main/xerus/monstercat/tabs/FetchTab.kt @@ -10,8 +10,8 @@ import xerus.ktutil.helpers.RoughMap import xerus.ktutil.helpers.SimpleRefresher import xerus.ktutil.javafx.* import xerus.ktutil.javafx.ui.controls.Snackbar -import xerus.ktutil.readObject -import xerus.ktutil.writeObject +import xerus.ktutil.readToObject +import xerus.ktutil.writeToFile import xerus.monstercat.* import xerus.monstercat.Sheets.fetchMCatalogTab import xerus.monstercat.api.Releases @@ -96,7 +96,7 @@ abstract class FetchTab : VTab() { return logger.fine("Writing cache file $cacheFile") try { - writeObject(cacheFile, sheet) + sheet.writeToFile(cacheFile) } catch (e: IOException) { monsterUtilities.showError(e, "Couldn't write $tabName cache!") } @@ -106,7 +106,7 @@ abstract class FetchTab : VTab() { if (!Settings.ENABLECACHE()) return try { - readSheet(readObject(cacheFile)) + readSheet(cacheFile.readToObject()) logger.fine("Restored cache file $cacheFile") showNotification(snackbarTextCache) } catch (ignored: FileNotFoundException) { From 50e86c6332dfc0a3efd0e51874bf3385c36bb009 Mon Sep 17 00:00:00 2001 From: Xerus <27jf@web.de> Date: Sat, 15 Sep 2018 16:55:51 +0200 Subject: [PATCH 6/7] Replace XerusLogger with slf4j+logback Fixes #14 --- build.gradle.kts | 3 +- src/main/xerus/monstercat/Logging.kt | 87 +++++++++++++++++++ src/main/xerus/monstercat/Main.kt | 61 +++++-------- src/main/xerus/monstercat/MonsterUtilities.kt | 37 ++++---- src/main/xerus/monstercat/Settings.kt | 8 +- src/main/xerus/monstercat/api/API.kt | 5 +- .../xerus/monstercat/api/APIConnection.kt | 6 +- src/main/xerus/monstercat/api/Cache.kt | 19 ++-- src/main/xerus/monstercat/api/DiscordRPC.kt | 15 ++-- src/main/xerus/monstercat/api/Player.kt | 7 +- .../xerus/monstercat/downloader/Download.kt | 8 +- .../monstercat/downloader/TabDownloader.kt | 17 ++-- src/main/xerus/monstercat/tabs/BaseTab.kt | 3 + src/main/xerus/monstercat/tabs/FetchTab.kt | 15 ++-- src/main/xerus/monstercat/tabs/TabCatalog.kt | 7 +- src/main/xerus/monstercat/tabs/TabGenres.kt | 8 +- src/main/xerus/monstercat/tabs/TabSettings.kt | 21 +++-- src/main/xerus/monstercat/tabs/TabSound.kt | 6 +- .../ch.qos.logback.classic.spi.Configurator | 1 + 19 files changed, 209 insertions(+), 125 deletions(-) create mode 100644 src/main/xerus/monstercat/Logging.kt create mode 100644 src/resources/META-INF/services/ch.qos.logback.classic.spi.Configurator diff --git a/build.gradle.kts b/build.gradle.kts index 49b8443..d9ad749 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -52,6 +52,7 @@ dependencies { implementation("com.github.Xerus2000.util", "javafx", "-SNAPSHOT") implementation("org.controlsfx", "controlsfx", "8.40.14") + implementation("ch.qos.logback", "logback-classic", "1.2.3") implementation("com.github.Bluexin", "drpc4k", "-SNAPSHOT") implementation("org.apache.httpcomponents", "httpmime", "4.5.+") implementation("com.google.apis", "google-api-services-sheets", "v4-rev542-1.25.0") @@ -72,7 +73,7 @@ tasks { "run"(JavaExec::class) { group = MAIN - // Usage: gradle run -Dargs="FINE save" + // Usage: gradle run -Dargs="--loglevel trace" args = System.getProperty("args", "").split(" ") } diff --git a/src/main/xerus/monstercat/Logging.kt b/src/main/xerus/monstercat/Logging.kt new file mode 100644 index 0000000..908e3c1 --- /dev/null +++ b/src/main/xerus/monstercat/Logging.kt @@ -0,0 +1,87 @@ +package xerus.monstercat + +import ch.qos.logback.classic.Level +import ch.qos.logback.classic.LoggerContext +import ch.qos.logback.classic.encoder.PatternLayoutEncoder +import ch.qos.logback.classic.filter.LevelFilter +import ch.qos.logback.classic.spi.Configurator +import ch.qos.logback.classic.spi.ILoggingEvent +import ch.qos.logback.core.ConsoleAppender +import ch.qos.logback.core.FileAppender +import ch.qos.logback.core.rolling.RollingFileAppender +import ch.qos.logback.core.spi.ContextAwareBase +import kotlinx.coroutines.experimental.GlobalScope +import kotlinx.coroutines.experimental.launch +import mu.KotlinLogging +import org.slf4j.Logger +import org.slf4j.LoggerFactory +import xerus.ktutil.currentSeconds +import xerus.ktutil.getStackTraceString +import java.io.File + +private val logDir: File + get() = cacheDir.resolve("logs").apply { mkdirs() } +private val logFile = logDir.resolve("log${currentSeconds()}.txt") +private var logLevel: Level = Level.WARN + +internal fun initLogging(args: Array) { + args.indexOf("--loglevel").takeIf { it > -1 }?.let { + logLevel = args.getOrNull(it)?.let { Level.toLevel(it) } ?: throw IllegalArgumentException("No loglevel specified!") + } + Thread.setDefaultUncaughtExceptionHandler { thread, ex -> + LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME).warn("Uncaught exception in $thread: ${ex.getStackTraceString()}") + } + val logger = KotlinLogging.logger { } + logger.info("Logging to $logFile") + GlobalScope.launch { + val logs = logDir.listFiles() + if (logs.size > 10) { + logs.asSequence().sortedByDescending { it.name }.drop(5).filter { + val timestamp = it.nameWithoutExtension.substring(3).toIntOrNull() ?: return@filter true + timestamp + 200_000 < currentSeconds() + }.also { + val count = it.count() + if (count > 0) + logger.debug("Deleting $count old logs") + }.forEach { it.delete() } + } + } +} + +internal class LogbackConfigurator : ContextAwareBase(), Configurator { + + override fun configure(lc: LoggerContext) { + + val encoder = PatternLayoutEncoder().apply { + context = lc + pattern = "%d{HH:mm:ss} [%-25.25thread] %-5level %-30logger{30} %msg%n" + start() + } + + val consoleAppender = ConsoleAppender().apply { + name = "console" + context = lc + this.encoder = encoder + addFilter(LevelFilter().apply { + setLevel(logLevel) + }) + start() + } + + RollingFileAppender().apply { + this.rollingPolicy + } + val fileAppender = FileAppender().apply { + name = "file" + file = logFile.toString() + context = lc + this.encoder = encoder + start() + } + + val rootLogger = lc.getLogger(Logger.ROOT_LOGGER_NAME) + rootLogger.addAppender(consoleAppender) + rootLogger.addAppender(fileAppender) + } + +} \ No newline at end of file diff --git a/src/main/xerus/monstercat/Main.kt b/src/main/xerus/monstercat/Main.kt index b9b9598..7820511 100644 --- a/src/main/xerus/monstercat/Main.kt +++ b/src/main/xerus/monstercat/Main.kt @@ -5,8 +5,9 @@ import com.google.api.services.sheets.v4.SheetsScopes import javafx.scene.Scene import javafx.scene.image.Image import kotlinx.coroutines.experimental.* -import xerus.ktutil.* -import xerus.ktutil.helpers.XerusLogger +import mu.KotlinLogging +import xerus.ktutil.SystemUtils +import xerus.ktutil.getResource import xerus.ktutil.javafx.applySkin import xerus.ktutil.javafx.ui.App import xerus.ktutil.ui.SimpleFrame @@ -14,65 +15,49 @@ import java.io.File import java.net.URL import java.util.concurrent.ExecutorService import java.util.concurrent.Executors +import java.util.concurrent.ThreadFactory +import java.util.concurrent.atomic.AtomicInteger import javax.swing.JTextArea -typealias logger = XerusLogger - val VERSION = getResource("version")!!.readText() val isUnstable = VERSION.contains('-') -val logDir: File - get() = cacheDir.resolve("logs").apply { mkdirs() } +val cacheDir: File + get() = (File("/var/tmp").takeIf { it.exists() } ?: File(System.getProperty("java.io.tmpdir"))) + .resolve("monsterutilities").apply { mkdirs() } lateinit var monsterUtilities: MonsterUtilities -val globalThreadPool: ExecutorService = Executors.newCachedThreadPool() +val globalThreadPool: ExecutorService = Executors.newCachedThreadPool(object : ThreadFactory { + private val poolNumber = AtomicInteger(1) + override fun newThread(r: Runnable) = + Thread(Thread.currentThread().threadGroup, r, "global-" + poolNumber.getAndIncrement()) +}) val globalDispatcher = globalThreadPool.asCoroutineDispatcher() -val location: URL = MonsterUtilities::class.java.protectionDomain.codeSource.location -var checkUpdate = Settings.AUTOUPDATE() && location.toString().endsWith(".jar") +val jarLocation: URL = MonsterUtilities::class.java.protectionDomain.codeSource.location fun main(args: Array) { - XerusLogger.parseArgs(*args, defaultLevel = "finer") - if (args.contains("--no-update")) - checkUpdate = false - Thread.setDefaultUncaughtExceptionHandler { thread, ex -> - logger.warning("Uncaught exception in $thread: ${ex.getStackTraceString()}") - } - val logfile = logDir.resolve("log${currentSeconds()}.txt") - try { - XerusLogger.logToFile(logfile) - logger.config("Logging to $logfile") - GlobalScope.launch { - val logs = logDir.listFiles() - if (logs.size > 10) { - logs.asSequence().sortedByDescending { it.name }.drop(5).filter { - val timestamp = it.nameWithoutExtension.substring(3).toIntOrNull() ?: return@filter true - timestamp + 200_000 < currentSeconds() - }.also { - val count = it.count() - if (count > 0) - logger.finer("Deleting $count old logs") - }.forEach { it.delete() } - } - } - } catch (t: Throwable) { - showErrorSafe(t, "Can't log to $logfile!") - } + initLogging(args) + val logger = KotlinLogging.logger {} + if (!SystemUtils.javaVersion.startsWith("1.8")) { SimpleFrame { add(JTextArea("Please install and use Java 8!\nThe current version is ${SystemUtils.javaVersion}").apply { isEditable = false }) } return } logger.info("Version: $VERSION, Java version: ${SystemUtils.javaVersion}") - logger.config("Initializing Google Sheets API Service") + + logger.info("Initializing Google Sheets API Service") Sheets.initService("MonsterUtilities", GoogleCredential().createScoped(listOf(SheetsScopes.SPREADSHEETS_READONLY))) + + val checkUpdate = !args.contains("--no-update") && Settings.AUTOUPDATE() && jarLocation.toString().endsWith(".jar") App.launch("MonsterUtilities $VERSION", { stage -> stage.icons.addAll(arrayOf("img/icon64.png").map { getResource(it)?.let { Image(it.toExternalForm()) } - ?: null.apply { logger.warning("Resource $it not found") } + ?: null.apply { logger.warn("Resource $it not found!") } }) }, { - val scene = Scene(MonsterUtilities(), 800.0, 700.0) + val scene = Scene(MonsterUtilities(checkUpdate), 800.0, 700.0) scene.applySkin(Settings.SKIN()) scene }) diff --git a/src/main/xerus/monstercat/MonsterUtilities.kt b/src/main/xerus/monstercat/MonsterUtilities.kt index 0b66314..a065ab4 100644 --- a/src/main/xerus/monstercat/MonsterUtilities.kt +++ b/src/main/xerus/monstercat/MonsterUtilities.kt @@ -8,6 +8,7 @@ import javafx.scene.image.ImageView import javafx.scene.layout.VBox import kotlinx.coroutines.experimental.GlobalScope import kotlinx.coroutines.experimental.launch +import mu.KotlinLogging import org.controlsfx.dialog.ExceptionDialog import xerus.ktutil.* import xerus.ktutil.javafx.* @@ -26,7 +27,9 @@ import java.util.* import java.util.concurrent.TimeUnit import kotlin.reflect.KClass -class MonsterUtilities : VBox(), JFXMessageDisplay { +class MonsterUtilities(checkForUpdate: Boolean) : VBox(), JFXMessageDisplay { + + private val logger = KotlinLogging.logger { } val tabs: MutableList val tabPane: TabPane @@ -39,12 +42,12 @@ class MonsterUtilities : VBox(), JFXMessageDisplay { tabPane = TabPane() tabs = ArrayList() val startupTab = Settings.STARTUPTAB.get().takeUnless { it == "Previous" } ?: Settings.LASTTAB() - logger.fine("Startup tab: $startupTab") + logger.debug("Startup tab: $startupTab") fun addTab(tabClass: KClass) { try { val baseTab = tabClass.java.getDeclaredConstructor().newInstance() - logger.finer("New Tab: $baseTab") + logger.debug("New Tab: $baseTab") tabs.add(baseTab) val tab = Tab(baseTab.tabName, baseTab.asNode()) tab.isClosable = false @@ -67,10 +70,10 @@ class MonsterUtilities : VBox(), JFXMessageDisplay { Settings.LASTVERSION.put(VERSION) } else { GlobalScope.launch { - logger.fine("New version! Now running $VERSION, previously " + Settings.LASTVERSION()) + logger.info("New version! Now running $VERSION, previously " + Settings.LASTVERSION()) val f = Settings.DELETE() if (f.exists()) { - logger.config("Deleting older version $f...") + logger.info("Deleting older version $f...") val time = currentSeconds() var res: Boolean do { @@ -78,9 +81,9 @@ class MonsterUtilities : VBox(), JFXMessageDisplay { } while (!res && time + 10 > currentSeconds()) if (res) { Settings.DELETE.clear() - logger.config("Deleted $f!") + logger.info("Deleted $f!") } else - logger.warning("Couldn't delete older version residing in $f") + logger.warn("Couldn't delete older version residing in $f") } Settings.LASTVERSION.put(VERSION) } @@ -90,7 +93,7 @@ class MonsterUtilities : VBox(), JFXMessageDisplay { children.add(Player.box) fill(tabPane) - if (checkUpdate) + if (checkForUpdate) checkForUpdate() DiscordRPC.connect() } @@ -101,7 +104,7 @@ class MonsterUtilities : VBox(), JFXMessageDisplay { GlobalScope.launch { try { val latestVersion = URL("http://monsterutilities.bplaced.net/downloads/" + if (unstable) "unstable" else "latest").openConnection().getInputStream().reader().readLines().firstOrNull() - logger.fine("Latest version: $latestVersion") + logger.info("Latest version: $latestVersion") if (latestVersion == null || latestVersion.length > 50 || latestVersion == VERSION || (!userControlled && latestVersion == Settings.IGNOREVERSION())) { if (userControlled) showMessage("No update found!", "Updater", Alert.AlertType.INFORMATION) @@ -131,7 +134,7 @@ class MonsterUtilities : VBox(), JFXMessageDisplay { private fun update(version: String, unstable: Boolean = false) { val newFile = File(Settings.FILENAMEPATTERN().replace("%version%", version, true)).absoluteFile - logger.fine("Update initiated to $newFile") + logger.info("Update initiated to $newFile") val worker = object : Task() { init { updateTitle("Downloading Update") @@ -141,22 +144,22 @@ class MonsterUtilities : VBox(), JFXMessageDisplay { override fun call() { val connection = URL("http://monsterutilities.bplaced.net/downloads?download&version=" + if (unstable) "unstable" else version).openConnection() val contentLength = connection.contentLengthLong - logger.fine("Update to $version started, size ${contentLength.byteCountString()}") + logger.debug("Update to $version started, size ${contentLength.byteCountString()}") connection.getInputStream().copyTo(newFile.outputStream(), true, true) { updateProgress(it, contentLength) isCancelled } if (isCancelled) - logger.config("Update cancelled, deleting $newFile: ${newFile.delete().to("Success", "FAILED")}") + logger.info("Update cancelled, deleting $newFile: ${newFile.delete().to("Success", "FAILED")}") } override fun succeeded() { - if (isUnstable == unstable && location.toString().endsWith(".jar")) { - val jar = File(location.toURI()) + if (isUnstable == unstable && jarLocation.toString().endsWith(".jar")) { + val jar = File(jarLocation.toURI()) logger.info("Scheduling '$jar' for delete") Settings.DELETE.set(jar) } - logger.warning("Exiting for update to $version!") + logger.warn("Exiting for update to $version!") Settings.flush() newFile.setExecutable(true) @@ -167,7 +170,7 @@ class MonsterUtilities : VBox(), JFXMessageDisplay { if (!exited) { Platform.exit() - logger.warning("Exiting $VERSION!") + logger.warn("Exiting $VERSION!") } else { showAlert(Alert.AlertType.WARNING, "Error while updating", content = "The downloaded jar was not started successfully!") } @@ -251,7 +254,7 @@ class MonsterUtilities : VBox(), JFXMessageDisplay { } override fun showError(error: Throwable, title: String) { - logger.severe("$title: $error") + logger.error("$title: $error") onFx { val dialog = ExceptionDialog(error) dialog.initOwner(App.stage) diff --git a/src/main/xerus/monstercat/Settings.kt b/src/main/xerus/monstercat/Settings.kt index ff06f6a..11c7e90 100644 --- a/src/main/xerus/monstercat/Settings.kt +++ b/src/main/xerus/monstercat/Settings.kt @@ -4,6 +4,7 @@ import javafx.beans.value.ChangeListener import javafx.beans.value.ObservableValue import javafx.scene.control.Alert import javafx.scene.control.ButtonBar +import mu.KotlinLogging import xerus.ktutil.javafx.applySkin import xerus.ktutil.javafx.properties.listen import xerus.ktutil.preferences.SettingsNode @@ -12,11 +13,8 @@ import xerus.monstercat.tabs.availableColumns import xerus.monstercat.tabs.defaultColumns import java.io.File -val cacheDir: File - get() = (File("/var/tmp").takeIf { it.exists() } ?: File(System.getProperty("java.io.tmpdir"))) - .resolve("monsterutilities").apply { mkdirs() } - object Settings : SettingsNode("xerus/monsterutilities") { + private val logger = KotlinLogging.logger { } val PLAYERVOLUME = create("playerVolume", 0.4) val PLAYERSCROLLSENSITIVITY = create("playerSeekbarScrollSensitivity", 6.0) @@ -45,7 +43,7 @@ object Settings : SettingsNode("xerus/monsterutilities") { init { Settings.ENABLECACHE.listen { selected -> - logger.fine("Cache " + (if (selected) "en" else "dis") + "abled") + logger.debug("Cache " + (if (selected) "en" else "dis") + "abled") if (selected) FetchTab.writeCache() } diff --git a/src/main/xerus/monstercat/api/API.kt b/src/main/xerus/monstercat/api/API.kt index 5fe438a..1badb3b 100644 --- a/src/main/xerus/monstercat/api/API.kt +++ b/src/main/xerus/monstercat/api/API.kt @@ -1,14 +1,15 @@ package xerus.monstercat.api +import mu.KotlinLogging import xerus.ktutil.to import xerus.ktutil.toInt import xerus.monstercat.api.response.Track import xerus.monstercat.api.response.declaredKeys -import xerus.monstercat.logger import java.net.URLEncoder import java.util.regex.Pattern object API { + private val logger = KotlinLogging.logger { } /** Finds the best match for the given [title] and [artists] */ fun find(title: String, artists: String): Track? { @@ -18,7 +19,7 @@ object API { .filter { it.isNotBlank() } .forEach { connection.addQuery("fuzzy", "title," + it.trim()) } val results = connection.getTracks() - logger.finest("Found $results for $connection") + logger.debug("Found $results for $connection") return results?.maxBy { track -> track.init() track.artists.map { artists.contains(it.name).to(3, 0) }.average() + diff --git a/src/main/xerus/monstercat/api/APIConnection.kt b/src/main/xerus/monstercat/api/APIConnection.kt index 76b6a94..4103561 100644 --- a/src/main/xerus/monstercat/api/APIConnection.kt +++ b/src/main/xerus/monstercat/api/APIConnection.kt @@ -2,6 +2,7 @@ package xerus.monstercat.api +import mu.KotlinLogging import org.apache.http.HttpResponse import org.apache.http.client.config.CookieSpecs import org.apache.http.client.config.RequestConfig @@ -14,12 +15,13 @@ import xerus.monstercat.Sheets import xerus.monstercat.api.response.* import xerus.monstercat.downloader.CONNECTSID import xerus.monstercat.downloader.QUALITY -import xerus.monstercat.logger import java.io.IOException import java.io.InputStream import java.net.URI import kotlin.reflect.KClass +private val logger = KotlinLogging.logger { } + /** eases query creation to the Monstercat API */ class APIConnection(vararg path: String) : HTTPQuery() { @@ -59,7 +61,7 @@ class APIConnection(vararg path: String) : HTTPQuery() { private var httpGet: HttpGet? = null fun execute() { httpGet = HttpGet(uri) - logger.finest("$this connecting") + logger.trace("$this connecting") val conf = RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD).build() response = HttpClientBuilder.create().setDefaultRequestConfig(conf).setDefaultCookieStore(cookies()).build().execute(httpGet) } diff --git a/src/main/xerus/monstercat/api/Cache.kt b/src/main/xerus/monstercat/api/Cache.kt index 1b19cef..1434fd2 100644 --- a/src/main/xerus/monstercat/api/Cache.kt +++ b/src/main/xerus/monstercat/api/Cache.kt @@ -1,5 +1,6 @@ package xerus.monstercat.api +import mu.KotlinLogging import xerus.ktutil.currentSeconds import xerus.ktutil.helpers.Refresher import xerus.monstercat.Settings @@ -7,10 +8,10 @@ import xerus.monstercat.api.response.Release import xerus.monstercat.api.response.Track import xerus.monstercat.cacheDir import xerus.monstercat.downloader.CONNECTSID -import xerus.monstercat.logger import java.io.File object Releases : Refresher() { + private val logger = KotlinLogging.logger { } private const val SEPARATOR = ";;" @@ -29,7 +30,7 @@ object Releases : Refresher() { } override suspend fun doRefresh() { - logger.finer("Release refresh requested") + logger.debug("Release refresh requested") val releaseConnection = APIConnection("catalog", "release") .fields(Release::class).limit(((currentSeconds() - lastRefresh) / 80_000).coerceIn(2, 5)) lastRefresh = currentSeconds() @@ -41,7 +42,7 @@ object Releases : Refresher() { return } if (releases.containsAll(rel)) { - logger.finer("Releases are already up to date!") + logger.debug("Releases are already up to date!") if (!releaseCache.exists() && Settings.ENABLECACHE()) writeReleases() return @@ -49,20 +50,20 @@ object Releases : Refresher() { val ind = releases.lastIndexOf(rel.last()) if (ind == -1) { - logger.fine("Full Release refresh initiated") + logger.info("Full Release refresh initiated") releaseConnection.removeQuery("limit").getReleases()?.let { releases.clear() releases.addAll(it.asReversed()) } ?: run { - logger.warning("Release refresh failed!") + logger.warn("Release refresh failed!") return } - logger.fine("Found ${releases.size} Releases") + logger.info("Found ${releases.size} Releases") } else { val s = releases.size releases.removeAll(releases.subList(ind, releases.size)) releases.addAll(rel.asReversed()) - logger.fine("${releases.size - s} new Releases added, now at ${releases.size}") + logger.info("${releases.size - s} new Releases added, now at ${releases.size}") } if (Settings.ENABLECACHE()) writeReleases() @@ -73,7 +74,7 @@ object Releases : Refresher() { for (r in releases) it.appendln(r.serialize().joinToString(SEPARATOR)) } - logger.fine("Wrote ${releases.size} Releases to Cache") + logger.debug("Wrote ${releases.size} Releases to Cache") } private fun readReleases(): Boolean { @@ -83,7 +84,7 @@ object Releases : Refresher() { } true } catch (e: Throwable) { - logger.finer("Cache corrupted - clearing: $e") + logger.debug("Cache corrupted - clearing: $e", e) releaseCache.delete() releases.clear() false diff --git a/src/main/xerus/monstercat/api/DiscordRPC.kt b/src/main/xerus/monstercat/api/DiscordRPC.kt index 5da8168..5ad51aa 100644 --- a/src/main/xerus/monstercat/api/DiscordRPC.kt +++ b/src/main/xerus/monstercat/api/DiscordRPC.kt @@ -5,12 +5,13 @@ import be.bluexin.drpc4k.jna.RPCHandler import kotlinx.coroutines.experimental.GlobalScope import kotlinx.coroutines.experimental.delay import kotlinx.coroutines.experimental.launch +import mu.KotlinLogging import xerus.ktutil.getResource import xerus.ktutil.javafx.properties.listen import xerus.ktutil.javafx.ui.App -import xerus.monstercat.logger object DiscordRPC { + private val logger = KotlinLogging.logger { } private val apiKey get() = getResource("discordapi")!!.readText() @@ -28,12 +29,12 @@ object DiscordRPC { delay(delay) if (!RPCHandler.connected.get()) { RPCHandler.onReady = { - logger.fine("Discord Rich Presence ready!") + logger.info("Ready") RPCHandler.updatePresence(idlePresence) } - RPCHandler.onErrored = { errorCode, message -> logger.warning("Discord RPC Error #$errorCode, $message") } + RPCHandler.onErrored = { errorCode, message -> logger.warn("Discord RPC Error #$errorCode, $message") } RPCHandler.connect(apiKey) - logger.config("Connecting Discord RPC") + logger.info("Connecting") App.stage.setOnHiding { disconnect() } } } @@ -41,10 +42,10 @@ object DiscordRPC { fun disconnect() { if (RPCHandler.connected.get()) { - logger.config("Disconnecting Discord RPC") + logger.info("Disconnecting") RPCHandler.disconnect() RPCHandler.finishPending() - logger.finer("Disconnected Discord RPC") + logger.debug("Disconnected") } } @@ -52,7 +53,7 @@ object DiscordRPC { RPCHandler.ifConnectedOrLater { RPCHandler.updatePresence(presence) if (presence != idlePresence) - logger.finer("Changed Discord RPC to '${presence.details} - ${presence.state}'") + logger.debug("Changed Rich Presence to '${presence.details} - ${presence.state}'") } } diff --git a/src/main/xerus/monstercat/api/Player.kt b/src/main/xerus/monstercat/api/Player.kt index bff6a28..00cdbba 100644 --- a/src/main/xerus/monstercat/api/Player.kt +++ b/src/main/xerus/monstercat/api/Player.kt @@ -12,6 +12,7 @@ import javafx.util.Duration import kotlinx.coroutines.experimental.GlobalScope import kotlinx.coroutines.experimental.delay import kotlinx.coroutines.experimental.launch +import mu.KotlinLogging import xerus.ktutil.javafx.* import xerus.ktutil.javafx.properties.SimpleObservable import xerus.ktutil.javafx.properties.dependOn @@ -23,11 +24,11 @@ import xerus.ktutil.square import xerus.monstercat.Settings import xerus.monstercat.api.response.Release import xerus.monstercat.api.response.Track -import xerus.monstercat.logger import java.util.logging.Level import kotlin.math.pow object Player : FadingHBox(true, targetHeight = 25) { + private val logger = KotlinLogging.logger { } private val seekBar = ProgressBar(0.0).apply { id("seek-bar") @@ -120,7 +121,7 @@ object Player : FadingHBox(true, targetHeight = 25) { showBack("$track is currently not available for streaming!") return } - logger.finer("Loading $track from $hash") + logger.debug("Loading $track from $hash") activePlayer.value = MediaPlayer(Media("https://s3.amazonaws.com/data.monstercat.com/blobs/$hash")) updateVolume() playing("Loading $track") @@ -136,7 +137,7 @@ object Player : FadingHBox(true, targetHeight = 25) { } } setOnError { - logger.log(Level.WARNING, "Error loading $track: $error", error) + logger.warn("Error loading $track: $error", error) showBack("Error loading $track: ${error.message?.substringAfter(": ")}") } } diff --git a/src/main/xerus/monstercat/downloader/Download.kt b/src/main/xerus/monstercat/downloader/Download.kt index bd869db..41be10e 100644 --- a/src/main/xerus/monstercat/downloader/Download.kt +++ b/src/main/xerus/monstercat/downloader/Download.kt @@ -2,12 +2,12 @@ package xerus.monstercat.downloader import com.google.common.io.CountingInputStream import javafx.concurrent.Task +import mu.KotlinLogging import xerus.ktutil.* import xerus.monstercat.api.APIConnection import xerus.monstercat.api.response.MusicItem import xerus.monstercat.api.response.Release import xerus.monstercat.api.response.Track -import xerus.monstercat.logger import java.io.FileOutputStream import java.io.InputStream import java.nio.file.Path @@ -37,6 +37,8 @@ private inline val basePath private fun String.addFormatSuffix() = "$this.${QUALITY().split('_')[0]}" +private val logger = KotlinLogging.logger { } + abstract class Download(val item: MusicItem, val coverUrl: String) : Task() { init { @@ -76,7 +78,7 @@ abstract class Download(val item: MusicItem, val coverUrl: String) : Task( private val buffer = ByteArray(1024) protected fun downloadFile(path: Path) { val file = path.toFile() - logger.finest("Downloading $file") + logger.trace("Downloading $file") updateMessage(file.name) val partFile = file.resolveSibling(file.name + ".part") val output = FileOutputStream(partFile) @@ -97,7 +99,7 @@ abstract class Download(val item: MusicItem, val coverUrl: String) : Task( partFile.renameTo(file) } } catch (e: Exception) { - logger.throwing("Download", "downloadFile", e) + logger.error("Error while downloading to $path", e) } finally { output.close() } diff --git a/src/main/xerus/monstercat/downloader/TabDownloader.kt b/src/main/xerus/monstercat/downloader/TabDownloader.kt index 5c339c7..18bbec1 100644 --- a/src/main/xerus/monstercat/downloader/TabDownloader.kt +++ b/src/main/xerus/monstercat/downloader/TabDownloader.kt @@ -33,7 +33,6 @@ import xerus.monstercat.api.APIConnection import xerus.monstercat.api.CookieValidity import xerus.monstercat.api.response.* import xerus.monstercat.globalThreadPool -import xerus.monstercat.logger import xerus.monstercat.monsterUtilities import xerus.monstercat.tabs.VTab import java.time.LocalDate @@ -241,7 +240,7 @@ class TabDownloader : VTab() { APIConnection("catalog", "release", it.value.id, "tracks").getTracks()?.map { it.toString().normalised } } } - logger.finer("Fetching Tracks for ${deferred.size} Releases") + logger.debug("Fetching Tracks for ${deferred.size} Releases") val max = deferred.size val tracksToExclude = HashSet(max) var progress = 0 @@ -253,7 +252,7 @@ class TabDownloader : VTab() { updateProgress(progress++, max) } } - logger.finest { "Tracks to exclude: " + tracksToExclude.joinToString() } + logger.trace { "Tracks to exclude: " + tracksToExclude.joinToString() } context.close() if (!isCancelled) { if (tracksToExclude.isEmpty() && albums.isNotEmpty()) { @@ -323,7 +322,7 @@ class TabDownloader : VTab() { trackView.clearPredicate() val releases: List = releaseView.checkedItems.filter { it.isLeaf }.map { it.value } val tracks: List = trackView.checkedItems.filter { it.isLeaf }.map { it.value } - logger.fine("Starting Downloader for ${releases.size} Releases and ${tracks.size} Tracks") + logger.info("Starting Downloader for ${releases.size} Releases and ${tracks.size} Tracks") items = tracks + releases total = items.size onFx { @@ -362,7 +361,7 @@ class TabDownloader : VTab() { counter = GlobalScope.launch { val estimate = ((estimatedLength / lengths.sum() + total / done - 2) * timer.time() / 1000).roundToLong() time = if (time > 0) (time * 9 + estimate) / 10 else estimate - logger.finest("Estimate: ${formatTimeDynamic(estimate, estimate.coerceAtLeast(60))} Weighed: ${formatTimeDynamic(time, time.coerceAtLeast(60))}") + logger.trace("Estimate: ${formatTimeDynamic(estimate, estimate.coerceAtLeast(60))} Weighed: ${formatTimeDynamic(time, time.coerceAtLeast(60))}") while (time > 0) { onFx { progressLabel.text = "$done / $total Errors: $e - Estimated time left: " + formatTimeDynamic(time, time.coerceAtLeast(60)) @@ -414,16 +413,16 @@ class TabDownloader : VTab() { download.setOnFailed { errors.value++ val exception = download.exception - logger.throwing("Downloader", "download", exception) + logger.error("$download failed with $exception", exception) log("Error downloading ${download.item}: " + if (exception is ParserException) exception.message else exception.str()) } var added = false try { globalThreadPool.execute(download) onFx { tasks.add(download); added = true } - } catch (e: Throwable) { - logger.throwing("TabDownloader", "downloader", e) - log("Could not start download for $item: $e") + } catch (exception: Throwable) { + logger.error("$download could not be started in TabDownloader because of $exception", exception) + log("Could not start download for $item: $exception") } while (!added || tasks.size >= DOWNLOADTHREADS()) delay(200) diff --git a/src/main/xerus/monstercat/tabs/BaseTab.kt b/src/main/xerus/monstercat/tabs/BaseTab.kt index 542bc6b..3438ee1 100644 --- a/src/main/xerus/monstercat/tabs/BaseTab.kt +++ b/src/main/xerus/monstercat/tabs/BaseTab.kt @@ -3,6 +3,7 @@ package xerus.monstercat.tabs import javafx.scene.control.Control import javafx.scene.layout.Pane import javafx.scene.layout.VBox +import mu.KotlinLogging import org.controlsfx.validation.decoration.GraphicValidationDecoration val minimalValidationDecorator = object : GraphicValidationDecoration() { @@ -19,6 +20,8 @@ interface BaseTab { } abstract class VTab : VBox(), BaseTab { + protected val logger = KotlinLogging.logger(javaClass.name) + init { styleClass.add("vtab") } diff --git a/src/main/xerus/monstercat/tabs/FetchTab.kt b/src/main/xerus/monstercat/tabs/FetchTab.kt index 84d19fe..b4b3977 100644 --- a/src/main/xerus/monstercat/tabs/FetchTab.kt +++ b/src/main/xerus/monstercat/tabs/FetchTab.kt @@ -5,6 +5,8 @@ import javafx.collections.ObservableList import javafx.scene.Node import javafx.scene.control.Button import javafx.scene.control.Label +import mu.KotlinLogging +import org.slf4j.Logger import xerus.ktutil.helpers.DelayedRefresher import xerus.ktutil.helpers.RoughMap import xerus.ktutil.helpers.SimpleRefresher @@ -17,7 +19,6 @@ import xerus.monstercat.Sheets.fetchMCatalogTab import xerus.monstercat.api.Releases import java.io.* - abstract class FetchTab : VTab() { val cols = RoughMap() @@ -32,7 +33,7 @@ abstract class FetchTab : VTab() { val sheetFetcher = SimpleRefresher { if (this::class != TabGenres::class) { onFx { setPlaceholder(Label("Fetching...")) } - logger.fine("Fetching MCatalog $tabName") + logger.debug("Fetching $tabName") val sheet = fetchMCatalogTab(tabName, request) if (sheet != null) { readSheet(sheet) @@ -41,7 +42,7 @@ abstract class FetchTab : VTab() { restoreCache() onFx { if (data.isEmpty()) { - logger.finer("Showing retry button for $tabName because data is empty") + logger.debug("Showing retry button for $tabName because data is empty") setPlaceholder(retryButton) } else setPlaceholder(Label("No matches found!")) @@ -49,7 +50,7 @@ abstract class FetchTab : VTab() { } else { // todo use Genre sheet onFx { setPlaceholder(Label("No matches found!")) } - logger.fine("Loading $tabName") + logger.debug("Loading $tabName") @Suppress("UNCHECKED_CAST") readSheet(ObjectInputStream(TabGenres::class.java.getResourceAsStream("/Genres")).readObject() as MutableList>) } @@ -94,7 +95,7 @@ abstract class FetchTab : VTab() { private fun writeCache(sheet: Any) { if (!Settings.ENABLECACHE()) return - logger.fine("Writing cache file $cacheFile") + logger.debug("Writing cache file $cacheFile") try { sheet.writeToFile(cacheFile) } catch (e: IOException) { @@ -107,11 +108,11 @@ abstract class FetchTab : VTab() { return try { readSheet(cacheFile.readToObject()) - logger.fine("Restored cache file $cacheFile") + logger.debug("Restored cache file $cacheFile") showNotification(snackbarTextCache) } catch (ignored: FileNotFoundException) { } catch (e: Throwable) { - logger.throwing(javaClass.simpleName, "restoreCache", e) + logger.error("$this failed to restore Cache", e) cacheFile.delete() } } diff --git a/src/main/xerus/monstercat/tabs/TabCatalog.kt b/src/main/xerus/monstercat/tabs/TabCatalog.kt index 393f8be..17ebf3e 100644 --- a/src/main/xerus/monstercat/tabs/TabCatalog.kt +++ b/src/main/xerus/monstercat/tabs/TabCatalog.kt @@ -14,7 +14,6 @@ import xerus.ktutil.preferences.multiSeparator import xerus.ktutil.toLocalDate import xerus.monstercat.Settings import xerus.monstercat.api.Player -import xerus.monstercat.logger import java.time.LocalTime import kotlin.math.absoluteValue @@ -72,7 +71,7 @@ class TabCatalog : TableTab() { val colValue = { list: List -> cols.find(colName)?.let { list[it] }.also { if (it == null && notFound.add(colName)) { - logger.warning("Column $colName not found!") + logger.warn("Column $colName not found!") } } } @@ -98,7 +97,7 @@ class TabCatalog : TableTab() { newColumns.add(col) col.isVisible = visibleColumns.contains(colName, true) } catch (e: Exception) { - logger.throwing("TabCatalog", "column initialization", e) + logger.warn("TabCatalog column initialization failed with $e", e) } } table.columns.setAll(newColumns) @@ -121,7 +120,7 @@ class TabCatalog : TableTab() { col.prefWidth = avg col.minWidth = (avg - deviation).coerceAtLeast(Label(col.text).textWidth().plus(5).coerceAtLeast(30.0)) col.maxWidth = widths.max()!! - logger.finest("Catalog column %-11s avg %3.0f +-%2.0f max %3.0f min %2.0f".format(col.text, avg, deviation, col.maxWidth, col.minWidth)) + logger.trace("Catalog column %-11s avg %3.0f +-%2.0f max %3.0f min %2.0f".format(col.text, avg, deviation, col.maxWidth, col.minWidth)) } } } diff --git a/src/main/xerus/monstercat/tabs/TabGenres.kt b/src/main/xerus/monstercat/tabs/TabGenres.kt index 42c4b2f..b0e34d8 100644 --- a/src/main/xerus/monstercat/tabs/TabGenres.kt +++ b/src/main/xerus/monstercat/tabs/TabGenres.kt @@ -11,8 +11,6 @@ import xerus.ktutil.javafx.* import xerus.ktutil.javafx.properties.listen import xerus.ktutil.javafx.ui.FilterableTreeItem import xerus.monstercat.Settings.GENRECOLORINTENSITY -import xerus.monstercat.Sheets -import xerus.monstercat.logger val genreColors = RoughMap() val genreColor = { item: String? -> @@ -32,7 +30,7 @@ class TabGenres : FetchTab() { val searchField = TextField() VBox.setMargin(searchField, Insets(0.0, 0.0, 6.0, 0.0)) // apparently can't set this in css val root = FilterableTreeItem(Row()) - root.bindPredicate(searchField.textProperty(), { row, text -> row.subList(0, 3).any { it.contains(text, true) } }) + root.bindPredicate(searchField.textProperty()) { row, text -> row.subList(0, 3).any { it.contains(text, true) } } view.isShowRoot = false data.addListener(InvalidationListener { view.root = root @@ -41,7 +39,7 @@ class TabGenres : FetchTab() { var curLevel = 0 val hex = cols.find("Hex") - if (hex == null) logger.warning("No hex Column found!") + if (hex == null) logger.warn("No hex Column found!") var style = "" for (list in data) { @@ -50,7 +48,7 @@ class TabGenres : FetchTab() { val row = Row(10, *list.toTypedArray()) val nextLevel = row.indexOfFirst { it.isNotEmpty() } if (nextLevel < curLevel) - repeat(curLevel - nextLevel) { cur = cur.parent as? FilterableTreeItem ?: cur.also { logger.warning("$cur should have a parent!") } } + repeat(curLevel - nextLevel) { cur = cur.parent as? FilterableTreeItem ?: cur.also { logger.warn("$cur should have a parent!") } } if (hex != null) { if (nextLevel == 0) { diff --git a/src/main/xerus/monstercat/tabs/TabSettings.kt b/src/main/xerus/monstercat/tabs/TabSettings.kt index 89c1f7a..b9c5933 100644 --- a/src/main/xerus/monstercat/tabs/TabSettings.kt +++ b/src/main/xerus/monstercat/tabs/TabSettings.kt @@ -10,6 +10,7 @@ import javafx.scene.paint.Color import javafx.scene.paint.Paint import javafx.stage.Stage import javafx.stage.StageStyle +import mu.KotlinLogging import org.apache.http.client.methods.HttpPost import org.apache.http.entity.mime.HttpMultipartMode import org.apache.http.entity.mime.MultipartEntityBuilder @@ -94,9 +95,9 @@ class TabSettings : VTab() { ) } - lateinit var dialog: Dialog> + lateinit var dialog: Dialog fun feedback() { - dialog = Dialog>().apply { + dialog = Dialog().apply { (dialogPane.scene.window as Stage).initWindowOwner(App.stage) val send = ButtonType("Send", ButtonBar.ButtonData.YES) dialogPane.buttonTypes.addAll(send, ButtonType.CANCEL) @@ -128,24 +129,24 @@ class TabSettings : VTab() { return@setResultConverter if (it.buttonData == ButtonBar.ButtonData.CANCEL_CLOSE) null else { - subjectField.text to messageArea.text + Feedback(subjectField.text, messageArea.text) } } } dialog.show() dialog.resultProperty().listen { result -> - logger.finest("Submitting: $result") + logger.trace("Submitting: $result") result?.run { - sendFeedback(first, second) + sendFeedback(subject, message) } } } /** @return false if it should be retried */ private fun sendFeedback(subject: String, message: String) { - val zipFile = cacheDir.resolve("logs.zip") + val zipFile = cacheDir.resolve("report.zip") System.getProperties().list(PrintStream(cacheDir.resolve("System.properties.txt").outputStream())) - val files = cacheDir.listFiles() + logDir.listFiles() + val files = cacheDir.walk() ZipOutputStream(zipFile.outputStream()).use { zip -> files.filter { it.isFile && it != zipFile }.forEach { zip.putNextEntry(ZipEntry(it.toString().removePrefix(cacheDir.toString()))) @@ -154,7 +155,7 @@ class TabSettings : VTab() { } } } - logger.config("Sending request with subject '$subject' and ${files.size} logs with a packed size of ${zipFile.length().byteCountString()}") + logger.info("Sending feedback '$subject' with a packed size of ${zipFile.length().byteCountString()}") val entity = MultipartEntityBuilder.create() .setMode(HttpMultipartMode.BROWSER_COMPATIBLE) .addTextBody("subject", subject) @@ -165,7 +166,7 @@ class TabSettings : VTab() { postRequest.entity = entity val response = HttpClientBuilder.create().build().execute(postRequest) val status = response.statusLine - logger.finer("Response: $status") + logger.debug("Feedback Response: $status") if (status.statusCode == 200) { monsterUtilities.showMessage("Your feedback was submitted successfully!") } else { @@ -184,4 +185,6 @@ class TabSettings : VTab() { } } + data class Feedback(val subject: String, val message: String) + } diff --git a/src/main/xerus/monstercat/tabs/TabSound.kt b/src/main/xerus/monstercat/tabs/TabSound.kt index 8f856d1..59d3b4a 100644 --- a/src/main/xerus/monstercat/tabs/TabSound.kt +++ b/src/main/xerus/monstercat/tabs/TabSound.kt @@ -37,13 +37,11 @@ class TabSound : VTab() { // Sync view with equalizer model eq.enabledProperty().bind(Settings.ENABLEEQUALIZER) - var i = 0 - for (band in eq.bands) { + for ((i, band) in eq.bands.withIndex()) { while (eqModel.size <= i) eqModel.add(band.gain) val index: Int = i - eqBox.children.add(createEQBandView(band, eqModel[index], { eqModel[index] = it })) - i++ + eqBox.children.add(createEQBandView(band, eqModel[index]) { eqModel[index] = it }) } } ?: Settings.ENABLEEQUALIZER.unbind() } diff --git a/src/resources/META-INF/services/ch.qos.logback.classic.spi.Configurator b/src/resources/META-INF/services/ch.qos.logback.classic.spi.Configurator new file mode 100644 index 0000000..3529e43 --- /dev/null +++ b/src/resources/META-INF/services/ch.qos.logback.classic.spi.Configurator @@ -0,0 +1 @@ +xerus.monstercat.LogbackConfigurator \ No newline at end of file From 5fe6419586e1c24ef828dedbc5c6ef5dc884ffc4 Mon Sep 17 00:00:00 2001 From: Xerus <27jf@web.de> Date: Sun, 16 Sep 2018 19:06:39 +0200 Subject: [PATCH 7/7] Fix logging threshold & commandline parameter --- build.gradle.kts | 4 ++-- src/main/xerus/monstercat/Logging.kt | 17 +++++++++++------ 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index d9ad749..c871e3e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -53,7 +53,7 @@ dependencies { implementation("org.controlsfx", "controlsfx", "8.40.14") implementation("ch.qos.logback", "logback-classic", "1.2.3") - implementation("com.github.Bluexin", "drpc4k", "-SNAPSHOT") + implementation("com.github.Xerus2000", "drpc4k", "-SNAPSHOT") implementation("org.apache.httpcomponents", "httpmime", "4.5.+") implementation("com.google.apis", "google-api-services-sheets", "v4-rev542-1.25.0") @@ -74,7 +74,7 @@ tasks { "run"(JavaExec::class) { group = MAIN // Usage: gradle run -Dargs="--loglevel trace" - args = System.getProperty("args", "").split(" ") + args = System.getProperty("args", "--loglevel debug").split(" ") } "shadowJar"(ShadowJar::class) { diff --git a/src/main/xerus/monstercat/Logging.kt b/src/main/xerus/monstercat/Logging.kt index 908e3c1..73a3927 100644 --- a/src/main/xerus/monstercat/Logging.kt +++ b/src/main/xerus/monstercat/Logging.kt @@ -4,6 +4,7 @@ import ch.qos.logback.classic.Level import ch.qos.logback.classic.LoggerContext import ch.qos.logback.classic.encoder.PatternLayoutEncoder import ch.qos.logback.classic.filter.LevelFilter +import ch.qos.logback.classic.filter.ThresholdFilter import ch.qos.logback.classic.spi.Configurator import ch.qos.logback.classic.spi.ILoggingEvent import ch.qos.logback.core.ConsoleAppender @@ -26,12 +27,16 @@ private var logLevel: Level = Level.WARN internal fun initLogging(args: Array) { args.indexOf("--loglevel").takeIf { it > -1 }?.let { - logLevel = args.getOrNull(it)?.let { Level.toLevel(it) } ?: throw IllegalArgumentException("No loglevel specified!") + logLevel = args.getOrNull(it + 1)?.let { Level.toLevel(it, null) } ?: run { + println("WARNING: Loglevel argument given without a valid value! Use one of {OFF, ERROR, WARN, INFO, DEBUG, TRACE, ALL}") + return@let + } } Thread.setDefaultUncaughtExceptionHandler { thread, ex -> LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME).warn("Uncaught exception in $thread: ${ex.getStackTraceString()}") } val logger = KotlinLogging.logger { } + logger.info("Console loglevel: $logLevel") logger.info("Logging to $logFile") GlobalScope.launch { val logs = logDir.listFiles() @@ -62,15 +67,13 @@ internal class LogbackConfigurator : ContextAwareBase(), Configurator { name = "console" context = lc this.encoder = encoder - addFilter(LevelFilter().apply { - setLevel(logLevel) + addFilter(ThresholdFilter().apply { + setLevel(logLevel.toString()) + start() }) start() } - RollingFileAppender().apply { - this.rollingPolicy - } val fileAppender = FileAppender().apply { name = "file" file = logFile.toString() @@ -80,6 +83,8 @@ internal class LogbackConfigurator : ContextAwareBase(), Configurator { } val rootLogger = lc.getLogger(Logger.ROOT_LOGGER_NAME) + if(logLevel.levelInt < Level.DEBUG_INT) + rootLogger.level = logLevel rootLogger.addAppender(consoleAppender) rootLogger.addAppender(fileAppender) }