From 41c3c5ae4c242fc8f72dc654d7fceae55ffab8a0 Mon Sep 17 00:00:00 2001 From: JChris246 Date: Thu, 13 Mar 2025 23:13:43 -0400 Subject: [PATCH 1/2] fix: allow moving files across drives --- cmdHandlers.go | 2 +- socketHandlers.go | 3 +- utils/helpers.go | 89 +++++++++++++++++------------------------------ wav/convert.go | 3 +- wav/wav.go | 58 ++++++++++++++++++++++++++++++ 5 files changed, 94 insertions(+), 61 deletions(-) diff --git a/cmdHandlers.go b/cmdHandlers.go index 71e64d0..3a2dc81 100644 --- a/cmdHandlers.go +++ b/cmdHandlers.go @@ -313,7 +313,7 @@ func saveSong(filePath string, force bool) error { wavFile := fileName + ".wav" sourcePath := filepath.Join(filepath.Dir(filePath), wavFile) newFilePath := filepath.Join(SONGS_DIR, wavFile) - err = os.Rename(sourcePath, newFilePath) + err = utils.MoveFile(sourcePath, newFilePath) if err != nil { return fmt.Errorf("failed to rename temporary file to output file: %v", err) } diff --git a/socketHandlers.go b/socketHandlers.go index 75ce0c6..406f2b4 100644 --- a/socketHandlers.go +++ b/socketHandlers.go @@ -10,6 +10,7 @@ import ( "song-recognition/shazam" "song-recognition/spotify" "song-recognition/utils" + "song-recognition/wav" "strings" socketio "github.com/googollee/go-socket.io" @@ -186,7 +187,7 @@ func handleNewRecording(socket socketio.Conn, recordData string) { return } - samples, err := utils.ProcessRecording(&recData, true) + samples, err := wav.ProcessRecording(&recData, true) if err != nil { err := xerrors.New(err) logger.ErrorContext(ctx, "Failed to process recording.", slog.Any("error", err)) diff --git a/utils/helpers.go b/utils/helpers.go index cd7ceb0..4502ca7 100644 --- a/utils/helpers.go +++ b/utils/helpers.go @@ -1,18 +1,10 @@ package utils import ( - "context" - "encoding/base64" "encoding/binary" "fmt" - "log/slog" + "io" "os" - "song-recognition/models" - "song-recognition/wav" - "strings" - "time" - - "github.com/mdobak/go-xerrors" ) func DeleteFile(filePath string) error { @@ -32,6 +24,36 @@ func CreateFolder(folderPath string) error { return nil } +func MoveFile(sourcePath string, destinationPath string) error { + srcFile, err := os.Open(sourcePath) + if err != nil { + return err + } + + destFile, err := os.Create(destinationPath) + if err != nil { + return err + } + defer destFile.Close() + + _, err = io.Copy(destFile, srcFile) + if err != nil { + return err + } + + err = srcFile.Close() + if err != nil { + return err + } + + err = os.Remove(sourcePath) + if err != nil { + return err + } + + return nil +} + func FloatsToBytes(data []float64, bitsPerSample int) ([]byte, error) { var byteData []byte @@ -72,52 +94,3 @@ func FloatsToBytes(data []float64, bitsPerSample int) ([]byte, error) { return byteData, nil } - -func ProcessRecording(recData *models.RecordData, saveRecording bool) ([]float64, error) { - decodedAudioData, err := base64.StdEncoding.DecodeString(recData.Audio) - if err != nil { - return nil, err - } - - now := time.Now() - fileName := fmt.Sprintf("%04d_%02d_%02d_%02d_%02d_%02d.wav", - now.Second(), now.Minute(), now.Hour(), - now.Day(), now.Month(), now.Year(), - ) - filePath := "tmp/" + fileName - - err = wav.WriteWavFile(filePath, decodedAudioData, recData.SampleRate, recData.Channels, recData.SampleSize) - if err != nil { - return nil, err - } - - reformatedWavFile, err := wav.ReformatWAV(filePath, 1) - if err != nil { - return nil, err - } - - wavInfo, _ := wav.ReadWavInfo(reformatedWavFile) - samples, _ := wav.WavBytesToSamples(wavInfo.Data) - - if saveRecording { - logger := GetLogger() - ctx := context.Background() - - err := CreateFolder("recordings") - if err != nil { - err := xerrors.New(err) - logger.ErrorContext(ctx, "Failed create folder.", slog.Any("error", err)) - } - - newFilePath := strings.Replace(reformatedWavFile, "tmp/", "recordings/", 1) - err = os.Rename(reformatedWavFile, newFilePath) - if err != nil { - logger.ErrorContext(ctx, "Failed to move file.", slog.Any("error", err)) - } - } - - DeleteFile(fileName) - DeleteFile(reformatedWavFile) - - return samples, nil -} diff --git a/wav/convert.go b/wav/convert.go index aa5366b..b8ca3ca 100644 --- a/wav/convert.go +++ b/wav/convert.go @@ -5,6 +5,7 @@ import ( "os" "os/exec" "path/filepath" + "song-recognition/utils" "strings" ) @@ -43,7 +44,7 @@ func ConvertToWAV(inputFilePath string, channels int) (wavFilePath string, err e } // Rename the temporary file to the output file - err = os.Rename(tmpFile, outputFile) + err = utils.MoveFile(tmpFile, outputFile) if err != nil { return "", fmt.Errorf("failed to rename temporary file to output file: %v", err) } diff --git a/wav/wav.go b/wav/wav.go index 010ac5d..99e6539 100644 --- a/wav/wav.go +++ b/wav/wav.go @@ -2,13 +2,22 @@ package wav import ( "bytes" + "context" + "encoding/base64" "encoding/binary" "encoding/json" "errors" "fmt" "io/ioutil" + "log/slog" "os" "os/exec" + "song-recognition/models" + "song-recognition/utils" + "strings" + "time" + + "github.com/mdobak/go-xerrors" ) // WavHeader defines the structure of a WAV header @@ -200,3 +209,52 @@ func GetMetadata(filePath string) (FFmpegMetadata, error) { return metadata, nil } + +func ProcessRecording(recData *models.RecordData, saveRecording bool) ([]float64, error) { + decodedAudioData, err := base64.StdEncoding.DecodeString(recData.Audio) + if err != nil { + return nil, err + } + + now := time.Now() + fileName := fmt.Sprintf("%04d_%02d_%02d_%02d_%02d_%02d.wav", + now.Second(), now.Minute(), now.Hour(), + now.Day(), now.Month(), now.Year(), + ) + filePath := "tmp/" + fileName + + err = WriteWavFile(filePath, decodedAudioData, recData.SampleRate, recData.Channels, recData.SampleSize) + if err != nil { + return nil, err + } + + reformatedWavFile, err := ReformatWAV(filePath, 1) + if err != nil { + return nil, err + } + + wavInfo, _ := ReadWavInfo(reformatedWavFile) + samples, _ := WavBytesToSamples(wavInfo.Data) + + if saveRecording { + logger := utils.GetLogger() + ctx := context.Background() + + err := utils.CreateFolder("recordings") + if err != nil { + err := xerrors.New(err) + logger.ErrorContext(ctx, "Failed create folder.", slog.Any("error", err)) + } + + newFilePath := strings.Replace(reformatedWavFile, "tmp/", "recordings/", 1) + err = os.Rename(reformatedWavFile, newFilePath) + if err != nil { + logger.ErrorContext(ctx, "Failed to move file.", slog.Any("error", err)) + } + } + + utils.DeleteFile(fileName) + utils.DeleteFile(reformatedWavFile) + + return samples, nil +} From de7a0de54df1cbd6658d881730a2bca738902631 Mon Sep 17 00:00:00 2001 From: Chigozirim Igweamaka Date: Sat, 15 Mar 2025 13:44:42 +0100 Subject: [PATCH 2/2] fix: remove uniqueness constraint on ytID in db schema to allow ytID to be null for multiple songs without one --- db/sqlite.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/sqlite.go b/db/sqlite.go index 0a44d60..03691a6 100644 --- a/db/sqlite.go +++ b/db/sqlite.go @@ -35,7 +35,7 @@ func createTables(db *sql.DB) error { id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT NOT NULL, artist TEXT NOT NULL, - ytID TEXT UNIQUE, + ytID TEXT, key TEXT NOT NULL UNIQUE ); `