diff options
-rw-r--r-- | addons/reference/reference.go | 53 | ||||
-rw-r--r-- | cmd/ponzu/main.go | 9 | ||||
-rw-r--r-- | system/addon/api.go | 43 | ||||
-rw-r--r-- | system/admin/config/config.go | 1 | ||||
-rw-r--r-- | system/admin/handlers.go | 5 | ||||
-rw-r--r-- | system/db/cache.go | 35 | ||||
-rw-r--r-- | system/db/config.go | 40 |
7 files changed, 117 insertions, 69 deletions
diff --git a/addons/reference/reference.go b/addons/reference/reference.go index b6cede8..78e46eb 100644 --- a/addons/reference/reference.go +++ b/addons/reference/reference.go @@ -1,44 +1,49 @@ +// Package reference is a Ponzu addon to enable content editors to create +// references to other content types which are stored as query strings within +// the referencer's content DB package reference import ( "bytes" "encoding/json" "fmt" + "html/template" "log" - "net/http" - "text/template" "github.com/bosssauce/ponzu/management/editor" + "github.com/bosssauce/ponzu/system/addon" ) -// Referenceable enures there is a way to reference the implenting type from -// within another type's editor and from type-scoped API calls -type Referenceable interface { - Referenced() []byte -} - // Select returns the []byte of a <select> HTML element plus internal <options> with a label. // IMPORTANT: // The `fieldName` argument will cause a panic if it is not exactly the string // form of the struct field that this editor input is representing -func Select(fieldName string, p interface{}, attrs map[string]string, contentType string, tmpl *template.Template) []byte { +func Select(fieldName string, p interface{}, attrs map[string]string, contentType, tmplString string) []byte { // decode all content type from db into options map // map["?type=<contentType>&id=<id>"]t.String() options := make(map[string]string) - var data []map[string]interface{} - j := ContentAll(contentType) + var all map[string]interface{} + j := addon.ContentAll(contentType) - err := json.Unmarshal(j, data) + err := json.Unmarshal(j, &all) if err != nil { return nil } + // make template for option html display + tmpl := template.Must(template.New(contentType).Parse(tmplString)) + + // make data something usable to iterate over and assign options + data := all["data"].([]interface{}) + for i := range data { - k := fmt.Sprintf("?type=%s&id=%s", contentType, data[i]["id"].(string)) + item := data[i].(map[string]interface{}) + k := fmt.Sprintf("?type=%s&id=%.0f", contentType, item["id"].(float64)) v := &bytes.Buffer{} - err := tmpl.Execute(v, data[i]) + err := tmpl.Execute(v, item) if err != nil { + log.Println("Error executing template for reference of:", contentType) return nil } @@ -47,23 +52,3 @@ func Select(fieldName string, p interface{}, attrs map[string]string, contentTyp return editor.Select(fieldName, p, attrs, options) } - -// ContentAll retrives all items from the HTTP API within the provided namespace -func ContentAll(namespace string) []byte { - endpoint := "http://0.0.0.0:8080/api/contents?type=" - buf := []byte{} - r := bytes.NewReader(buf) - req, err := http.NewRequest(http.MethodGet, endpoint+namespace, r) - if err != nil { - log.Println("Error creating request for reference from:", namespace) - return nil - } - - c := http.Client{} - res, err := c.Do(req) - defer res.Body.Close() - - fmt.Println(res, string(buf)) - - return buf -} diff --git a/cmd/ponzu/main.go b/cmd/ponzu/main.go index ebcbbad..4ae3bcc 100644 --- a/cmd/ponzu/main.go +++ b/cmd/ponzu/main.go @@ -291,7 +291,14 @@ func main() { tls.Enable() } - log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", port), nil)) + // save the port the system is listening on so internal system can make + // HTTP api calls while in dev or production w/o adding more cli flags + err := db.PutConfig("http_port", fmt.Sprintf("%d", port)) + if err != nil { + log.Fatalln("System failed to save config. Please try to run again.") + } + + log.Fatalln(http.ListenAndServe(fmt.Sprintf(":%d", port), nil)) case "": fmt.Println(usage) diff --git a/system/addon/api.go b/system/addon/api.go new file mode 100644 index 0000000..1ca260b --- /dev/null +++ b/system/addon/api.go @@ -0,0 +1,43 @@ +// Package addon provides an API for Ponzu addons to interface with the system +package addon + +import ( + "bytes" + "fmt" + "io/ioutil" + "log" + "net/http" + "time" + + "github.com/bosssauce/ponzu/system/db" +) + +// ContentAll retrives all items from the HTTP API within the provided namespace +func ContentAll(namespace string) []byte { + host := db.ConfigCache("domain") + port := db.ConfigCache("http_port") + endpoint := "http://%s:%s/api/contents?type=%s" + buf := []byte{} + r := bytes.NewReader(buf) + url := fmt.Sprintf(endpoint, host, port, namespace) + + req, err := http.NewRequest(http.MethodGet, url, r) + if err != nil { + log.Println("Error creating request for reference of:", namespace) + return nil + } + + c := http.Client{ + Timeout: time.Duration(time.Second * 5), + } + res, err := c.Do(req) + defer res.Body.Close() + + j, err := ioutil.ReadAll(res.Body) + if err != nil { + log.Println("Error reading request body for reference of:", namespace) + return nil + } + + return j +} diff --git a/system/admin/config/config.go b/system/admin/config/config.go index b898b49..2e957ed 100644 --- a/system/admin/config/config.go +++ b/system/admin/config/config.go @@ -12,6 +12,7 @@ type Config struct { Name string `json:"name"` Domain string `json:"domain"` + HTTPPort string `json:"http_port"` AdminEmail string `json:"admin_email"` ClientSecret string `json:"client_secret"` Etag string `json:"etag"` diff --git a/system/admin/handlers.go b/system/admin/handlers.go index fed77f7..55a5f30 100644 --- a/system/admin/handlers.go +++ b/system/admin/handlers.go @@ -71,6 +71,7 @@ func initHandler(res http.ResponseWriter, req *http.Request) { etag := db.NewEtag() req.Form.Set("etag", etag) + // create and save admin user email := strings.ToLower(req.FormValue("email")) password := req.FormValue("password") usr := user.NewUser(email, password) @@ -82,6 +83,10 @@ func initHandler(res http.ResponseWriter, req *http.Request) { return } + // set HTTP port which should be previously added to config cache + port := db.ConfigCache("http_port") + req.Form.Set("http_port", port) + // set initial user email as admin_email and make config req.Form.Set("admin_email", email) err = db.SetConfig(req.Form) diff --git a/system/db/cache.go b/system/db/cache.go index 5f2dd03..30ecf5a 100644 --- a/system/db/cache.go +++ b/system/db/cache.go @@ -2,10 +2,8 @@ package db import ( "encoding/base64" - "encoding/json" "fmt" "net/http" - "net/url" "strings" "time" ) @@ -39,41 +37,10 @@ func NewEtag() string { // InvalidateCache sets a new Etag for http responses func InvalidateCache() error { - kv := make(map[string]interface{}) - - c, err := ConfigAll() + err := PutConfig("etag", NewEtag()) if err != nil { return err } - err = json.Unmarshal(c, &kv) - if err != nil { - return err - } - - kv["etag"] = NewEtag() - - data := make(url.Values) - for k, v := range kv { - switch v.(type) { - case string: - data.Set(k, v.(string)) - case []string: - vv := v.([]string) - for i := range vv { - if i == 0 { - data.Set(k, vv[i]) - } else { - data.Add(k, vv[i]) - } - } - } - } - - err = SetConfig(data) - if err != nil { - - } - return nil } diff --git a/system/db/config.go b/system/db/config.go index b5a07e4..ef3c382 100644 --- a/system/db/config.go +++ b/system/db/config.go @@ -117,7 +117,47 @@ func ConfigAll() ([]byte, error) { return val.Bytes(), nil } +// PutConfig updates a single k/v in the config +func PutConfig(key string, value interface{}) error { + kv := make(map[string]interface{}) + + c, err := ConfigAll() + if err != nil { + return err + } + + err = json.Unmarshal(c, &kv) + if err != nil { + return err + } + + data := make(url.Values) + for k, v := range kv { + switch v.(type) { + case string: + data.Set(k, v.(string)) + case []string: + vv := v.([]string) + for i := range vv { + if i == 0 { + data.Set(k, vv[i]) + } else { + data.Add(k, vv[i]) + } + } + } + } + + err = SetConfig(data) + if err != nil { + return err + } + + return nil +} + // ConfigCache is a in-memory cache of the Configs for quicker lookups +// 'key' is the JSON tag associated with the config field func ConfigCache(key string) string { return configCache.Get(key) } |