snap/context.go

202 lines
3.5 KiB
Go
Raw Normal View History

2018-02-07 22:25:00 +00:00
package snap
import (
2023-05-29 20:21:08 +00:00
"bytes"
"encoding/json"
"io/ioutil"
"net/http"
2023-05-23 14:09:57 +00:00
"git.twelvetwelve.org/library/snap/auth"
2023-05-29 20:38:37 +00:00
"github.com/gorilla/mux"
)
2018-02-07 22:25:00 +00:00
type Context struct {
srv *Server
auth *auth.AuthData
w http.ResponseWriter
r *http.Request
2023-05-29 20:21:08 +00:00
vars *Vars
form *Form
2018-02-07 22:25:00 +00:00
}
2018-02-11 00:17:14 +00:00
type SnapContent struct {
2021-05-29 21:14:15 +00:00
User string
UserProperties map[string]string
Theme string
Meta map[string]string
Content interface{}
2018-02-11 00:17:14 +00:00
}
2018-02-07 22:25:00 +00:00
func (c *Context) GetRequest() *http.Request {
return c.r
}
func (c *Context) Writer() http.ResponseWriter {
return c.w
}
func (c *Context) GetUser() string {
if c.auth == nil {
return ""
}
return c.auth.User
2018-02-07 22:25:00 +00:00
}
2018-02-11 00:17:14 +00:00
func (c *Context) Error(code int, msg string) {
c.srv.renderError(c.w, code, msg)
}
2021-05-29 21:14:15 +00:00
func (c *Context) ErrorObject(code int, obj interface{}) {
msg, err := json.Marshal(obj)
if err != nil {
c.Error(http.StatusInternalServerError, "Internal Server Error")
return
}
c.Error(code, string(msg))
}
func (c *Context) Reply(msg string) {
c.srv.reply(c.w, msg)
}
2021-05-29 21:14:15 +00:00
func (c *Context) ReplyWithHeaders(msg string, kv map[string]string) {
h := c.w.Header()
for k, v := range kv {
h.Add(k, v)
}
c.srv.reply(c.w, msg)
}
func (c *Context) ReplyObject(obj interface{}) {
2023-05-29 20:21:08 +00:00
compact := c.r.Header.Get("Compact")
msg, err := json.Marshal(obj)
if err != nil {
2021-05-29 21:14:15 +00:00
c.Error(http.StatusInternalServerError, "Internal Server Error")
return
}
2023-05-29 20:21:08 +00:00
if compact == "" {
var pretty bytes.Buffer
err := json.Indent(&pretty, msg, "", " ")
if err == nil {
msg = pretty.Bytes()
}
}
c.Reply(string(msg))
}
func (c *Context) GetObject(obj interface{}) error {
data, err := ioutil.ReadAll(c.r.Body)
defer c.r.Body.Close()
if err != nil {
return err
}
return json.Unmarshal(data, obj)
}
2018-02-07 22:25:00 +00:00
func (c *Context) Render(tmpl string, content interface{}) {
c.srv.render(c.w, tmpl, content)
}
2018-02-11 00:17:14 +00:00
func (c *Context) RenderEx(tmpl string, content interface{}) {
cnt := SnapContent{
User: c.GetUser(),
Theme: c.srv.theme,
2021-05-29 21:14:15 +00:00
Meta: c.srv.meta,
Content: content,
2018-02-11 00:17:14 +00:00
}
2021-06-18 19:43:52 +00:00
if c.auth != nil {
cnt.UserProperties = c.auth.Properties
}
2018-02-11 00:17:14 +00:00
c.srv.render(c.w, tmpl, &cnt)
}
2021-05-29 21:14:15 +00:00
func (c *Context) RenderWithMeta(tmpl string, meta map[string]string, content interface{}) {
// Merge metas
if meta == nil {
meta = make(map[string]string)
}
for k, v := range c.srv.meta {
if _, ok := meta[k]; !ok {
meta[k] = v
}
}
cnt := SnapContent{
User: c.GetUser(),
Theme: c.srv.theme,
Meta: meta,
Content: content,
}
if c.auth != nil {
cnt.UserProperties = c.auth.Properties
}
c.srv.render(c.w, tmpl, &cnt)
}
2023-05-29 20:21:08 +00:00
func (c *Context) Form() (*Options, error) {
if c.form != nil {
return &Options{
kv: c.form,
}, nil
2018-02-11 00:17:14 +00:00
}
2023-05-29 20:21:08 +00:00
err := c.r.ParseForm()
if err != nil {
2023-05-29 20:21:08 +00:00
return nil, err
}
2023-05-29 20:21:08 +00:00
c.form = &Form{
r: c.r,
2021-05-29 21:14:15 +00:00
}
2023-05-29 20:21:08 +00:00
return &Options{
kv: c.form,
}, nil
2021-05-29 21:14:15 +00:00
}
func (c *Context) Redirect(url string) {
http.Redirect(c.w, c.r, url, http.StatusSeeOther)
}
func (c *Context) QueryValue(key string) string {
return c.r.URL.Query().Get(key)
}
2019-10-20 14:01:21 +00:00
2021-05-29 21:14:15 +00:00
func (c *Context) QueryHas(key string) bool {
_, ok := c.r.URL.Query()[key]
return ok
}
2019-10-20 14:01:21 +00:00
func (c *Context) QueryValueWithDefault(key string, def string) string {
val := c.r.URL.Query().Get(key)
if val == "" {
return def
}
return val
}
2023-05-29 20:21:08 +00:00
func (c *Context) ReadObject(object interface{}) error {
defer c.r.Body.Close()
decoder := json.NewDecoder(c.r.Body)
return decoder.Decode(object)
}
func (c *Context) ParseVars() *Options {
2023-05-29 20:38:37 +00:00
if c.vars == nil {
c.vars = &Vars{
vars: mux.Vars(c.r),
2023-05-29 20:21:08 +00:00
}
}
return &Options{
2023-05-29 20:38:37 +00:00
kv: c.vars,
2023-05-29 20:21:08 +00:00
}
}