Skip to content

Commit

Permalink
sync playcounts from last.fm (#17)
Browse files Browse the repository at this point in the history
  • Loading branch information
wakingrufus authored Oct 20, 2022
1 parent 8902dd2 commit 884d002
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ class JfxMediaPlayerController(

private fun playNext() {
queue.firstOrNull()?.also { track ->
if(!track.file.exists()){
if (!track.file.exists()) {
library.removeTrack(track)
playNext()
}
Expand Down Expand Up @@ -147,6 +147,10 @@ class JfxMediaPlayerController(
scrobbledProperty.set(false)
GlobalScope.launch(Dispatchers.Default) {
lastFm.value?.nowPlaying(track)
val lastFmCount = lastFm.value.getPlaycount(track) ?: 0
if (lastFmCount > track.playCount) {
library.updatePlayCount(track, lastFmCount)
}
}
GlobalScope.launch(Dispatchers.JavaFx) {
nowPlayingProperty.set(track)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ import org.jaudiotagger.audio.AudioFileIO
import org.jaudiotagger.audio.mp3.MP3File
import org.jaudiotagger.tag.FieldKey
import org.jaudiotagger.tag.datatype.DataTypes
import org.jaudiotagger.tag.id3.*
import org.jaudiotagger.tag.id3.framebody.AbstractFrameBodyTextInfo
import org.jaudiotagger.tag.id3.ID3v23Frames
import org.jaudiotagger.tag.id3.ID3v23Tag
import java.io.File
import java.io.FileReader
import java.io.FileWriter
Expand Down Expand Up @@ -136,15 +136,19 @@ class ObservableLibrary(val rootDir: File) : Logging {
}

fun countPlay(track: Track) {
track.playCount++
updatePlayCount(track, track.playCount + 1)
}

fun updatePlayCount(track: Track, count: Int) {
track.playCount = count
val audioFile = AudioFileIO.read(track.file)
if (audioFile is MP3File) {
if (audioFile.hasID3v2Tag()) {
val v2tag = audioFile.iD3v2Tag
val countFrame = v2tag.getFirstField(ID3v23Frames.FRAME_ID_V3_PLAY_COUNTER)
?: v2tag.createFrame(ID3v23Frames.FRAME_ID_V3_PLAY_COUNTER)
val body = countFrame.body
body.setObjectValue(DataTypes.OBJ_NUMBER, track.playCount)
body.setObjectValue(DataTypes.OBJ_NUMBER, count)
v2tag.setFrame(countFrame)
AudioFileIO.write(audioFile)
createCSVFile()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
package com.github.wakingrufus.jamm.lastfm

import com.github.kittinunf.fuel.core.ResponseResultOf
import com.github.kittinunf.fuel.json.responseJson
import com.github.kittinunf.result.Result
import com.github.wakingrufus.jamm.common.Track
import com.github.wakingrufus.jamm.desktop.Logging
import com.github.wakingrufus.jamm.desktop.globalLogger
import com.github.wakingrufus.jamm.desktop.logger
import org.slf4j.Logger
import java.nio.charset.StandardCharsets
import java.time.Instant

class LastFmClient(val sessionKey: String) : Logging {
var username: String? = null
fun scrobble(time: Instant, track: Track) {
val args = mutableListOf(
"artist" to track.artist.name,
Expand Down Expand Up @@ -45,6 +49,53 @@ class LastFmClient(val sessionKey: String) : Logging {
it.logError(logger())
}
}

fun getUserName(): String? {
val result = signedPost("user.getInfo", sessionKey, emptyList()).responseJson()
return when (result.third) {
is Result.Success -> result.third.get().obj().getJSONObject("user").getString("name")
is Result.Failure -> {
globalLogger().warn(result.second.responseMessage)
globalLogger().warn(result.second.body().toByteArray().toString(StandardCharsets.UTF_8))
null
}
}
}

fun getPlaycount(track: Track): Int? {
if (username == null) {
username = getUserName()
logger().debug("user=$username")
}
val args = mutableListOf<Pair<String, Any>>()
username?.also {
args.add("username" to it)
}
args.add("artist" to track.artist.name)
args.add("track" to track.title)
// track.musicBrainzTrackId?.takeIf { it.isNotBlank() }.also {
// if (it != null) {
// args.add("mbid" to it)
// } else {
// args.add("artist" to track.artist.name)
// args.add("track" to track.title)
// }
// }
val result = unAuthedSignedCall("track.getInfo", args).responseJson()
return if (result.third is Result.Failure) {
globalLogger().warn(result.second.responseMessage)
globalLogger().warn(result.second.body().toByteArray().toString(StandardCharsets.UTF_8))
null
} else {
val jsonObj = result.third.get().obj()
if (jsonObj.has("error")) {
logger().warn(result.third.get().obj().toString())
null
} else {
result.third.get().obj().getJSONObject("track").getInt("userplaycount")
}
}
}
}

fun ResponseResultOf<ByteArray>.logError(logger: Logger) {
Expand Down

0 comments on commit 884d002

Please sign in to comment.