Rework files to use strings instead of duplicate functions

There's too many functions at this point.
This commit is contained in:
Eli Ribble 2026-02-08 00:58:51 +00:00
parent d437c68403
commit 21fac37597
No known key found for this signature in database
7 changed files with 217 additions and 96 deletions

69
userfile/audio.go Normal file
View file

@ -0,0 +1,69 @@
package userfile
import (
"errors"
"fmt"
"os"
"os/exec"
"github.com/Gleipnir-Technology/nidus-sync/db"
"github.com/google/uuid"
"github.com/rs/zerolog/log"
)
func NormalizeAudio(audioUUID uuid.UUID) error {
//source := AudioFileContentPathRaw(audioUUID.String())
source := fileContentPath("user", audioUUID, "m4a")
_, err := os.Stat(source)
if errors.Is(err, os.ErrNotExist) {
log.Warn().Str("source", source).Msg("file doesn't exist, skipping normalization")
return nil
}
log.Info().Str("sourcce", source).Msg("Normalizing")
//destination := AudioFileContentPathNormalized(audioUUID.String())
destination := fileContentPathAudioNormalized(audioUUID)
// Use "ffmpeg" directly, assuming it's in the system PATH
cmd := exec.Command("ffmpeg", "-i", source, "-filter:a", "loudnorm", destination)
out, err := cmd.CombinedOutput()
if err != nil {
log.Printf("FFmpeg output for normalization: %s", out)
return fmt.Errorf("ffmpeg normalization failed: %v", err)
}
err = db.NoteAudioNormalized(audioUUID.String())
if err != nil {
return fmt.Errorf("failed to update database for normalized audio %s: %v", audioUUID, err)
}
log.Info().Str("destination", destination).Msg("Normalized audio")
return nil
}
func TranscodeToOgg(audioUUID uuid.UUID) error {
//source := AudioFileContentPathNormalized(audioUUID.String())
source := fileContentPathAudioNormalized(audioUUID)
_, err := os.Stat(source)
if errors.Is(err, os.ErrNotExist) {
log.Warn().Str("source", source).Msg("file doesn't exist, skipping OGG transcoding")
return nil
}
log.Info().Str("source", source).Msg("Transcoding to ogg")
//destination := userfile.AudioFileContentPathOgg(audioUUID.String())
destination := fileContentPath("user", audioUUID, "ogg")
// Use "ffmpeg" directly, assuming it's in the system PATH
cmd := exec.Command("ffmpeg", "-i", source, "-vn", "-acodec", "libvorbis", destination)
out, err := cmd.CombinedOutput()
if err != nil {
log.Error().Err(err).Bytes("out", out).Msg("FFmpeg output for OGG transcoding")
return fmt.Errorf("ffmpeg OGG transcoding failed: %v", err)
}
err = db.NoteAudioTranscodedToOgg(audioUUID.String())
if err != nil {
return fmt.Errorf("failed to update database for OGG transcoded audio %s: %v", audioUUID, err)
}
log.Info().Str("destination", destination).Msg("Transcoded audio")
return nil
}
func fileContentPathAudioNormalized(u uuid.UUID) string {
//destination := AudioFileContentPathNormalized(audioUUID.String())
return fileContentPath("user", u, "normalized.m4a")
}

77
userfile/upload.go Normal file
View file

@ -0,0 +1,77 @@
package userfile
import (
"bytes"
"fmt"
"io"
"mime/multipart"
"net/http"
"github.com/google/uuid"
"github.com/rs/zerolog/log"
)
type FileUpload struct {
ContentType string
UploadFilesize int
UploadFilename string
UUID uuid.UUID
}
func SaveFileUpload(r *http.Request, name string, subdir string, extension string) ([]FileUpload, error) {
results := make([]FileUpload, 0)
for n, fheaders := range r.MultipartForm.File {
log.Debug().Str("n", n).Msg("looking at header")
if n != name {
continue
}
for _, headers := range fheaders {
f, err := saveFileUpload(headers, subdir, extension)
if err != nil {
return results, fmt.Errorf("Failed to extract photo upload: %w", err)
}
results = append(results, f)
}
}
return results, nil
}
func saveFileUploads(r *http.Request, subdir string, extension string) ([]FileUpload, error) {
results := make([]FileUpload, 0)
for name, fheaders := range r.MultipartForm.File {
for _, headers := range fheaders {
upload, err := saveFileUpload(headers, subdir, extension)
if err != nil {
return results, fmt.Errorf("Failed to save upload '%s': %w", name, err)
}
results = append(results, upload)
}
}
return results, nil
}
func saveFileUpload(headers *multipart.FileHeader, subdir string, extension string) (upload FileUpload, err error) {
file, err := headers.Open()
if err != nil {
return upload, fmt.Errorf("Failed to open header: %w", err)
}
defer file.Close()
file_bytes, err := io.ReadAll(file)
content_type := http.DetectContentType(file_bytes)
u, err := uuid.NewUUID()
if err != nil {
return upload, fmt.Errorf("Failed to create uuid", err)
}
err = fileContentWrite(bytes.NewReader(file_bytes), subdir, u, extension)
if err != nil {
return upload, fmt.Errorf("Failed to write file to disk: %w", err)
}
log.Info().Int("size", len(file_bytes)).Str("uploaded_filename", headers.Filename).Str("content-type", content_type).Str("uuid", u.String()).Msg("Saved an uploaded file to disk")
return FileUpload{
ContentType: content_type,
UploadFilename: headers.Filename,
UploadFilesize: len(file_bytes),
UUID: u,
}, nil
}

View file

@ -11,21 +11,26 @@ import (
"github.com/rs/zerolog/log"
)
func AudioFileContentPathRaw(audioUUID string) string {
return fmt.Sprintf("%s/%s.m4a", config.FilesDirectoryUser, audioUUID)
}
func AudioFileContentPathMp3(audioUUID string) string {
return fmt.Sprintf("%s/%s.mp3", config.FilesDirectoryUser, audioUUID)
}
func AudioFileContentPathNormalized(audioUUID string) string {
return fmt.Sprintf("%s/%s-normalized.m4a", config.FilesDirectoryUser, audioUUID)
}
func AudioFileContentPathOgg(audioUUID string) string {
return fmt.Sprintf("%s/%s.ogg", config.FilesDirectoryUser, audioUUID)
}
/*
func AudioFileContentPathRaw(audioUUID string) string {
return fmt.Sprintf("%s/%s.m4a", config.FilesDirectoryUser, audioUUID)
}
func AudioFileContentPathMp3(audioUUID string) string {
return fmt.Sprintf("%s/%s.mp3", config.FilesDirectoryUser, audioUUID)
}
func AudioFileContentPathNormalized(audioUUID string) string {
return fmt.Sprintf("%s/%s-normalized.m4a", config.FilesDirectoryUser, audioUUID)
}
func AudioFileContentPathOgg(audioUUID string) string {
return fmt.Sprintf("%s/%s.ogg", config.FilesDirectoryUser, audioUUID)
}
*/
func AudioFileContentWrite(audioUUID uuid.UUID, body io.Reader) error {
// Create file in configured directory
filepath := AudioFileContentPathRaw(audioUUID.String())
filepath := fileContentPath("user", audioUUID, "m4a")
dst, err := os.Create(filepath)
if err != nil {
log.Error().Err(err).Str("filepath", filepath).Msg("Failed to create audio file")
@ -41,17 +46,22 @@ func AudioFileContentWrite(audioUUID uuid.UUID, body io.Reader) error {
log.Info().Str("filepath", filepath).Msg("Save audio file content")
return nil
}
func ImageFileContentPathRawUser(uid string) string {
return imageFileContentPath(config.FilesDirectoryUser, uid, "raw")
}
func imageFileContentPathLogoPng(uid string) string {
return imageFileContentPath(config.FilesDirectoryLogo, uid, "png")
}
func imageFileContentPath(dir string, uid string, ext string) string {
return fmt.Sprintf("%s/%s.%s", dir, uid, ext)
}
/*
func ImageFileContentPathRawUser(uid string) string {
return imageFileContentPath(config.FilesDirectoryUser, uid, "raw")
}
func imageFileContentPathLogoPng(uid string) string {
return imageFileContentPath(config.FilesDirectoryLogo, uid, "png")
}
func imageFileContentPath(dir string, uid string, ext string) string {
return fmt.Sprintf("%s/%s.%s", dir, uid, ext)
}
*/
func ImageFileContentWrite(uid uuid.UUID, body io.Reader) error {
filepath := ImageFileContentPathRawUser(uid.String())
filepath := fileContentPath("user", uid, "raw")
// Create file in configured directory
dst, err := os.Create(filepath)
@ -68,13 +78,15 @@ func ImageFileContentWrite(uid uuid.UUID, body io.Reader) error {
return nil
}
func ImageFileContentWriteLogo(w http.ResponseWriter, uid uuid.UUID) {
image_path := imageFileContentPathLogoPng(uid.String())
//image_path := imageFileContentPathLogoPng(uid.String())
image_path := fileContentPath("logo", uid, "png")
writeFileContent(w, image_path)
}
func PublicImageFileContentWrite(uid uuid.UUID, body io.Reader) error {
// Create file in configured directory
filepath := PublicImageFileContentPathRaw(uid.String())
//filepath := PublicImageFileContentPathRaw(uid.String())
filepath := fileContentPath("public", uid, "raw")
dst, err := os.Create(filepath)
if err != nil {
log.Error().Err(err).Str("filepath", filepath).Msg("Failed to create public image file")
@ -91,15 +103,39 @@ func PublicImageFileContentWrite(uid uuid.UUID, body io.Reader) error {
return nil
}
/*
func PublicImageFileContentPathRaw(uid string) string {
return fmt.Sprintf("%s/%s.raw", config.FilesDirectoryPublic, uid)
}
*/
func PublicImageFileToResponse(w http.ResponseWriter, uid string) {
image_path := PublicImageFileContentPathRaw(uid)
func PublicImageFileToResponse(w http.ResponseWriter, uid uuid.UUID) {
//image_path := PublicImageFileContentPathRaw(uid)
image_path := fileContentPath("public", uid, "raw")
writeFileContent(w, image_path)
}
func fileContentPath(subdir string, uid uuid.UUID, extension string) string {
return fmt.Sprintf("%s/%s/%s.%s", config.FilesDirectory, subdir, uid.String(), extension)
}
func fileContentWrite(body io.Reader, subdir string, uid uuid.UUID, extension string) error {
// Create file in configured directory
filepath := fileContentPath(subdir, uid, extension)
dst, err := os.Create(filepath)
if err != nil {
log.Error().Err(err).Str("filepath", filepath).Msg("Failed to create file")
return fmt.Errorf("Failed to create file at %s: %v", filepath, err)
}
defer dst.Close()
// Copy rest of request body to file
_, err = io.Copy(dst, body)
if err != nil {
return fmt.Errorf("Unable to save content of %s: %v", filepath, err)
}
return nil
}
func writeFileContent(w http.ResponseWriter, image_path string) {
// Open the file
file, err := os.Open(image_path)