simple binary create, delete, list
This commit is contained in:
parent
e998272f81
commit
ebca3e84f2
|
@ -24,3 +24,11 @@ func (s *BinaryService) CreateEntryFile(name string, file []byte, entry model.En
|
||||||
func (s *BinaryService) FindById(id string) (*model.BinaryFile, error) {
|
func (s *BinaryService) FindById(id string) (*model.BinaryFile, error) {
|
||||||
return s.repo.FindById(id)
|
return s.repo.FindById(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *BinaryService) ListIds() ([]string, error) {
|
||||||
|
return s.repo.ListIds()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *BinaryService) Delete(binary *model.BinaryFile) error {
|
||||||
|
return s.repo.Delete(binary)
|
||||||
|
}
|
||||||
|
|
|
@ -19,6 +19,8 @@ type BinaryRepository interface {
|
||||||
Create(name string, data []byte, entry model.Entry) (*model.BinaryFile, error)
|
Create(name string, data []byte, entry model.Entry) (*model.BinaryFile, error)
|
||||||
FindById(id string) (*model.BinaryFile, error)
|
FindById(id string) (*model.BinaryFile, error)
|
||||||
FindByNameForEntry(name string, entry model.Entry) (*model.BinaryFile, error)
|
FindByNameForEntry(name string, entry model.Entry) (*model.BinaryFile, error)
|
||||||
|
ListIds() ([]string, error)
|
||||||
|
Delete(binary *model.BinaryFile) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type AuthorRepository interface {
|
type AuthorRepository interface {
|
||||||
|
|
|
@ -99,3 +99,21 @@ func (repo *DefaultBinaryFileRepo) FindByNameForEntry(name string, entry model.E
|
||||||
}
|
}
|
||||||
return &model.BinaryFile{Id: sqlFile.Id, Name: sqlFile.Name, Data: sqlFile.Data}, nil
|
return &model.BinaryFile{Id: sqlFile.Id, Name: sqlFile.Name, Data: sqlFile.Data}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ListIds implements repository.BinaryRepository
|
||||||
|
func (repo *DefaultBinaryFileRepo) ListIds() ([]string, error) {
|
||||||
|
var ids []string
|
||||||
|
err := repo.db.Select(&ids, "SELECT id FROM binary_files")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return ids, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete implements repository.BinaryRepository
|
||||||
|
func (repo *DefaultBinaryFileRepo) Delete(binary *model.BinaryFile) error {
|
||||||
|
id := binary.Id
|
||||||
|
println("Deleting binary file", id)
|
||||||
|
_, err := repo.db.Exec("DELETE FROM binary_files WHERE id = ?", id)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
{{define "title"}}Binaries{{end}}
|
||||||
|
|
||||||
|
{{define "main"}}
|
||||||
|
|
||||||
|
<h2>Binaries</h2>
|
||||||
|
|
||||||
|
<form action="/admin/binaries/new" method="post" enctype="multipart/form-data">
|
||||||
|
<div>
|
||||||
|
<label for="file">File</label>
|
||||||
|
<input type="file" name="file" id="file">
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<input type="submit" value="Upload">
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<table role="grid">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th scope="col">File</th>
|
||||||
|
<th scope="col">Actions</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
{{ range .Binaries }}
|
||||||
|
<tr>
|
||||||
|
<td scope="row">
|
||||||
|
<a href="/media/{{ . }}">{{ . }}</a>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<form action="/admin/binaries/delete" method="post">
|
||||||
|
<input type="hidden" name="file" value="{{ . }}">
|
||||||
|
<label for="confirm">
|
||||||
|
<input type="checkbox" name="confirm"> Confirm
|
||||||
|
</label>
|
||||||
|
<input style="padding:0;height:2rem;" type="submit" value="Delete">
|
||||||
|
</form>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{{ end }}
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
<nav class="row">
|
||||||
|
{{ if not .FirstPage }}
|
||||||
|
<div>
|
||||||
|
<a href="?page={{ .PrevPage }}">Prev</a>
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
<div>Page {{.Page}}</div>
|
||||||
|
|
||||||
|
{{ if not .LastPage }}
|
||||||
|
<div>
|
||||||
|
<a href="?page={{ .NextPage }}">Next</a>
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
{{end}}
|
|
@ -52,11 +52,15 @@ func NewWebApp(
|
||||||
|
|
||||||
// admin
|
// admin
|
||||||
adminHandler := NewAdminHandler(configRepo, configRegister, typeRegistry)
|
adminHandler := NewAdminHandler(configRepo, configRegister, typeRegistry)
|
||||||
|
binaryManageHandler := NewBinaryManageHandler(configRepo, binService)
|
||||||
admin := app.Group("/admin")
|
admin := app.Group("/admin")
|
||||||
admin.Use(middleware.NewAuthMiddleware(authorService).Handle)
|
admin.Use(middleware.NewAuthMiddleware(authorService).Handle)
|
||||||
admin.Get("/", adminHandler.Handle)
|
admin.Get("/", adminHandler.Handle)
|
||||||
admin.Get("/config/:config/", adminHandler.HandleConfigGet)
|
admin.Get("/config/:config/", adminHandler.HandleConfigGet)
|
||||||
admin.Post("/config/:config/", adminHandler.HandleConfigPost)
|
admin.Post("/config/:config/", adminHandler.HandleConfigPost)
|
||||||
|
admin.Get("/binaries/", binaryManageHandler.Handle)
|
||||||
|
admin.Post("/binaries/new/", binaryManageHandler.HandleUpload)
|
||||||
|
admin.Post("/binaries/delete", binaryManageHandler.HandleDelete)
|
||||||
|
|
||||||
// Editor
|
// Editor
|
||||||
editor := app.Group("/editor")
|
editor := app.Group("/editor")
|
||||||
|
|
|
@ -0,0 +1,92 @@
|
||||||
|
package web
|
||||||
|
|
||||||
|
import (
|
||||||
|
"owl-blogs/app"
|
||||||
|
"owl-blogs/app/repository"
|
||||||
|
"owl-blogs/render"
|
||||||
|
"sort"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/gofiber/fiber/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
type BinaryManageHandler struct {
|
||||||
|
configRepo repository.ConfigRepository
|
||||||
|
service *app.BinaryService
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewBinaryManageHandler(configRepo repository.ConfigRepository, service *app.BinaryService) *BinaryManageHandler {
|
||||||
|
return &BinaryManageHandler{
|
||||||
|
configRepo: configRepo,
|
||||||
|
service: service,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *BinaryManageHandler) Handle(c *fiber.Ctx) error {
|
||||||
|
siteConfig := getSiteConfig(h.configRepo)
|
||||||
|
|
||||||
|
allIds, err := h.service.ListIds()
|
||||||
|
sort.Slice(allIds, func(i, j int) bool {
|
||||||
|
return strings.ToLower(allIds[i]) < strings.ToLower(allIds[j])
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
pageData := paginate(c, allIds, 50)
|
||||||
|
|
||||||
|
c.Set(fiber.HeaderContentType, fiber.MIMETextHTML)
|
||||||
|
return render.RenderTemplateWithBase(c, siteConfig, "views/binary_manager", fiber.Map{
|
||||||
|
"Binaries": pageData.items,
|
||||||
|
"Page": pageData.page,
|
||||||
|
"NextPage": pageData.page + 1,
|
||||||
|
"PrevPage": pageData.page - 1,
|
||||||
|
"FirstPage": pageData.page == 1,
|
||||||
|
"LastPage": pageData.lastPage,
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *BinaryManageHandler) HandleUpload(c *fiber.Ctx) error {
|
||||||
|
file, err := c.FormFile("file")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
reader, err := file.Open()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer reader.Close()
|
||||||
|
|
||||||
|
content := make([]byte, file.Size)
|
||||||
|
_, err = reader.Read(content)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
binary, err := h.service.Create(file.Filename, content)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.Redirect("/media/" + binary.Id)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *BinaryManageHandler) HandleDelete(c *fiber.Ctx) error {
|
||||||
|
id := c.FormValue("file")
|
||||||
|
binary, err := h.service.FindById(id)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
confirm := c.FormValue("confirm")
|
||||||
|
if confirm != "on" {
|
||||||
|
return c.Redirect("/admin/binaries/")
|
||||||
|
}
|
||||||
|
|
||||||
|
err = h.service.Delete(binary)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.Redirect("/admin/binaries/")
|
||||||
|
}
|
37
web/utils.go
37
web/utils.go
|
@ -4,6 +4,9 @@ import (
|
||||||
"owl-blogs/app/repository"
|
"owl-blogs/app/repository"
|
||||||
"owl-blogs/config"
|
"owl-blogs/config"
|
||||||
"owl-blogs/domain/model"
|
"owl-blogs/domain/model"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/gofiber/fiber/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
func getSiteConfig(repo repository.ConfigRepository) model.SiteConfig {
|
func getSiteConfig(repo repository.ConfigRepository) model.SiteConfig {
|
||||||
|
@ -14,3 +17,37 @@ func getSiteConfig(repo repository.ConfigRepository) model.SiteConfig {
|
||||||
}
|
}
|
||||||
return siteConfig
|
return siteConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type paginationData[T any] struct {
|
||||||
|
items []T
|
||||||
|
page uint
|
||||||
|
lastPage bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func paginate[T any](c *fiber.Ctx, items []T, limit int) paginationData[T] {
|
||||||
|
page := c.Query("page")
|
||||||
|
if page == "" {
|
||||||
|
page = "1"
|
||||||
|
}
|
||||||
|
pageNum, err := strconv.Atoi(page)
|
||||||
|
if err != nil {
|
||||||
|
pageNum = 1
|
||||||
|
}
|
||||||
|
offset := (pageNum - 1) * limit
|
||||||
|
lastPage := false
|
||||||
|
if offset > len(items) {
|
||||||
|
offset = len(items)
|
||||||
|
lastPage = true
|
||||||
|
}
|
||||||
|
if offset+limit > len(items) {
|
||||||
|
limit = len(items) - offset
|
||||||
|
lastPage = true
|
||||||
|
}
|
||||||
|
items = items[offset : offset+limit]
|
||||||
|
|
||||||
|
return paginationData[T]{
|
||||||
|
items: items,
|
||||||
|
page: uint(pageNum),
|
||||||
|
lastPage: lastPage,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue