~evanj/cms

ref: 40c0e4fc7f8f794524c1f37f2c5d7355b4985475 cms/internal/c/space/space.go -rw-r--r-- 3.6 KiB
40c0e4fcEvan M Jones Chore(readme): Removing tag line. 1 year, 4 months ago
                                                                                
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
package space

import (
	"fmt"
	"log"
	"net/http"
	"strconv"
	"strings"

	"git.sr.ht/~evanj/cms/internal/c"
	"git.sr.ht/~evanj/cms/internal/m/contenttype"
	"git.sr.ht/~evanj/cms/internal/m/hook"
	"git.sr.ht/~evanj/cms/internal/m/space"
	"git.sr.ht/~evanj/cms/internal/m/user"
	"git.sr.ht/~evanj/cms/internal/s/tmpl"
)

var (
	spaceHTML = tmpl.MustParse("html/space.html")
)

type Space struct {
	*c.Controller
	log *log.Logger
	db  dber
}

type dber interface {
	UserGet(username, password string) (user.User, error)
	UserGetFromToken(token string) (user.User, error)
	SpaceNew(user user.User, name, desc string) (space.Space, error)
	SpaceGet(user user.User, spaceID string) (space.Space, error)
	SpaceDelete(space space.Space) error
	ContentTypesPerSpace(space space.Space, page int) ([]contenttype.ContentType, error)
	HookPerSpace(space space.Space, page int) ([]hook.Hook, error)
}

func New(log *log.Logger, db dber) *Space {
	return &Space{
		c.New(log, db),
		log,
		db,
	}
}

func (s *Space) serve(w http.ResponseWriter, r *http.Request, spaceID string) {
	user, err := s.GetCookieUser(w, r)
	if err != nil {
		s.Error(w, r, http.StatusBadRequest, "must be logged in to create space")
		return
	}

	space, err := s.db.SpaceGet(user, spaceID)
	if err != nil {
		s.Error(w, r, http.StatusNotFound, "failed to find space")
		return
	}

	page, err := strconv.Atoi(r.URL.Query().Get("page"))
	if err != nil || page < 1 {
		page = 1
	}
	page-- // Show one to user but start counting at zero for us.

	cts, err := s.db.ContentTypesPerSpace(space, page)
	if err != nil {
		s.Error(w, r, http.StatusInternalServerError, "failed to find contenttypes for space")
		return
	}

	// TODO: Page differently? Yes.
	hooks, err := s.db.HookPerSpace(space, page)
	if err != nil {
		s.log.Println(err)
		s.Error(w, r, http.StatusInternalServerError, "failed to find webhooks for space")
		return
	}

	s.HTML(w, r, spaceHTML, map[string]interface{}{
		"User":         user,
		"Space":        space,
		"ContentTypes": cts,
		"Hooks":        hooks,
	})
}

func (s *Space) create(w http.ResponseWriter, r *http.Request) {
	name := r.FormValue("name")
	desc := r.FormValue("desc")

	user, err := s.GetCookieUser(w, r)
	if err != nil {
		s.Error(w, r, http.StatusBadRequest, "must be logged in to create space")
		return
	}

	space, err := s.db.SpaceNew(user, name, desc)
	if err != nil {
		s.log.Println(err)
		s.Error(w, r, http.StatusBadRequest, err.Error())
		return
	}

	url := fmt.Sprintf("/space/%s", space.ID())
	s.log.Println("successfully created new space for user", user.Name(), "redirecting to", url)
	http.Redirect(w, r, url, http.StatusTemporaryRedirect)
}

func (s *Space) delete(w http.ResponseWriter, r *http.Request) {
	spaceID := r.FormValue("space")

	user, err := s.GetCookieUser(w, r)
	if err != nil {
		s.Error(w, r, http.StatusBadRequest, "must be logged in to create space")
		return
	}

	space, err := s.db.SpaceGet(user, spaceID)
	if err != nil {
		s.Error(w, r, http.StatusNotFound, "failed to find space")
		return
	}

	if err := s.db.SpaceDelete(space); err != nil {
		s.log.Println(err)
		s.Error(w, r, http.StatusInternalServerError, "failed to delete space")
		return
	}

	url := "/"
	s.log.Println("successfully deleted space for user", user.Name(), "redirecting to", url)
	http.Redirect(w, r, url, http.StatusTemporaryRedirect)
}

func (s *Space) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	switch r.URL.Path {
	case "/space/new":
		s.create(w, r)
		return
	case "/space/delete":
		s.delete(w, r)
		return
	}

	parts := strings.Split(r.URL.Path, "/")
	if len(parts) > 2 {
		s.serve(w, r, parts[2])
		return
	}

	http.NotFound(w, r)
}