snap/context.go

209 lines
3.8 KiB
Go

package snap
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"strconv"
"strings"
"git.thirdmartini.com/pub/snap/auth"
)
type Context struct {
srv *Server
auth *auth.AuthData
w http.ResponseWriter
r *http.Request
vars map[string]string
}
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{}) {
msg, err := json.Marshal(obj)
if err != nil {
c.Error(http.StatusInternalServerError, "Internal Server Error")
return
}
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) GetVar(k string) (string, bool) {
v, ok := c.vars[k]
return v, ok
}
func (c *Context) GetVarDefault(k string, def string) string {
v, ok := c.vars[k]
if !ok {
return def
}
return v
}
func (c *Context) GetVarAsSlice(k string, delim string, def []string) []string {
v, ok := c.vars[k]
if !ok {
return def
}
r := strings.Split(v, delim)
if len(r) == 1 && r[0] == "" {
return def
}
return r
}
func (c *Context) ParseForm() error {
return c.r.ParseForm()
}
func (c *Context) FormValue(k string) string {
return c.r.FormValue(k)
}
func (c *Context) FormValueUint64(k string) uint64 {
str := c.r.FormValue(k)
val, err := strconv.ParseUint(str, 10, 64)
if err != nil {
return 0
}
return val
}
func (c *Context) FormValueAsSlice(k string, delim string) []string {
v := c.r.FormValue(k)
r := strings.Split(v, delim)
if len(r) == 1 && r[0] == "" {
return []string{}
}
return r
}
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
}