Fixed some bugs and added Random Classic
This commit is contained in:
8
.idea/dataSources.xml
generated
8
.idea/dataSources.xml
generated
@@ -1,17 +1,17 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="DataSourceManagerImpl" format="xml" multifile-model="true">
|
<component name="DataSourceManagerImpl" format="xml" multifile-model="true">
|
||||||
<data-source source="LOCAL" name="music_prod@192.168.86.181" uuid="e63caf71-2b1a-400d-9cc4-4b87b1f9b807">
|
<data-source source="LOCAL" name="music_prod@192.168.86.100" uuid="e63caf71-2b1a-400d-9cc4-4b87b1f9b807">
|
||||||
<driver-ref>postgresql</driver-ref>
|
<driver-ref>postgresql</driver-ref>
|
||||||
<synchronize>true</synchronize>
|
<synchronize>true</synchronize>
|
||||||
<jdbc-driver>org.postgresql.Driver</jdbc-driver>
|
<jdbc-driver>org.postgresql.Driver</jdbc-driver>
|
||||||
<jdbc-url>jdbc:postgresql://192.168.86.181:9432/music_prod</jdbc-url>
|
<jdbc-url>jdbc:postgresql://192.168.86.100:5432/music_prod</jdbc-url>
|
||||||
</data-source>
|
</data-source>
|
||||||
<data-source source="LOCAL" name="music_test@192.168.86.181" uuid="d063e147-d7f0-48db-9f04-57a108261ef1">
|
<data-source source="LOCAL" name="music_test@192.168.86.100" uuid="d063e147-d7f0-48db-9f04-57a108261ef1">
|
||||||
<driver-ref>postgresql</driver-ref>
|
<driver-ref>postgresql</driver-ref>
|
||||||
<synchronize>true</synchronize>
|
<synchronize>true</synchronize>
|
||||||
<jdbc-driver>org.postgresql.Driver</jdbc-driver>
|
<jdbc-driver>org.postgresql.Driver</jdbc-driver>
|
||||||
<jdbc-url>jdbc:postgresql://192.168.86.181:9432/music_test</jdbc-url>
|
<jdbc-url>jdbc:postgresql://192.168.86.100:5432/music_test</jdbc-url>
|
||||||
</data-source>
|
</data-source>
|
||||||
<data-source source="LOCAL" name="music_test@ssh.sanplex.xyz" uuid="a9cf3eb8-abc2-479b-9f27-12b4cbbfc321">
|
<data-source source="LOCAL" name="music_test@ssh.sanplex.xyz" uuid="a9cf3eb8-abc2-479b-9f27-12b4cbbfc321">
|
||||||
<driver-ref>postgresql</driver-ref>
|
<driver-ref>postgresql</driver-ref>
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ export default {
|
|||||||
let trackAddedToQue = false;
|
let trackAddedToQue = false;
|
||||||
this.disableButtons = true;
|
this.disableButtons = true;
|
||||||
let copyOfPlaylist = this.localPlaylist;
|
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 the local playlist of MP3s is empty, wait for a new track to load
|
||||||
if (copyOfPlaylist.length === 0) {
|
if (copyOfPlaylist.length === 0) {
|
||||||
console.log("No track preloaded, loading a new one");
|
console.log("No track preloaded, loading a new one");
|
||||||
|
|||||||
@@ -44,6 +44,11 @@ func (m *Music) GetRandomSongLowChance(ctx *gin.Context) {
|
|||||||
helpers.SendSong(ctx, song)
|
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) {
|
func (m *Music) GetSongInfo(ctx *gin.Context) {
|
||||||
song := server.GetSongInfo()
|
song := server.GetSongInfo()
|
||||||
ctx.JSON(http.StatusOK, song)
|
ctx.JSON(http.StatusOK, song)
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ func SetupRestServer(swagger embed.FS) {
|
|||||||
musicGroup.GET("reset", music.ResetMusic)
|
musicGroup.GET("reset", music.ResetMusic)
|
||||||
musicGroup.GET("rand", music.GetRandomSong)
|
musicGroup.GET("rand", music.GetRandomSong)
|
||||||
musicGroup.GET("rand/low", music.GetRandomSongLowChance)
|
musicGroup.GET("rand/low", music.GetRandomSongLowChance)
|
||||||
|
musicGroup.GET("rand/classic", music.GetRandomSongClassic)
|
||||||
musicGroup.GET("info", music.GetSongInfo)
|
musicGroup.GET("info", music.GetSongInfo)
|
||||||
musicGroup.GET("list", music.GetPlayedSongs)
|
musicGroup.GET("list", music.GetPlayedSongs)
|
||||||
musicGroup.GET("next", music.GetNextSong)
|
musicGroup.GET("next", music.GetNextSong)
|
||||||
@@ -87,6 +88,7 @@ func SetupRestServer(swagger embed.FS) {
|
|||||||
router.GET("/test", index.GetDBTest)
|
router.GET("/test", index.GetDBTest)
|
||||||
router.StaticFS("/swagger", helpers.EmbedFolder(swagger, "swagger", false))
|
router.StaticFS("/swagger", helpers.EmbedFolder(swagger, "swagger", false))
|
||||||
router.Use(static.Serve("/", static.LocalFile("/frontend", true)))
|
router.Use(static.Serve("/", static.LocalFile("/frontend", true)))
|
||||||
|
router.Use(static.Serve("/new", static.LocalFile("/newFrontend", true)))
|
||||||
|
|
||||||
port := os.Getenv("PORT")
|
port := os.Getenv("PORT")
|
||||||
if port == "" {
|
if port == "" {
|
||||||
|
|||||||
@@ -20,9 +20,34 @@ func GetGameName(gameId int) string {
|
|||||||
return gameName
|
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() {
|
func SetGameDeletionDate() {
|
||||||
_, err := pool.Exec(context.Background(),
|
_, 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 {
|
if err != nil {
|
||||||
_, _ = fmt.Fprintf(os.Stderr, "Exec failed: %v\n", err)
|
_, _ = 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 {
|
func FindAllGames() []models.GameData {
|
||||||
rows, err := pool.Query(context.Background(),
|
rows, err := pool.Query(context.Background(),
|
||||||
"SELECT id, game_name, added, deleted, last_changed, path, times_played, last_played, number_of_songs "+
|
"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")
|
"ORDER BY game_name")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_, _ = fmt.Fprintf(os.Stderr, "QueryRow failed: %v\n", err)
|
_, _ = fmt.Fprintf(os.Stderr, "QueryRow failed: %v\n", err)
|
||||||
|
|||||||
@@ -24,8 +24,8 @@ func ClearSongs(gameId int) {
|
|||||||
|
|
||||||
func AddSong(song models.SongData) {
|
func AddSong(song models.SongData) {
|
||||||
_, err := pool.Exec(context.Background(),
|
_, err := pool.Exec(context.Background(),
|
||||||
"INSERT INTO song(game_id, song_name, path) VALUES ($1, $2, $3)",
|
"INSERT INTO song(game_id, song_name, path, file_name) VALUES ($1, $2, $3, $4)",
|
||||||
song.GameId, song.SongName, song.Path)
|
song.GameId, song.SongName, song.Path, song.FileName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_, _ = fmt.Fprintf(os.Stderr, "Exec failed: %v\n", err)
|
_, _ = fmt.Fprintf(os.Stderr, "Exec failed: %v\n", err)
|
||||||
}
|
}
|
||||||
@@ -33,7 +33,7 @@ func AddSong(song models.SongData) {
|
|||||||
|
|
||||||
func FindSongsFromGame(id int) []models.SongData {
|
func FindSongsFromGame(id int) []models.SongData {
|
||||||
rows, err := pool.Query(context.Background(),
|
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 {
|
if err != nil {
|
||||||
_, _ = fmt.Fprintf(os.Stderr, "QueryRow failed: %v\n", err)
|
_, _ = fmt.Fprintf(os.Stderr, "QueryRow failed: %v\n", err)
|
||||||
return nil
|
return nil
|
||||||
@@ -43,6 +43,7 @@ func FindSongsFromGame(id int) []models.SongData {
|
|||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var songName string
|
var songName string
|
||||||
var path string
|
var path string
|
||||||
|
var fileName string
|
||||||
var timesPlayed int
|
var timesPlayed int
|
||||||
|
|
||||||
err := rows.Scan(&songName, &path, ×Played)
|
err := rows.Scan(&songName, &path, ×Played)
|
||||||
@@ -54,6 +55,7 @@ func FindSongsFromGame(id int) []models.SongData {
|
|||||||
GameId: id,
|
GameId: id,
|
||||||
SongName: songName,
|
SongName: songName,
|
||||||
Path: path,
|
Path: path,
|
||||||
|
FileName: fileName,
|
||||||
TimesPlayed: timesPlayed,
|
TimesPlayed: timesPlayed,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
46
pkg/db/songList.go
Normal file
46
pkg/db/songList.go
Normal file
@@ -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
|
||||||
|
}
|
||||||
@@ -40,4 +40,21 @@ type SongData struct {
|
|||||||
SongName string
|
SongName string
|
||||||
Path string
|
Path string
|
||||||
TimesPlayed int
|
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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,13 +54,15 @@ func GetRandomSong() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func GetRandomSongLowChance() string {
|
func GetRandomSongLowChance() string {
|
||||||
gameList := db.FindAllGames()
|
if games == nil || len(games) == 0 {
|
||||||
|
games = db.FindAllGames()
|
||||||
|
}
|
||||||
|
|
||||||
var listOfGames []models.GameData
|
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
|
var timesToAdd = averagePlayed - data.TimesPlayed
|
||||||
if timesToAdd <= 0 {
|
if timesToAdd <= 0 {
|
||||||
listOfGames = append(listOfGames, data)
|
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 {
|
func GetSongInfo() models.SongInfo {
|
||||||
if songQue == nil {
|
if songQue == nil {
|
||||||
return models.SongInfo{}
|
return models.SongInfo{}
|
||||||
@@ -195,17 +231,17 @@ func getSongFromList(games []models.GameData) models.SongData {
|
|||||||
|
|
||||||
//Check if file exists and open
|
//Check if file exists and open
|
||||||
openFile, err := os.Open(song.Path)
|
openFile, err := os.Open(song.Path)
|
||||||
if err != nil {
|
if err != nil || game.Path+"/"+song.FileName != song.Path {
|
||||||
//File not found
|
//File not found
|
||||||
db.RemoveBrokenSong(song)
|
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 {
|
} else {
|
||||||
songFound = true
|
songFound = true
|
||||||
}
|
}
|
||||||
|
|
||||||
err = openFile.Close()
|
err = openFile.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Println(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return song
|
return song
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// SyncGames TODO: Make sync concurrent
|
||||||
func SyncGames() {
|
func SyncGames() {
|
||||||
host := os.Getenv("DB_HOST")
|
host := os.Getenv("DB_HOST")
|
||||||
var dir string
|
var dir string
|
||||||
@@ -124,8 +125,9 @@ func checkSongs(gameDir string, gameId int) {
|
|||||||
}
|
}
|
||||||
path := gameDir + entry.Name()
|
path := gameDir + entry.Name()
|
||||||
fileName := entry.Name()
|
fileName := entry.Name()
|
||||||
|
songName, _ := strings.CutSuffix(fileName, ".mp3")
|
||||||
if isSong(entry) {
|
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) {
|
} else if isCoverImage(entry) {
|
||||||
//TODO: Later add cover art image here in db
|
//TODO: Later add cover art image here in db
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
songs/1-01 Opening.mp3
Normal file
BIN
songs/1-01 Opening.mp3
Normal file
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user