Added file management.
This commit is contained in:
parent
b808500a23
commit
ca1de66033
12 changed files with 201 additions and 21 deletions
100
pkg/handlers/files.go
Normal file
100
pkg/handlers/files.go
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
package handlers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"time"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/mikestefanello/pagoda/pkg/msg"
|
||||
"github.com/mikestefanello/pagoda/pkg/page"
|
||||
"github.com/mikestefanello/pagoda/pkg/services"
|
||||
"github.com/mikestefanello/pagoda/templates"
|
||||
"github.com/spf13/afero"
|
||||
)
|
||||
|
||||
const (
|
||||
routeNameFiles = "files"
|
||||
routeNameFilesSubmit = "files.submit"
|
||||
)
|
||||
|
||||
type (
|
||||
Files struct {
|
||||
files afero.Fs
|
||||
*services.TemplateRenderer
|
||||
}
|
||||
|
||||
File struct {
|
||||
Name string
|
||||
Size int64
|
||||
Modified string
|
||||
}
|
||||
)
|
||||
|
||||
func init() {
|
||||
Register(new(Files))
|
||||
}
|
||||
|
||||
func (h *Files) Init(c *services.Container) error {
|
||||
h.TemplateRenderer = c.TemplateRenderer
|
||||
h.files = c.Files
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *Files) Routes(g *echo.Group) {
|
||||
g.GET("/files", h.Page).Name = routeNameFiles
|
||||
g.POST("/files", h.Submit).Name = routeNameFilesSubmit
|
||||
}
|
||||
|
||||
func (h *Files) Page(ctx echo.Context) error {
|
||||
p := page.New(ctx)
|
||||
p.Layout = templates.LayoutMain
|
||||
p.Name = templates.PageFiles
|
||||
p.Title = "Upload a file"
|
||||
|
||||
// Send a list of all uploaded files to the template to be rendered.
|
||||
info, err := afero.ReadDir(h.files, "")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
files := make([]File, 0)
|
||||
for _, file := range info {
|
||||
files = append(files, File{
|
||||
Name: file.Name(),
|
||||
Size: file.Size(),
|
||||
Modified: file.ModTime().Format(time.DateTime),
|
||||
})
|
||||
}
|
||||
|
||||
p.Data = files
|
||||
|
||||
return h.RenderPage(ctx, p)
|
||||
}
|
||||
|
||||
func (h *Files) Submit(ctx echo.Context) error {
|
||||
file, err := ctx.FormFile("file")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
src, err := file.Open()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer src.Close()
|
||||
|
||||
dst, err := h.files.Create(file.Filename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer dst.Close()
|
||||
|
||||
if _, err = io.Copy(dst, src); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
msg.Success(ctx, fmt.Sprintf("%s was uploaded successfully.", file.Filename))
|
||||
|
||||
return h.Page(ctx)
|
||||
}
|
||||
|
|
@ -4,11 +4,13 @@ import (
|
|||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"github.com/mikestefanello/backlite"
|
||||
"log/slog"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/mikestefanello/backlite"
|
||||
"github.com/spf13/afero"
|
||||
|
||||
entsql "entgo.io/ent/dialect/sql"
|
||||
"github.com/labstack/echo/v4"
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
|
|
@ -39,6 +41,9 @@ type Container struct {
|
|||
// Database stores the connection to the database
|
||||
Database *sql.DB
|
||||
|
||||
// Files stores the file system.
|
||||
Files afero.Fs
|
||||
|
||||
// ORM stores a client to the ORM
|
||||
ORM *ent.Client
|
||||
|
||||
|
|
@ -63,6 +68,7 @@ func NewContainer() *Container {
|
|||
c.initWeb()
|
||||
c.initCache()
|
||||
c.initDatabase()
|
||||
c.initFiles()
|
||||
c.initORM()
|
||||
c.initAuth()
|
||||
c.initTemplateRenderer()
|
||||
|
|
@ -159,6 +165,21 @@ func (c *Container) initDatabase() {
|
|||
}
|
||||
}
|
||||
|
||||
// initFiles initializes the file system.
|
||||
func (c *Container) initFiles() {
|
||||
// Use in-memory storage for tests.
|
||||
if c.Config.App.Environment == config.EnvTest {
|
||||
c.Files = afero.NewMemMapFs()
|
||||
return
|
||||
}
|
||||
|
||||
fs := afero.NewOsFs()
|
||||
if err := fs.MkdirAll(c.Config.Files.Directory, 0755); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
c.Files = afero.NewBasePathFs(fs, c.Config.Files.Directory)
|
||||
}
|
||||
|
||||
// initORM initializes the ORM
|
||||
func (c *Container) initORM() {
|
||||
drv := entsql.OpenDB(c.Config.Database.Driver, c.Database)
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ func TestNewContainer(t *testing.T) {
|
|||
assert.NotNil(t, c.Validator)
|
||||
assert.NotNil(t, c.Cache)
|
||||
assert.NotNil(t, c.Database)
|
||||
assert.NotNil(t, c.Files)
|
||||
assert.NotNil(t, c.ORM)
|
||||
assert.NotNil(t, c.Mail)
|
||||
assert.NotNil(t, c.Auth)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue