edge/pkg/module/file.go

294 lines
7.3 KiB
Go

package module
// import (
// "context"
// "fmt"
// "io"
// "mime/multipart"
// "os"
// "path/filepath"
// "time"
// "forge.cadoles.com/arcad/edge/pkg/app"
// "forge.cadoles.com/arcad/edge/pkg/bus"
// "github.com/dop251/goja"
// "github.com/genjidb/genji"
// "github.com/genjidb/genji/database"
// "github.com/genjidb/genji/document"
// "github.com/google/uuid"
// "github.com/pkg/errors"
// "github.com/spf13/afero"
// "gitlab.com/wpetit/goweb/logger"
// )
// const (
// fileKeyID = "id"
// collectionFiles = "files"
// )
// type FileEntry struct {
// ID string
// Filename string
// Size int64
// ContentType string
// CreatedAt string
// Metadata map[string]interface{}
// }
// type FileModule struct {
// appID app.ID
// backend *app.Server
// bus bus.Bus
// db *AppDatabaseMixin
// dataDir string
// fs afero.Fs
// }
// func (m *FileModule) Name() string {
// return "file"
// }
// func (m *FileModule) Export(export *goja.Object) {
// // if err := export.Set("ls", m.ls); err != nil {
// // panic(errors.Wrap(err, "could not set 'save' function"))
// // }
// }
// func (m *FileModule) logAndPanic(msg string, err error) {
// err = errors.Wrap(err, msg)
// logger.Error(context.Background(), msg, logger.E(err))
// panic(errors.WithStack(err))
// }
// func (m *FileModule) handleMessages() {
// ctx := context.Background()
// ns := createAppMessageNamespace(m.appID)
// go func() {
// err := m.bus.Reply(ctx, ns, MessageTypeUploadRequest, func(msg bus.Message) (bus.Message, error) {
// uploadRequest, ok := msg.(*MessageUploadRequest)
// if !ok {
// return nil, errors.Wrapf(bus.ErrUnexpectedMessage, "expected message upload request, got '%s'", msg.MessageType())
// }
// res, err := m.handleUploadRequest(uploadRequest)
// if err != nil {
// logger.Error(ctx, "could not handle upload request", logger.E(errors.WithStack(err)))
// return nil, errors.WithStack(err)
// }
// logger.Debug(ctx, "upload request response", logger.F("response", res))
// return res, nil
// })
// if err != nil {
// panic(errors.WithStack(err))
// }
// }()
// err := m.bus.Reply(ctx, ns, MessageTypeDownloadRequest, func(msg bus.Message) (bus.Message, error) {
// downloadRequest, ok := msg.(*MessageDownloadRequest)
// if !ok {
// return nil, errors.Wrapf(bus.ErrUnexpectedMessage, "expected message download request, got '%s'", msg.MessageType())
// }
// res, err := m.handleDownloadRequest(downloadRequest)
// if err != nil {
// logger.Error(ctx, "could not handle download request", logger.E(errors.WithStack(err)))
// return nil, errors.WithStack(err)
// }
// return res, nil
// })
// if err != nil {
// panic(errors.WithStack(err))
// }
// }
// func (m *FileModule) handleUploadRequest(req *MessageUploadRequest) (*MessageUploadResponse, error) {
// fileInfo := map[string]interface{}{
// "filename": req.Header.Filename,
// "contentType": req.Header.Header.Get("Content-Type"),
// "size": req.Header.Size,
// "metadata": req.Metadata,
// }
// res := NewMessageUploadResponse(req.AppID, req.UserID, req.RequestID)
// fileID := uuid.New().String()
// result, err := m.backend.ExecFuncByName("onFileUpload", req.UserID, fileID, fileInfo)
// if err != nil {
// if errors.Is(err, app.ErrFuncDoesNotExist) {
// res.Allow = false
// return res, nil
// }
// return nil, errors.WithStack(err)
// }
// res.Allow = result.ToBoolean()
// if res.Allow {
// if err := m.saveFile(fileID, req.UserID, req.Header, req.File, req.Metadata); err != nil {
// return nil, errors.WithStack(err)
// }
// res.FileID = fileID
// }
// return res, nil
// }
// func (m *FileModule) saveFile(fileID string, header *multipart.FileHeader, file multipart.File, metadata map[string]interface{}) error {
// err := m.db.WithCollectionTx(collectionFiles, func(tx *genji.Tx) error {
// entry := &FileEntry{
// ID: fileID,
// Filename: header.Filename,
// Size: header.Size,
// ContentType: header.Header.Get("Content-Type"),
// CreatedAt: time.Now().UTC().String(),
// Metadata: metadata,
// }
// insertQuery := fmt.Sprintf("INSERT INTO `%s` VALUES ?", collectionFiles)
// if err := tx.Exec(insertQuery, &entry); err != nil {
// return errors.WithStack(err)
// }
// fileDir := m.getFileDir(fileID)
// if err := m.fs.MkdirAll(fileDir, 0o755); err != nil {
// return errors.WithStack(err)
// }
// filePath := filepath.Join(fileDir, fileID)
// newFile, err := m.fs.Create(filePath)
// if err != nil {
// return errors.WithStack(err)
// }
// defer newFile.Close()
// if _, err := io.Copy(newFile, file); err != nil {
// return errors.WithStack(err)
// }
// return nil
// })
// if err != nil {
// return errors.WithStack(err)
// }
// return nil
// }
// func (m *FileModule) handleDownloadRequest(req *MessageDownloadRequest) (*MessageDownloadResponse, error) {
// res := NewMessageDownloadResponse(req.AppID, req.UserID, req.RequestID)
// result, err := m.backend.ExecFuncByName("onFileDownload", req.UserID, req.FileID)
// if err != nil {
// if errors.Is(err, app.ErrFuncDoesNotExist) {
// res.Allow = false
// return res, nil
// }
// return nil, errors.WithStack(err)
// }
// res.Allow = result.ToBoolean()
// file, fileEntry, err := m.openFile(req.FileID)
// if err != nil && !os.IsNotExist(errors.Cause(err)) {
// return nil, errors.WithStack(err)
// }
// if file != nil {
// res.File = file
// }
// if fileEntry != nil {
// res.Filename = fileEntry.Filename
// res.ContentType = fileEntry.ContentType
// res.Size = fileEntry.Size
// }
// return res, nil
// }
// func (m *FileModule) openFile(fileID string) (afero.File, *FileEntry, error) {
// var (
// fileEntry *FileEntry
// file afero.File
// )
// err := m.db.WithCollectionTx(collectionFiles, func(tx *genji.Tx) error {
// selectQuery := fmt.Sprintf("SELECT * FROM `%s` WHERE id = ?", collectionFiles)
// doc, err := tx.QueryDocument(selectQuery, fileID)
// if err != nil {
// if errors.Is(err, database.ErrDocumentNotFound) {
// return nil
// }
// return errors.WithStack(err)
// }
// fileEntry = &FileEntry{}
// if err := document.StructScan(doc, fileEntry); err != nil {
// return errors.WithStack(err)
// }
// fileDir := m.getFileDir(fileID)
// filePath := filepath.Join(fileDir, fileID)
// file, err = m.fs.Open(filePath)
// if err != nil {
// file = nil
// return errors.WithStack(err)
// }
// return nil
// })
// if err != nil {
// return nil, nil, errors.WithStack(err)
// }
// return file, fileEntry, nil
// }
// func (m *FileModule) getFileDir(fileID string) string {
// return filepath.Join(m.dataDir, string(m.appID), "files", fileID[0:2], fileID[2:4], fileID[4:6])
// }
// func FileModuleFactory(dataDir string, bus bus.Bus) app.ServerModuleFactory {
// return func(appID app.ID, backend *app.Server) app.ServerModule {
// var fs afero.Fs
// if dataDir == inMemory {
// fs = afero.NewMemMapFs()
// } else {
// fs = afero.NewOsFs()
// }
// mod := &FileModule{
// dataDir: dataDir,
// appID: appID,
// bus: bus,
// backend: backend,
// db: NewAppDatabaseMixin(dataDir, "file.db", appID),
// fs: fs,
// }
// go mod.handleMessages()
// return mod
// }
// }