Added support for profiling. Removed the pkg module altogether. Everything except old sync is now using code generated by sqlc.
207 lines
4.6 KiB
Go
207 lines
4.6 KiB
Go
package database
|
|
|
|
import (
|
|
"fmt"
|
|
"io/fs"
|
|
"log"
|
|
"os"
|
|
"sort"
|
|
"strconv"
|
|
"strings"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
var wg sync.WaitGroup
|
|
|
|
func SyncGames() {
|
|
start := time.Now()
|
|
dir := os.Getenv("MUSIC_PATH")
|
|
fmt.Printf("dir: %s\n", dir)
|
|
foldersToSkip := []string{".sync", "dist", "old", "characters"}
|
|
fmt.Println(foldersToSkip)
|
|
SetGameDeletionDate()
|
|
checkBrokenSongs()
|
|
|
|
files, err := os.ReadDir(dir)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
for _, file := range files {
|
|
syncGame(file, foldersToSkip, dir)
|
|
}
|
|
finished := time.Now()
|
|
totalTime := finished.Sub(start)
|
|
out := time.Time{}.Add(totalTime)
|
|
fmt.Printf("\nTotal time: %v\n", totalTime)
|
|
fmt.Printf("Total time: %v\n", out.Format("15:04:05.00000"))
|
|
}
|
|
|
|
func SyncGamesQuick() {
|
|
start := time.Now()
|
|
dir := os.Getenv("MUSIC_PATH")
|
|
fmt.Printf("dir: %s\n", dir)
|
|
foldersToSkip := []string{".sync", "dist", "old", "characters"}
|
|
fmt.Println(foldersToSkip)
|
|
SetGameDeletionDate()
|
|
checkBrokenSongs()
|
|
|
|
files, err := os.ReadDir(dir)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
for _, file := range files {
|
|
wg.Add(1)
|
|
go func() {
|
|
defer wg.Done()
|
|
syncGame(file, foldersToSkip, dir)
|
|
}()
|
|
}
|
|
wg.Wait()
|
|
finished := time.Now()
|
|
totalTime := finished.Sub(start)
|
|
out := time.Time{}.Add(totalTime)
|
|
fmt.Printf("\nTotal time: %v\n", totalTime)
|
|
fmt.Printf("Total time: %v\n", out.Format("15:04:05.00000"))
|
|
}
|
|
|
|
func syncGame(file os.DirEntry, foldersToSkip []string, dir string) {
|
|
if file.IsDir() && !contains(foldersToSkip, file.Name()) {
|
|
fmt.Println(file.Name())
|
|
path := dir + file.Name() + "/"
|
|
fmt.Println(path)
|
|
|
|
entries, err := os.ReadDir(path)
|
|
if err != nil {
|
|
log.Println(err)
|
|
}
|
|
id := -1
|
|
for _, entry := range entries {
|
|
fileInfo, err := entry.Info()
|
|
if err != nil {
|
|
log.Println(err)
|
|
}
|
|
id = getIdFromFile(fileInfo)
|
|
if id != -1 {
|
|
break
|
|
}
|
|
}
|
|
if id == -1 {
|
|
addNewGame(file.Name(), path)
|
|
} else {
|
|
checkIfChanged(id, file.Name(), path)
|
|
checkSongs(path, id)
|
|
}
|
|
}
|
|
}
|
|
|
|
func getIdFromFile(file os.FileInfo) int {
|
|
name := file.Name()
|
|
if !file.IsDir() && strings.HasSuffix(name, ".id") {
|
|
name = strings.Replace(name, ".id", "", 1)
|
|
name = strings.Replace(name, ".", "", 1)
|
|
i, _ := strconv.Atoi(name)
|
|
return i
|
|
}
|
|
return -1
|
|
}
|
|
|
|
func checkIfChanged(id int, name string, path string) {
|
|
fmt.Printf("Id from file: %v\n", id)
|
|
nameFromDb := GetGameName(id)
|
|
fmt.Printf("Name from file: %v\n", name)
|
|
fmt.Printf("Name from DB: %v\n", nameFromDb)
|
|
if nameFromDb == "" {
|
|
fmt.Println("Not in db")
|
|
InsertGameWithExistingId(id, name, path)
|
|
fmt.Println("Added to db")
|
|
} else if name != nameFromDb {
|
|
fmt.Println("Diff name")
|
|
UpdateGameName(id, name, path)
|
|
checkBrokenSongs()
|
|
}
|
|
RemoveDeletionDate(id)
|
|
}
|
|
|
|
func addNewGame(name string, path string) {
|
|
newId := GetIdByGameName(name)
|
|
if newId != -1 {
|
|
checkBrokenSongs()
|
|
RemoveDeletionDate(newId)
|
|
} else {
|
|
newId = InsertGame(name, path)
|
|
}
|
|
|
|
fmt.Printf("newId = %v", newId)
|
|
fileName := path + "/." + strconv.Itoa(newId) + ".id"
|
|
fmt.Printf("fileName = %v", fileName)
|
|
|
|
err := os.WriteFile(fileName, nil, 0644)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
checkSongs(path, newId)
|
|
}
|
|
|
|
func checkSongs(gameDir string, gameId int) {
|
|
files, err := os.ReadDir(gameDir)
|
|
if err != nil {
|
|
log.Println(err)
|
|
}
|
|
for _, file := range files {
|
|
entry, err := file.Info()
|
|
if err != nil {
|
|
log.Println(err)
|
|
}
|
|
if isSong(entry) {
|
|
path := gameDir + entry.Name()
|
|
fileName := entry.Name()
|
|
songName, _ := strings.CutSuffix(fileName, ".mp3")
|
|
if CheckSong(path) {
|
|
UpdateSong(songName, fileName, path)
|
|
} else {
|
|
AddSong(SongData{GameId: gameId, SongName: songName, Path: path, FileName: fileName})
|
|
}
|
|
} else if isCoverImage(entry) {
|
|
//TODO: Later add cover art image here in db
|
|
}
|
|
}
|
|
//TODO: Add number of songs here
|
|
}
|
|
|
|
func checkBrokenSongs() {
|
|
allSongs := FetchAllSongs()
|
|
var brokenSongs []SongData
|
|
for _, song := range allSongs {
|
|
//Check if file exists and open
|
|
openFile, err := os.Open(song.Path)
|
|
if err != nil {
|
|
//File not found
|
|
brokenSongs = append(brokenSongs, song)
|
|
fmt.Printf("song broken: %v", song.Path)
|
|
} else {
|
|
err = openFile.Close()
|
|
if err != nil {
|
|
log.Println(err)
|
|
}
|
|
}
|
|
}
|
|
RemoveBrokenSongs(brokenSongs)
|
|
}
|
|
|
|
func isSong(entry fs.FileInfo) bool {
|
|
return !entry.IsDir() && strings.HasSuffix(entry.Name(), ".mp3")
|
|
}
|
|
|
|
func isCoverImage(entry fs.FileInfo) bool {
|
|
return !entry.IsDir() && strings.Contains(entry.Name(), "cover") &&
|
|
(strings.HasSuffix(entry.Name(), ".jpg") || strings.HasSuffix(entry.Name(), ".png"))
|
|
}
|
|
|
|
func contains(s []string, searchTerm string) bool {
|
|
i := sort.SearchStrings(s, searchTerm)
|
|
return i < len(s) && s[i] == searchTerm
|
|
}
|