205 lines
3.6 KiB
Go
205 lines
3.6 KiB
Go
package snap
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"net/http"
|
|
|
|
"git.twelvetwelve.org/library/snap/auth"
|
|
"github.com/gorilla/mux"
|
|
)
|
|
|
|
type Context struct {
|
|
srv *Server
|
|
auth *auth.AuthData
|
|
|
|
w http.ResponseWriter
|
|
r *http.Request
|
|
vars *Vars
|
|
form *Form
|
|
}
|
|
|
|
type SnapContent struct {
|
|
User string
|
|
UserProperties map[string]string
|
|
Theme string
|
|
Meta map[string]string
|
|
Content interface{}
|
|
}
|
|
|
|
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
|
|
}
|
|
|
|
func (c *Context) Error(code int, msg string) {
|
|
c.srv.renderError(c.w, code, msg)
|
|
}
|
|
|
|
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)
|
|
}
|
|
|
|
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{}) {
|
|
compact := c.r.Header.Get("Compact")
|
|
msg, err := json.Marshal(obj)
|
|
if err != nil {
|
|
c.Error(http.StatusInternalServerError, "Internal Server Error")
|
|
return
|
|
}
|
|
|
|
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)
|
|
}
|
|
|
|
func (c *Context) Render(tmpl string, content interface{}) {
|
|
c.srv.render(c.w, tmpl, content)
|
|
}
|
|
|
|
func (c *Context) RenderEx(tmpl string, content interface{}) {
|
|
cnt := SnapContent{
|
|
User: c.GetUser(),
|
|
Theme: c.srv.theme,
|
|
Meta: c.srv.meta,
|
|
Content: content,
|
|
}
|
|
|
|
if c.auth != nil {
|
|
fmt.Printf("Properties: %+v\n", c.auth.Properties)
|
|
cnt.UserProperties = c.auth.Properties
|
|
}
|
|
|
|
c.srv.render(c.w, tmpl, &cnt)
|
|
}
|
|
|
|
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 {
|
|
fmt.Printf("Properties: %+v\n", c.auth.Properties)
|
|
cnt.UserProperties = c.auth.Properties
|
|
}
|
|
|
|
c.srv.render(c.w, tmpl, &cnt)
|
|
}
|
|
|
|
func (c *Context) Form() (*Options, error) {
|
|
if c.form != nil {
|
|
return &Options{
|
|
kv: c.form,
|
|
}, nil
|
|
}
|
|
|
|
err := c.r.ParseForm()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
c.form = &Form{
|
|
r: c.r,
|
|
}
|
|
|
|
return &Options{
|
|
kv: c.form,
|
|
}, nil
|
|
}
|
|
|
|
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)
|
|
}
|
|
|
|
func (c *Context) QueryHas(key string) bool {
|
|
_, ok := c.r.URL.Query()[key]
|
|
return ok
|
|
}
|
|
|
|
func (c *Context) QueryValueWithDefault(key string, def string) string {
|
|
val := c.r.URL.Query().Get(key)
|
|
if val == "" {
|
|
return def
|
|
}
|
|
return val
|
|
}
|
|
|
|
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 {
|
|
if c.vars == nil {
|
|
c.vars = &Vars{
|
|
vars: mux.Vars(c.r),
|
|
}
|
|
}
|
|
|
|
return &Options{
|
|
kv: c.vars,
|
|
}
|
|
}
|