Paperclip/pkg/internal/fs/merger.go

73 lines
1.6 KiB
Go
Raw Normal View History

package fs
2024-08-20 09:08:40 +00:00
import (
"fmt"
"io"
"os"
"path/filepath"
2024-09-22 07:39:36 +00:00
2024-11-02 02:41:31 +00:00
"git.solsynth.dev/hypernet/paperclip/pkg/internal/database"
"git.solsynth.dev/hypernet/paperclip/pkg/internal/models"
2024-09-22 07:39:36 +00:00
"github.com/spf13/viper"
2024-08-20 09:08:40 +00:00
)
func MergeFileChunks(meta models.AttachmentFragment, arrange []string) (models.Attachment, error) {
attachment := meta.ToAttachment()
2024-09-22 07:39:36 +00:00
// Fetch destination from config
destMap := viper.GetStringMapString("destinations.0")
2024-08-20 09:08:40 +00:00
var dest models.LocalDestination
2024-09-22 07:39:36 +00:00
dest.Path = destMap["path"]
2024-08-20 09:08:40 +00:00
2024-09-22 07:39:36 +00:00
// Create the destination file
2024-08-20 09:08:40 +00:00
destPath := filepath.Join(dest.Path, meta.Uuid)
destFile, err := os.Create(destPath)
if err != nil {
return attachment, err
2024-08-20 09:08:40 +00:00
}
defer destFile.Close()
2024-09-22 07:39:36 +00:00
// 32KB buffer
buf := make([]byte, 32*1024)
// Merge the chunks into the destination file
2024-08-20 09:08:40 +00:00
for _, chunk := range arrange {
chunkPath := filepath.Join(dest.Path, fmt.Sprintf("%s.part%s", meta.Uuid, chunk))
2024-08-20 09:08:40 +00:00
chunkFile, err := os.Open(chunkPath)
if err != nil {
return attachment, err
2024-08-20 09:08:40 +00:00
}
2024-09-22 07:39:36 +00:00
defer chunkFile.Close() // Ensure the file is closed after reading
2024-08-20 09:08:40 +00:00
2024-09-22 07:39:36 +00:00
for {
n, err := chunkFile.Read(buf)
if err != nil && err != io.EOF {
return attachment, err
2024-09-22 07:39:36 +00:00
}
if n == 0 {
break
}
if _, err := destFile.Write(buf[:n]); err != nil {
return attachment, err
2024-09-22 07:39:36 +00:00
}
}
2024-08-20 09:08:40 +00:00
}
2024-09-22 07:39:36 +00:00
// Clean up: remove chunk files
go DeleteFragment(meta)
2024-08-20 14:55:58 +00:00
for _, chunk := range arrange {
chunkPath := filepath.Join(dest.Path, fmt.Sprintf("%s.part%s", meta.Uuid, chunk))
2024-09-22 07:39:36 +00:00
if err := os.Remove(chunkPath); err != nil {
return attachment, err
2024-09-22 07:39:36 +00:00
}
2024-08-20 14:55:58 +00:00
}
// Clean up: remove fragment record
database.C.Delete(&meta)
return attachment, nil
2024-08-20 09:08:40 +00:00
}