summaryrefslogtreecommitdiff
path: root/src/http/assets.go
blob: 8c5ac7e1612428819bae74b2bafc22fd2954a6a3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
package http

import (
	"bytes"
	"errors"
	"fmt"
	"net/http"
	"path/filepath"
	"strings"
	"time"

	"dev.mediocregopher.com/mediocre-blog.git/src/http/apiutil"
	"dev.mediocregopher.com/mediocre-blog.git/src/post/asset"
)

func (a *api) managePostAssetsHandler() http.Handler {
	tpl := a.mustParseBasedTpl("post-assets-manage.html")
	return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
		a.executeTemplate(rw, r, tpl, nil)
	})
}

func (a *api) getPostAssetHandler() http.Handler {

	return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {

		maxWidth, err := apiutil.StrToInt(r.FormValue("w"), 0)
		if err != nil {
			apiutil.BadRequest(rw, r, fmt.Errorf("invalid w parameter: %w", err))
			return
		}

		var (
			path = strings.TrimPrefix(r.URL.Path, "/")
			buf  = new(bytes.Buffer)
		)

		err = a.params.PostAssetLoader.Load(
			path,
			buf,
			asset.LoadOpts{
				ImageWidth: maxWidth,
			},
		)

		if errors.Is(err, asset.ErrNotFound) {
			http.Error(rw, "Asset not found", 404)
			return

		} else if errors.Is(err, asset.ErrCannotResize) {
			http.Error(rw, "Image resizing not supported", 400)
			return

		} else if err != nil {
			apiutil.InternalServerError(
				rw, r, fmt.Errorf("fetching asset at path %q: %w", path, err),
			)
			return
		}

		http.ServeContent(
			rw, r, path, time.Time{}, bytes.NewReader(buf.Bytes()),
		)
	})
}

func (a *api) postPostAssetHandler() http.Handler {

	return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {

		id := r.PostFormValue("id")
		if id == "" {
			apiutil.BadRequest(rw, r, errors.New("id is required"))
			return
		}

		file, _, err := r.FormFile("file")
		if err != nil {
			apiutil.BadRequest(rw, r, fmt.Errorf("reading multipart file: %w", err))
			return
		}
		defer file.Close()

		if err := a.params.PostAssetStore.Set(id, file); err != nil {
			apiutil.InternalServerError(rw, r, fmt.Errorf("storing file: %w", err))
			return
		}

		a.executeRedirectTpl(rw, r, a.manageAssetsURL(false))
	})
}

func (a *api) deletePostAssetHandler() http.Handler {

	return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {

		id := filepath.Base(r.URL.Path)

		if id == "/" {
			apiutil.BadRequest(rw, r, errors.New("id is required"))
			return
		}

		err := a.params.PostAssetStore.Delete(id)

		if errors.Is(err, asset.ErrNotFound) {
			http.Error(rw, "Asset not found", 404)
			return
		} else if err != nil {
			apiutil.InternalServerError(
				rw, r, fmt.Errorf("deleting asset with id %q: %w", id, err),
			)
			return
		}

		a.executeRedirectTpl(rw, r, a.manageAssetsURL(false))
	})
}