diff --git a/.idea/dataSources.xml b/.idea/dataSources.xml index 49a4119..502a74d 100644 --- a/.idea/dataSources.xml +++ b/.idea/dataSources.xml @@ -1,17 +1,17 @@ - + postgresql true org.postgresql.Driver - jdbc:postgresql://192.168.86.181:9432/music_prod + jdbc:postgresql://192.168.86.100:5432/music_prod - + postgresql true org.postgresql.Driver - jdbc:postgresql://192.168.86.181:9432/music_test + jdbc:postgresql://192.168.86.100:5432/music_test postgresql diff --git a/cmd/frontend/src/components/layout/TheFooter.vue b/cmd/frontend/src/components/layout/TheFooter.vue index b616fbe..99f2758 100644 --- a/cmd/frontend/src/components/layout/TheFooter.vue +++ b/cmd/frontend/src/components/layout/TheFooter.vue @@ -58,6 +58,7 @@ export default { let trackAddedToQue = false; this.disableButtons = true; let copyOfPlaylist = this.localPlaylist; + setTimeout(() => this.isHidden = false, 2000); //If the local playlist of MP3s is empty, wait for a new track to load if (copyOfPlaylist.length === 0) { console.log("No track preloaded, loading a new one"); diff --git a/pkg/api/music.go b/pkg/api/music.go index 74653be..0b06429 100644 --- a/pkg/api/music.go +++ b/pkg/api/music.go @@ -44,6 +44,11 @@ func (m *Music) GetRandomSongLowChance(ctx *gin.Context) { helpers.SendSong(ctx, song) } +func (m *Music) GetRandomSongClassic(ctx *gin.Context) { + song := server.GetRandomSongClassic() + helpers.SendSong(ctx, song) +} + func (m *Music) GetSongInfo(ctx *gin.Context) { song := server.GetSongInfo() ctx.JSON(http.StatusOK, song) diff --git a/pkg/conf/conf.go b/pkg/conf/conf.go index ad44026..3427914 100644 --- a/pkg/conf/conf.go +++ b/pkg/conf/conf.go @@ -70,6 +70,7 @@ func SetupRestServer(swagger embed.FS) { musicGroup.GET("reset", music.ResetMusic) musicGroup.GET("rand", music.GetRandomSong) musicGroup.GET("rand/low", music.GetRandomSongLowChance) + musicGroup.GET("rand/classic", music.GetRandomSongClassic) musicGroup.GET("info", music.GetSongInfo) musicGroup.GET("list", music.GetPlayedSongs) musicGroup.GET("next", music.GetNextSong) @@ -87,6 +88,7 @@ func SetupRestServer(swagger embed.FS) { router.GET("/test", index.GetDBTest) router.StaticFS("/swagger", helpers.EmbedFolder(swagger, "swagger", false)) router.Use(static.Serve("/", static.LocalFile("/frontend", true))) + router.Use(static.Serve("/new", static.LocalFile("/newFrontend", true))) port := os.Getenv("PORT") if port == "" { diff --git a/pkg/db/game.go b/pkg/db/game.go index 0dc0a36..07ab7e5 100644 --- a/pkg/db/game.go +++ b/pkg/db/game.go @@ -20,9 +20,34 @@ func GetGameName(gameId int) string { return gameName } +func GetGameById(gameId int) models.GameData { + var id, timesPlayed int + var numberOfSongs pgtype.Int4 + var gameName, path string + var added, deleted, lastChanged, lastPlayed pgtype.Timestamp + err := pool.QueryRow(context.Background(), + "SELECT id, game_name, added, deleted, last_changed, path, times_played, last_played, number_of_songs "+ + "FROM game WHERE id = $1", gameId).Scan(&id, &gameName, &added, &deleted, &lastChanged, &path, ×Played, &lastPlayed, &numberOfSongs) + if err != nil { + _, _ = fmt.Fprintf(os.Stderr, "QueryRow failed: %v\n", err) + return models.GameData{} + } + return models.GameData{ + Id: id, + GameName: gameName, + Added: added.Time, + Deleted: deleted.Time, + LastChanged: lastChanged.Time, + Path: path, + TimesPlayed: timesPlayed, + LastPlayed: lastPlayed.Time, + NumberOfSongs: numberOfSongs.Int, + } +} + func SetGameDeletionDate() { _, err := pool.Exec(context.Background(), - "UPDATE game SET deleted=$1", time.Now()) + "UPDATE game SET deleted=$1 WHERE deleted IS NULL", time.Now()) if err != nil { _, _ = fmt.Fprintf(os.Stderr, "Exec failed: %v\n", err) } @@ -94,7 +119,7 @@ func InsertGameWithExistingId(id int, name string, path string) { func FindAllGames() []models.GameData { rows, err := pool.Query(context.Background(), "SELECT id, game_name, added, deleted, last_changed, path, times_played, last_played, number_of_songs "+ - "FROM game "+ + "FROM game WHERE deleted IS NULL"+ "ORDER BY game_name") if err != nil { _, _ = fmt.Fprintf(os.Stderr, "QueryRow failed: %v\n", err) diff --git a/pkg/db/song.go b/pkg/db/song.go index 3524949..217333c 100644 --- a/pkg/db/song.go +++ b/pkg/db/song.go @@ -24,8 +24,8 @@ func ClearSongs(gameId int) { func AddSong(song models.SongData) { _, err := pool.Exec(context.Background(), - "INSERT INTO song(game_id, song_name, path) VALUES ($1, $2, $3)", - song.GameId, song.SongName, song.Path) + "INSERT INTO song(game_id, song_name, path, file_name) VALUES ($1, $2, $3, $4)", + song.GameId, song.SongName, song.Path, song.FileName) if err != nil { _, _ = fmt.Fprintf(os.Stderr, "Exec failed: %v\n", err) } @@ -33,7 +33,7 @@ func AddSong(song models.SongData) { func FindSongsFromGame(id int) []models.SongData { rows, err := pool.Query(context.Background(), - "SELECT song_name, path, times_played FROM song WHERE game_id = $1", id) + "SELECT song_name, path, file_name, times_played FROM song WHERE game_id = $1", id) if err != nil { _, _ = fmt.Fprintf(os.Stderr, "QueryRow failed: %v\n", err) return nil @@ -43,6 +43,7 @@ func FindSongsFromGame(id int) []models.SongData { for rows.Next() { var songName string var path string + var fileName string var timesPlayed int err := rows.Scan(&songName, &path, ×Played) @@ -54,6 +55,7 @@ func FindSongsFromGame(id int) []models.SongData { GameId: id, SongName: songName, Path: path, + FileName: fileName, TimesPlayed: timesPlayed, }) } diff --git a/pkg/db/songList.go b/pkg/db/songList.go new file mode 100644 index 0000000..d05e895 --- /dev/null +++ b/pkg/db/songList.go @@ -0,0 +1,46 @@ +package db + +import ( + "context" + "fmt" + "music-server/pkg/models" + "os" + "time" +) + +func InsertSongInList(song models.SongListData) { + err := pool.QueryRow(context.Background(), + `INSERT INTO song_list (match_date, match_id, song_no, game_name, song_name) VALUES ($1, $2, $3, $4, $5)`, + song.MatchDate, song.MatchId, song.SongNo, song.GameName, song.SongName) + if err != nil { + _, _ = fmt.Fprintf(os.Stderr, "QueryRow failed: %v\n", err) + } +} + +func GetSongList(matchId int) []models.SongListData { + rows, err := pool.Query(context.Background(), + "SELECT match_date, match_id, song_no, game_name, song_name "+ + "FROM song_list WHERE match_date = $1"+ + "ORDER BY song_no DESC", matchId) + if err != nil { + _, _ = fmt.Fprintf(os.Stderr, "QueryRow failed: %v\n", err) + } + var songList []models.SongListData + for rows.Next() { + var matchId, songNo int + var matchDate time.Time + var gameName, songName string + err := rows.Scan(&matchDate, &matchId, &songNo, &gameName, &songName) + if err != nil { + _, _ = fmt.Fprintf(os.Stderr, "Scan failed: %v\n", err) + } + songList = append(songList, models.SongListData{ + MatchDate: matchDate, + MatchId: matchId, + SongNo: songNo, + GameName: gameName, + SongName: songName, + }) + } + return songList +} diff --git a/pkg/models/models.go b/pkg/models/models.go index 3868e0d..e68c0d3 100644 --- a/pkg/models/models.go +++ b/pkg/models/models.go @@ -40,4 +40,21 @@ type SongData struct { SongName string Path string TimesPlayed int + FileName string +} + +type SongListData struct { + MatchDate time.Time + MatchId int + SongNo int + GameName string + SongName string +} + +type VgmqData struct { + SongNo int + Path string + Clue string + Answered bool + Answer string } diff --git a/pkg/server/music.go b/pkg/server/music.go index 96fca82..b541faa 100644 --- a/pkg/server/music.go +++ b/pkg/server/music.go @@ -54,13 +54,15 @@ func GetRandomSong() string { } func GetRandomSongLowChance() string { - gameList := db.FindAllGames() + if games == nil || len(games) == 0 { + games = db.FindAllGames() + } var listOfGames []models.GameData - var averagePlayed = getAveragePlayed(gameList) + var averagePlayed = getAveragePlayed(games) - for _, data := range gameList { + for _, data := range games { var timesToAdd = averagePlayed - data.TimesPlayed if timesToAdd <= 0 { listOfGames = append(listOfGames, data) @@ -77,6 +79,40 @@ func GetRandomSongLowChance() string { } +func GetRandomSongClassic() string { + if games == nil || len(games) == 0 { + games = db.FindAllGames() + } + + var listOfAllSongs []models.SongData + for _, game := range games { + listOfAllSongs = append(listOfAllSongs, db.FindSongsFromGame(game.Id)...) + } + + songFound := false + var song models.SongData + for !songFound { + song = listOfAllSongs[rand.Intn(len(listOfAllSongs))] + gameData := db.GetGameById(song.GameId) + + //Check if file exists and open + openFile, err := os.Open(song.Path) + if err != nil || gameData.Path+"/"+song.FileName != song.Path { + //File not found + db.RemoveBrokenSong(song) + log.Println("Song not found, song '" + song.SongName + "' deleted from game '" + gameData.GameName + "' FileName: " + song.FileName) + } else { + songFound = true + } + err = openFile.Close() + if err != nil { + log.Println(err) + } + } + lastFetched = song + return song.Path +} + func GetSongInfo() models.SongInfo { if songQue == nil { return models.SongInfo{} @@ -195,17 +231,17 @@ func getSongFromList(games []models.GameData) models.SongData { //Check if file exists and open openFile, err := os.Open(song.Path) - if err != nil { + if err != nil || game.Path+"/"+song.FileName != song.Path { //File not found db.RemoveBrokenSong(song) - log.Println("Song not found, song '" + song.SongName + "' deleted from game '" + game.GameName + "' songPath: " + song.Path) + log.Println("Song not found, song '" + song.SongName + "' deleted from game '" + game.GameName + "' FileName: " + song.FileName) } else { songFound = true } err = openFile.Close() if err != nil { - log.Fatal(err) + log.Println(err) } } return song diff --git a/pkg/server/sync.go b/pkg/server/sync.go index 3b32dfe..1372d75 100644 --- a/pkg/server/sync.go +++ b/pkg/server/sync.go @@ -12,6 +12,7 @@ import ( "strings" ) +// SyncGames TODO: Make sync concurrent func SyncGames() { host := os.Getenv("DB_HOST") var dir string @@ -124,8 +125,9 @@ func checkSongs(gameDir string, gameId int) { } path := gameDir + entry.Name() fileName := entry.Name() + songName, _ := strings.CutSuffix(fileName, ".mp3") if isSong(entry) { - db.AddSong(models.SongData{GameId: gameId, SongName: fileName, Path: path}) + db.AddSong(models.SongData{GameId: gameId, SongName: songName, Path: path, FileName: fileName}) } else if isCoverImage(entry) { //TODO: Later add cover art image here in db } diff --git a/songs/1-01 Opening.mp3 b/songs/1-01 Opening.mp3 new file mode 100644 index 0000000..64dbcf8 Binary files /dev/null and b/songs/1-01 Opening.mp3 differ diff --git a/songs/Opening.mp3 b/songs/Opening.mp3 deleted file mode 100644 index 59c95c5..0000000 Binary files a/songs/Opening.mp3 and /dev/null differ