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