Have got saving working
This commit is contained in:
parent
f9a65c8ca9
commit
c8a276b248
|
|
@ -1,3 +1,4 @@
|
||||||
|
import feather from "feather-icons/dist/feather.js";
|
||||||
import Handlebars from "handlebars";
|
import Handlebars from "handlebars";
|
||||||
import {Controller} from "@hotwired/stimulus";
|
import {Controller} from "@hotwired/stimulus";
|
||||||
|
|
||||||
|
|
@ -7,12 +8,12 @@ Handlebars.registerHelper("submit_on", function (id, event) {
|
||||||
|
|
||||||
const processorFrame = Handlebars.compile(`
|
const processorFrame = Handlebars.compile(`
|
||||||
<div class="card mb-3">
|
<div class="card mb-3">
|
||||||
<div class="card-header d-flex justify-content-between">
|
<div class="card-header d-flex justify-content-between align-items-center">
|
||||||
<span>{{name}}</span>
|
<span>{{name}}</span>
|
||||||
<a href="#" class="btn btn-sm btn-secondary float-end"
|
<a href="#" class="float-end"
|
||||||
data-action="edit-upload#removeProcessor"
|
data-action="edit-upload#removeProcessor"
|
||||||
data-edit-upload-id-param="{{id}}"
|
data-edit-upload-id-param="{{id}}"
|
||||||
>X</a>
|
><i data-feather="x" width="18" height="18"></i></a>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<form data-role="processor-params" data-params-id="{{id}}">{{{props}}}</form>
|
<form data-role="processor-params" data-params-id="{{id}}">{{{props}}}</form>
|
||||||
|
|
@ -78,6 +79,16 @@ export default class UploadEditController extends Controller {
|
||||||
await this._removeProcessor(id);
|
await this._removeProcessor(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async saveUpload(ev) {
|
||||||
|
ev.preventDefault();
|
||||||
|
await this._save("replace");
|
||||||
|
}
|
||||||
|
|
||||||
|
async saveNewUpload(ev) {
|
||||||
|
ev.preventDefault();
|
||||||
|
await this._save("copy");
|
||||||
|
}
|
||||||
|
|
||||||
async updateProcessor(ev) {
|
async updateProcessor(ev) {
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
let id = ev.params.id;
|
let id = ev.params.id;
|
||||||
|
|
@ -108,6 +119,8 @@ export default class UploadEditController extends Controller {
|
||||||
});
|
});
|
||||||
el.innerHTML += cardOuter;
|
el.innerHTML += cardOuter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
feather.replace();
|
||||||
}
|
}
|
||||||
|
|
||||||
async _createSession() {
|
async _createSession() {
|
||||||
|
|
@ -179,6 +192,33 @@ export default class UploadEditController extends Controller {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async _save(mode) {
|
||||||
|
if (!this._state || !this._state.session) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
let resp = await fetch(`/sites/${this.siteIdValue}/imageedit/${this._state.session.guid}/save`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Accept': 'application/json',
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ mode })
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!resp.ok) {
|
||||||
|
console.error("Save failed:", resp.statusText);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let result = await resp.json();
|
||||||
|
window.location.href = `/sites/${this.siteIdValue}/uploads/${result.upload_id}`;
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async _doReturningState(fn) {
|
async _doReturningState(fn) {
|
||||||
try {
|
try {
|
||||||
this._state = await fn();
|
this._state = await fn();
|
||||||
|
|
|
||||||
|
|
@ -156,6 +156,7 @@ Starting weiro without any arguments will start the server.
|
||||||
siteGroup.Patch("/imageedit/:sessionID", ieh.PatchSession)
|
siteGroup.Patch("/imageedit/:sessionID", ieh.PatchSession)
|
||||||
siteGroup.Post("/imageedit/:sessionID/processors", ieh.AddProcessor)
|
siteGroup.Post("/imageedit/:sessionID/processors", ieh.AddProcessor)
|
||||||
siteGroup.Delete("/imageedit/:sessionID/processors/:processorID", ieh.DeleteProcessor)
|
siteGroup.Delete("/imageedit/:sessionID/processors/:processorID", ieh.DeleteProcessor)
|
||||||
|
siteGroup.Post("/imageedit/:sessionID/save", ieh.Save)
|
||||||
siteGroup.Get("/imageedit/:sessionID/preview/:versionID", ieh.Preview)
|
siteGroup.Get("/imageedit/:sessionID/preview/:versionID", ieh.Preview)
|
||||||
|
|
||||||
siteGroup.Get("/settings", ssh.General)
|
siteGroup.Get("/settings", ssh.General)
|
||||||
|
|
|
||||||
|
|
@ -114,6 +114,27 @@ func (ieh ImageEditHandlers) DeleteProcessor(c fiber.Ctx) error {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ieh ImageEditHandlers) Save(c fiber.Ctx) error {
|
||||||
|
sessionID := c.Params("sessionID")
|
||||||
|
if sessionID == "" {
|
||||||
|
return fiber.ErrBadRequest
|
||||||
|
}
|
||||||
|
|
||||||
|
var req struct {
|
||||||
|
Mode string `json:"mode"`
|
||||||
|
}
|
||||||
|
if err := c.Bind().JSON(&req); err != nil {
|
||||||
|
return fiber.ErrBadRequest
|
||||||
|
}
|
||||||
|
|
||||||
|
result, err := ieh.ImageEditService.Save(c.Context(), sessionID, req.Mode)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.Status(http.StatusOK).JSON(result)
|
||||||
|
}
|
||||||
|
|
||||||
func (ieh ImageEditHandlers) PatchSession(c fiber.Ctx) error {
|
func (ieh ImageEditHandlers) PatchSession(c fiber.Ctx) error {
|
||||||
var req struct {
|
var req struct {
|
||||||
UpdateProc *imgedit.UpdateProcessorReq `json:"processor"`
|
UpdateProc *imgedit.UpdateProcessorReq `json:"processor"`
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
// Code generated by sqlc. DO NOT EDIT.
|
// Code generated by sqlc. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// sqlc v1.28.0
|
// sqlc v1.30.0
|
||||||
// source: categories.sql
|
// source: categories.sql
|
||||||
|
|
||||||
package sqlgen
|
package sqlgen
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
// Code generated by sqlc. DO NOT EDIT.
|
// Code generated by sqlc. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// sqlc v1.28.0
|
// sqlc v1.30.0
|
||||||
|
|
||||||
package sqlgen
|
package sqlgen
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
// Code generated by sqlc. DO NOT EDIT.
|
// Code generated by sqlc. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// sqlc v1.28.0
|
// sqlc v1.30.0
|
||||||
|
|
||||||
package sqlgen
|
package sqlgen
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
// Code generated by sqlc. DO NOT EDIT.
|
// Code generated by sqlc. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// sqlc v1.28.0
|
// sqlc v1.30.0
|
||||||
// source: pages.sql
|
// source: pages.sql
|
||||||
|
|
||||||
package sqlgen
|
package sqlgen
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
// Code generated by sqlc. DO NOT EDIT.
|
// Code generated by sqlc. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// sqlc v1.28.0
|
// sqlc v1.30.0
|
||||||
// source: pending_uploads.sql
|
// source: pending_uploads.sql
|
||||||
|
|
||||||
package sqlgen
|
package sqlgen
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
// Code generated by sqlc. DO NOT EDIT.
|
// Code generated by sqlc. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// sqlc v1.28.0
|
// sqlc v1.30.0
|
||||||
// source: posts.sql
|
// source: posts.sql
|
||||||
|
|
||||||
package sqlgen
|
package sqlgen
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
// Code generated by sqlc. DO NOT EDIT.
|
// Code generated by sqlc. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// sqlc v1.28.0
|
// sqlc v1.30.0
|
||||||
// source: pubtargets.sql
|
// source: pubtargets.sql
|
||||||
|
|
||||||
package sqlgen
|
package sqlgen
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
// Code generated by sqlc. DO NOT EDIT.
|
// Code generated by sqlc. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// sqlc v1.28.0
|
// sqlc v1.30.0
|
||||||
// source: sites.sql
|
// source: sites.sql
|
||||||
|
|
||||||
package sqlgen
|
package sqlgen
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
// Code generated by sqlc. DO NOT EDIT.
|
// Code generated by sqlc. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// sqlc v1.28.0
|
// sqlc v1.30.0
|
||||||
// source: uploads.sql
|
// source: uploads.sql
|
||||||
|
|
||||||
package sqlgen
|
package sqlgen
|
||||||
|
|
@ -18,7 +18,7 @@ func (q *Queries) DeleteUpload(ctx context.Context, id int64) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
const insertUpload = `-- name: InsertUpload :exec
|
const insertUpload = `-- name: InsertUpload :one
|
||||||
INSERT INTO uploads (
|
INSERT INTO uploads (
|
||||||
site_id,
|
site_id,
|
||||||
guid,
|
guid,
|
||||||
|
|
@ -43,8 +43,8 @@ type InsertUploadParams struct {
|
||||||
CreatedAt int64
|
CreatedAt int64
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *Queries) InsertUpload(ctx context.Context, arg InsertUploadParams) error {
|
func (q *Queries) InsertUpload(ctx context.Context, arg InsertUploadParams) (int64, error) {
|
||||||
_, err := q.db.ExecContext(ctx, insertUpload,
|
row := q.db.QueryRowContext(ctx, insertUpload,
|
||||||
arg.SiteID,
|
arg.SiteID,
|
||||||
arg.Guid,
|
arg.Guid,
|
||||||
arg.MimeType,
|
arg.MimeType,
|
||||||
|
|
@ -54,7 +54,9 @@ func (q *Queries) InsertUpload(ctx context.Context, arg InsertUploadParams) erro
|
||||||
arg.Alt,
|
arg.Alt,
|
||||||
arg.CreatedAt,
|
arg.CreatedAt,
|
||||||
)
|
)
|
||||||
return err
|
var id int64
|
||||||
|
err := row.Scan(&id)
|
||||||
|
return id, err
|
||||||
}
|
}
|
||||||
|
|
||||||
const selectUploadByID = `-- name: SelectUploadByID :one
|
const selectUploadByID = `-- name: SelectUploadByID :one
|
||||||
|
|
@ -154,3 +156,17 @@ func (q *Queries) UpdateUpload(ctx context.Context, arg UpdateUploadParams) erro
|
||||||
_, err := q.db.ExecContext(ctx, updateUpload, arg.Alt, arg.ID)
|
_, err := q.db.ExecContext(ctx, updateUpload, arg.Alt, arg.ID)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const updateUploadFileSize = `-- name: UpdateUploadFileSize :exec
|
||||||
|
UPDATE uploads SET file_size = ? WHERE id = ?
|
||||||
|
`
|
||||||
|
|
||||||
|
type UpdateUploadFileSizeParams struct {
|
||||||
|
FileSize int64
|
||||||
|
ID int64
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) UpdateUploadFileSize(ctx context.Context, arg UpdateUploadFileSizeParams) error {
|
||||||
|
_, err := q.db.ExecContext(ctx, updateUploadFileSize, arg.FileSize, arg.ID)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
// Code generated by sqlc. DO NOT EDIT.
|
// Code generated by sqlc. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// sqlc v1.28.0
|
// sqlc v1.30.0
|
||||||
// source: users.sql
|
// source: users.sql
|
||||||
|
|
||||||
package sqlgen
|
package sqlgen
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ func (db *Provider) SelectUploadBySiteIDAndSlug(ctx context.Context, siteID int6
|
||||||
|
|
||||||
func (db *Provider) SaveUpload(ctx context.Context, upload *models.Upload) error {
|
func (db *Provider) SaveUpload(ctx context.Context, upload *models.Upload) error {
|
||||||
if upload.ID == 0 {
|
if upload.ID == 0 {
|
||||||
if err := db.queries.InsertUpload(ctx, sqlgen.InsertUploadParams{
|
newID, err := db.queries.InsertUpload(ctx, sqlgen.InsertUploadParams{
|
||||||
SiteID: upload.SiteID,
|
SiteID: upload.SiteID,
|
||||||
Guid: upload.GUID,
|
Guid: upload.GUID,
|
||||||
MimeType: upload.MIMEType,
|
MimeType: upload.MIMEType,
|
||||||
|
|
@ -53,9 +53,11 @@ func (db *Provider) SaveUpload(ctx context.Context, upload *models.Upload) error
|
||||||
Slug: upload.Slug,
|
Slug: upload.Slug,
|
||||||
Alt: upload.Alt,
|
Alt: upload.Alt,
|
||||||
CreatedAt: upload.CreatedAt.Unix(),
|
CreatedAt: upload.CreatedAt.Unix(),
|
||||||
}); err != nil {
|
})
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
upload.ID = newID
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -65,6 +67,13 @@ func (db *Provider) SaveUpload(ctx context.Context, upload *models.Upload) error
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (db *Provider) UpdateUploadFileSize(ctx context.Context, id int64, fileSize int64) error {
|
||||||
|
return db.queries.UpdateUploadFileSize(ctx, sqlgen.UpdateUploadFileSizeParams{
|
||||||
|
FileSize: fileSize,
|
||||||
|
ID: id,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func (db *Provider) DeleteUpload(ctx context.Context, id int64) error {
|
func (db *Provider) DeleteUpload(ctx context.Context, id int64) error {
|
||||||
return db.queries.DeleteUpload(ctx, id)
|
return db.queries.DeleteUpload(ctx, id)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,11 @@ func copyFile(src, dst string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *Provider) ReplaceFile(site models.Site, up models.Upload, srcPath string) error {
|
||||||
|
fullPath := p.uploadFileName(site, up)
|
||||||
|
return copyFile(srcPath, fullPath)
|
||||||
|
}
|
||||||
|
|
||||||
func (p *Provider) OpenUpload(site models.Site, up models.Upload) (io.ReadCloser, error) {
|
func (p *Provider) OpenUpload(site models.Site, up models.Upload) (io.ReadCloser, error) {
|
||||||
fullPath := p.uploadFileName(site, up)
|
fullPath := p.uploadFileName(site, up)
|
||||||
return os.Open(fullPath)
|
return os.Open(fullPath)
|
||||||
|
|
|
||||||
|
|
@ -175,6 +175,58 @@ func (s *Service) UpdateProcessor(ctx context.Context, sessionID string, req Upd
|
||||||
return session, nil
|
return session, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type SaveResult struct {
|
||||||
|
UploadID int64 `json:"upload_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) Save(ctx context.Context, sessionID string, mode string) (*SaveResult, error) {
|
||||||
|
session, err := s.loadAndVerifySession(ctx, sessionID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(session.Processors) == 0 {
|
||||||
|
return nil, fmt.Errorf("no processors in session")
|
||||||
|
}
|
||||||
|
|
||||||
|
lastProc := session.Processors[len(session.Processors)-1]
|
||||||
|
finalImagePath := fmt.Sprintf("%v/%v/%v.%v", s.scratchDir, session.GUID, lastProc.VersionID, session.ImageExt)
|
||||||
|
|
||||||
|
var mimeType string
|
||||||
|
switch session.ImageExt {
|
||||||
|
case "jpg", "jpeg":
|
||||||
|
mimeType = "image/jpeg"
|
||||||
|
case "png":
|
||||||
|
mimeType = "image/png"
|
||||||
|
}
|
||||||
|
|
||||||
|
var uploadID int64
|
||||||
|
switch mode {
|
||||||
|
case "replace":
|
||||||
|
upload, err := s.uploadService.ReplaceUploadFile(ctx, session.BaseUploadID, finalImagePath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
uploadID = upload.ID
|
||||||
|
case "copy":
|
||||||
|
baseUpload, _, err := s.uploadService.OpenUpload(ctx, session.BaseUploadID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
upload, err := s.uploadService.CreateUploadFromFile(ctx, finalImagePath, baseUpload.Filename, mimeType)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
uploadID = upload.ID
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("unknown save mode: %v", mode)
|
||||||
|
}
|
||||||
|
|
||||||
|
s.sessionStore.delete(session.GUID)
|
||||||
|
|
||||||
|
return &SaveResult{UploadID: uploadID}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Service) loadAndVerifySession(ctx context.Context, sessionID string) (*models.ImageEditSession, error) {
|
func (s *Service) loadAndVerifySession(ctx context.Context, sessionID string) (*models.ImageEditSession, error) {
|
||||||
site, user, err := s.fetchSiteAndUser(ctx)
|
site, user, err := s.fetchSiteAndUser(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,10 @@ func (ss *sessionStore) get(guid string) (*models.ImageEditSession, error) {
|
||||||
return &sessionData, nil
|
return &sessionData, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ss *sessionStore) delete(guid string) {
|
||||||
|
os.RemoveAll(filepath.Join(ss.baseDir, guid))
|
||||||
|
}
|
||||||
|
|
||||||
func (ss *sessionStore) getImage(session *models.ImageEditSession, imageFilename string) (string, func() (io.ReadCloser, error), error) {
|
func (ss *sessionStore) getImage(session *models.ImageEditSession, imageFilename string) (string, func() (io.ReadCloser, error), error) {
|
||||||
fullPath := filepath.Join(ss.baseDir, session.GUID, imageFilename)
|
fullPath := filepath.Join(ss.baseDir, session.GUID, imageFilename)
|
||||||
if s, err := os.Stat(fullPath); err != nil {
|
if s, err := os.Stat(fullPath); err != nil {
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,10 @@ import (
|
||||||
"html/template"
|
"html/template"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"lmika.dev/lmika/weiro/models"
|
"lmika.dev/lmika/weiro/models"
|
||||||
)
|
)
|
||||||
|
|
@ -67,6 +70,75 @@ func (s *Service) renderCopyTemplate(upload models.Upload) string {
|
||||||
return sb.String()
|
return sb.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Service) ReplaceUploadFile(ctx context.Context, uploadID int64, srcPath string) (models.Upload, error) {
|
||||||
|
site, _, err := s.fetchSiteAndUser(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return models.Upload{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
upload, err := s.db.SelectUploadByID(ctx, uploadID)
|
||||||
|
if err != nil {
|
||||||
|
return models.Upload{}, err
|
||||||
|
} else if upload.SiteID != site.ID {
|
||||||
|
return models.Upload{}, models.NotFoundError
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := s.up.ReplaceFile(site, upload, srcPath); err != nil {
|
||||||
|
return models.Upload{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
stat, err := os.Stat(srcPath)
|
||||||
|
if err != nil {
|
||||||
|
return models.Upload{}, err
|
||||||
|
}
|
||||||
|
upload.FileSize = stat.Size()
|
||||||
|
|
||||||
|
if err := s.db.UpdateUploadFileSize(ctx, upload.ID, upload.FileSize); err != nil {
|
||||||
|
return models.Upload{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return upload, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) CreateUploadFromFile(ctx context.Context, srcPath string, filename string, mimeType string) (models.Upload, error) {
|
||||||
|
site, _, err := s.fetchSiteAndUser(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return models.Upload{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
stat, err := os.Stat(srcPath)
|
||||||
|
if err != nil {
|
||||||
|
return models.Upload{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
newUploadGUID := models.NewNanoID()
|
||||||
|
newTime := time.Now().UTC()
|
||||||
|
newSlug := filepath.Join(
|
||||||
|
fmt.Sprintf("%04d", newTime.Year()),
|
||||||
|
fmt.Sprintf("%02d", newTime.Month()),
|
||||||
|
newUploadGUID+filepath.Ext(filename),
|
||||||
|
)
|
||||||
|
|
||||||
|
newUpload := models.Upload{
|
||||||
|
SiteID: site.ID,
|
||||||
|
GUID: models.NewNanoID(),
|
||||||
|
FileSize: stat.Size(),
|
||||||
|
MIMEType: mimeType,
|
||||||
|
Filename: filename,
|
||||||
|
CreatedAt: newTime,
|
||||||
|
Slug: newSlug,
|
||||||
|
}
|
||||||
|
if err := s.db.SaveUpload(ctx, &newUpload); err != nil {
|
||||||
|
return models.Upload{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := s.up.AdoptFile(site, newUpload, srcPath); err != nil {
|
||||||
|
return models.Upload{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return newUpload, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Service) ListUploads(ctx context.Context) (res []UploadWithURL, _ error) {
|
func (s *Service) ListUploads(ctx context.Context) (res []UploadWithURL, _ error) {
|
||||||
site, _, err := s.fetchSiteAndUser(ctx)
|
site, _, err := s.fetchSiteAndUser(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ SELECT * FROM uploads WHERE id = ? LIMIT 1;
|
||||||
-- name: SelectUploadBySiteIDAndSlug :one
|
-- name: SelectUploadBySiteIDAndSlug :one
|
||||||
SELECT * FROM uploads WHERE site_id = ? AND slug = ? LIMIT 1;
|
SELECT * FROM uploads WHERE site_id = ? AND slug = ? LIMIT 1;
|
||||||
|
|
||||||
-- name: InsertUpload :exec
|
-- name: InsertUpload :one
|
||||||
INSERT INTO uploads (
|
INSERT INTO uploads (
|
||||||
site_id,
|
site_id,
|
||||||
guid,
|
guid,
|
||||||
|
|
@ -23,5 +23,8 @@ RETURNING id;
|
||||||
-- name: UpdateUpload :exec
|
-- name: UpdateUpload :exec
|
||||||
UPDATE uploads SET alt = ? WHERE id = ?;
|
UPDATE uploads SET alt = ? WHERE id = ?;
|
||||||
|
|
||||||
|
-- name: UpdateUploadFileSize :exec
|
||||||
|
UPDATE uploads SET file_size = ? WHERE id = ?;
|
||||||
|
|
||||||
-- name: DeleteUpload :exec
|
-- name: DeleteUpload :exec
|
||||||
DELETE FROM uploads WHERE id = ?;
|
DELETE FROM uploads WHERE id = ?;
|
||||||
|
|
@ -24,7 +24,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-9">
|
<div class="col-md-9 m-3">
|
||||||
<button class="btn btn-primary" data-action="edit-upload#saveUpload">Save</button>
|
<button class="btn btn-primary" data-action="edit-upload#saveUpload">Save</button>
|
||||||
<button class="btn btn-secondary" data-action="edit-upload#saveNewUpload">Save as Copy</button>
|
<button class="btn btn-secondary" data-action="edit-upload#saveNewUpload">Save as Copy</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,10 @@
|
||||||
data-show-upload-site-id-value="{{ .upload.Upload.SiteID }}"
|
data-show-upload-site-id-value="{{ .upload.Upload.SiteID }}"
|
||||||
data-show-upload-upload-id-value="{{ .upload.Upload.ID }}">
|
data-show-upload-upload-id-value="{{ .upload.Upload.ID }}">
|
||||||
<button class="btn btn-outline-dark" data-action="show-upload#copy">Copy HTML</button>
|
<button class="btn btn-outline-dark" data-action="show-upload#copy">Copy HTML</button>
|
||||||
<button class="btn btn-danger" data-action="show-upload#delete">Delete</button>
|
<span>
|
||||||
|
<a href="/sites/{{ .site.ID }}/uploads/{{ .upload.Upload.ID }}/edit" class="btn btn-secondary">Edit</a>
|
||||||
|
<button class="btn btn-danger" data-action="show-upload#delete">Delete</button>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<figure>
|
<figure>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue