Files
MusicServer/internal/backend/music.go
Sebastian 806e88adeb
All checks were successful
Build / build (push) Successful in 2m35s
#1 - Created request to check newest version of the app
#2 - Added request to download the newest version of the app
#3 - Added request to check progress during sync
#4 - Now blocking all request while sync is in progress
#5 - Implemented ants for thread pooling
#6 - Changed the sync request to now only start the sync
2025-08-23 11:36:03 +02:00

311 lines
7.0 KiB
Go

package backend
import (
"log"
"math/rand"
"music-server/internal/db"
"music-server/internal/db/repository"
"os"
"strconv"
"strings"
)
type SongInfo struct {
Game string `json:"Game"`
GamePlayed int32 `json:"GamePlayed"`
Song string `json:"Song"`
SongPlayed int32 `json:"SongPlayed"`
CurrentlyPlaying bool `json:"CurrentlyPlaying"`
SongNo int `json:"SongNo"`
}
var currentSong = -1
var gamesNew []repository.Game
var songQueNew []repository.Song
var lastFetchedNew repository.Song
var repo *repository.Queries
func initRepo() {
if repo == nil {
repo = repository.New(db.Dbpool)
}
}
func getAllGames() []repository.Game {
if len(gamesNew) == 0 {
initRepo()
gamesNew, _ = repo.FindAllGames(db.Ctx)
}
return gamesNew
}
func GetSoundCheckSong() string {
files, err := os.ReadDir("songs")
if err != nil {
log.Fatal(err)
}
fileInfo := files[rand.Intn(len(files))]
return "songs/" + fileInfo.Name()
}
func Reset() {
songQueNew = nil
currentSong = -1
initRepo()
gamesNew, _ = repo.FindAllGames(db.Ctx)
}
func AddLatestToQue() {
if lastFetchedNew.Path != "" {
currentSong = len(songQueNew)
songQueNew = append(songQueNew, lastFetchedNew)
lastFetchedNew = repository.Song{}
}
}
func AddLatestPlayed() {
if len(songQueNew) == 0 {
return
}
currentSongData := songQueNew[currentSong]
initRepo()
repo.AddGamePlayed(db.Ctx, currentSongData.GameID)
repo.AddSongPlayed(db.Ctx, repository.AddSongPlayedParams{GameID: currentSongData.GameID, SongName: currentSongData.SongName})
}
func SetPlayed(songNumber int) {
if len(songQueNew) == 0 || songNumber >= len(songQueNew) {
return
}
songData := songQueNew[songNumber]
initRepo()
repo.AddGamePlayed(db.Ctx, songData.GameID)
repo.AddSongPlayed(db.Ctx, repository.AddSongPlayedParams{GameID: songData.GameID, SongName: songData.SongName})
}
func GetRandomSong() string {
getAllGames()
if len(gamesNew) == 0 {
return ""
}
song := getSongFromList(gamesNew)
lastFetchedNew = song
return song.Path
}
func GetRandomSongLowChance() string {
getAllGames()
var listOfGames []repository.Game
var averagePlayed = getAveragePlayed()
for _, data := range gamesNew {
timesToAdd := averagePlayed - data.TimesPlayed
if timesToAdd <= 0 {
listOfGames = append(listOfGames, data)
} else {
for i := int32(0); i < timesToAdd; i++ {
listOfGames = append(listOfGames, data)
}
}
}
song := getSongFromList(listOfGames)
lastFetchedNew = song
return song.Path
}
func GetRandomSongClassic() string {
getAllGames()
var listOfAllSongs []repository.Song
for _, game := range gamesNew {
songList, _ := repo.FindSongsFromGame(db.Ctx, game.ID)
listOfAllSongs = append(listOfAllSongs, songList...)
}
songFound := false
var song repository.Song
for !songFound {
song = listOfAllSongs[rand.Intn(len(listOfAllSongs))]
gameData, err := repo.GetGameById(db.Ctx, song.GameID)
if err != nil {
repo.RemoveBrokenSong(db.Ctx, song.Path)
log.Printf("Song not found, song '%s' deleted from game '%s' FileName: %v\n", song.SongName, gameData.GameName, song.FileName)
continue
}
//Check if file exists and open
openFile, err := os.Open(song.Path)
if err != nil || (song.FileName != nil && gameData.Path+*song.FileName != song.Path) {
//File not found
repo.RemoveBrokenSong(db.Ctx, song.Path)
log.Printf("Song not found, song '%s' deleted from game '%s' FileName: %v\n", song.SongName, gameData.GameName, song.FileName)
} else {
songFound = true
}
err = openFile.Close()
if err != nil {
log.Println(err)
}
}
lastFetchedNew = song
return song.Path
}
func GetSongInfo() SongInfo {
if songQueNew == nil {
return SongInfo{}
}
var currentSongData = songQueNew[currentSong]
currentGameData := getCurrentGame(currentSongData)
return SongInfo{
Game: currentGameData.GameName,
GamePlayed: currentGameData.TimesPlayed,
Song: currentSongData.SongName,
SongPlayed: currentSongData.TimesPlayed,
CurrentlyPlaying: true,
SongNo: currentSong,
}
}
func GetPlayedSongs() []SongInfo {
var songList []SongInfo
for i, song := range songQueNew {
gameData := getCurrentGame(song)
songList = append(songList, SongInfo{
Game: gameData.GameName,
GamePlayed: gameData.TimesPlayed,
Song: song.SongName,
SongPlayed: song.TimesPlayed,
CurrentlyPlaying: i == currentSong,
SongNo: i,
})
}
return songList
}
func GetSong(song string) string {
currentSong, _ = strconv.Atoi(song)
if currentSong >= len(songQueNew) {
currentSong = len(songQueNew) - 1
} else if currentSong < 0 {
currentSong = 0
}
songData := songQueNew[currentSong]
return songData.Path
}
func GetAllGames() []string {
getAllGames()
var jsonArray []string
for _, game := range gamesNew {
jsonArray = append(jsonArray, game.GameName)
}
return jsonArray
}
func GetAllGamesRandom() []string {
getAllGames()
var jsonArray []string
for _, game := range gamesNew {
jsonArray = append(jsonArray, game.GameName)
}
rand.Shuffle(len(jsonArray), func(i, j int) { jsonArray[i], jsonArray[j] = jsonArray[j], jsonArray[i] })
return jsonArray
}
func GetNextSong() string {
if songQueNew == nil {
return ""
}
if currentSong == len(songQueNew)-1 || currentSong == -1 {
songData := songQueNew[currentSong]
return songData.Path
} else {
currentSong = currentSong + 1
songData := songQueNew[currentSong]
return songData.Path
}
}
func GetPreviousSong() string {
if songQueNew == nil {
return ""
}
if currentSong == -1 || currentSong == 0 {
songData := songQueNew[0]
return songData.Path
} else {
currentSong = currentSong - 1
songData := songQueNew[currentSong]
return songData.Path
}
}
func getSongFromList(games []repository.Game) repository.Song {
songFound := false
var song repository.Song
for !songFound {
game := getRandomGame(games)
songs, _ := repo.FindSongsFromGame(db.Ctx, game.ID)
if len(songs) == 0 {
continue
}
song = songs[rand.Intn(len(songs))]
log.Println("song = ", song)
//Check if file exists and open
openFile, err := os.Open(song.Path)
if err != nil || (song.FileName != nil && game.Path+*song.FileName != song.Path) || (song.FileName != nil && strings.HasSuffix(*song.FileName, ".wav")) {
//File not found
repo.RemoveBrokenSong(db.Ctx, song.Path)
log.Printf("Song not found, song '%s' deleted from game '%s' FileName: %v\n", song.SongName, game.GameName, song.FileName)
} else {
songFound = true
}
err = openFile.Close()
if err != nil {
log.Println(err)
}
}
return song
}
func getCurrentGame(currentSongData repository.Song) repository.Game {
for _, game := range gamesNew {
if game.ID == currentSongData.GameID {
return game
}
}
return repository.Game{}
}
func getAveragePlayed() int32 {
getAllGames()
var sum int32
for _, data := range gamesNew {
sum += data.TimesPlayed
}
return sum / int32(len(gamesNew))
}
func getRandomGame(listOfGames []repository.Game) repository.Game {
return listOfGames[rand.Intn(len(listOfGames))]
}