aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--auth_persona.go56
-rw-r--r--core.go26
-rw-r--r--core_test.go4
-rw-r--r--formats.go10
-rw-r--r--octopart.go277
-rw-r--r--octopart_test.go87
-rw-r--r--serve.go245
7 files changed, 374 insertions, 331 deletions
diff --git a/auth_persona.go b/auth_persona.go
index 7895c2d..2b5942e 100644
--- a/auth_persona.go
+++ b/auth_persona.go
@@ -1,52 +1,52 @@
package main
import (
- "encoding/json"
- "io"
- "io/ioutil"
- "log"
- "net/http"
- "net/url"
+ "encoding/json"
+ "io"
+ "io/ioutil"
+ "log"
+ "net/http"
+ "net/url"
)
type PersonaResponse struct {
- Status, Email, Reason string
+ Status, Email, Reason string
}
func (b PersonaResponse) Okay() bool {
- return b.Status == "okay"
+ return b.Status == "okay"
}
func VerifyPersonaAssertion(assertion, audience string) PersonaResponse {
- resp, _ := http.PostForm(
- "https://browserid.org/verify",
- url.Values{
- "assertion": {assertion},
- "audience": {audience},
- })
- response := personaResponseFromJson(resp.Body)
- resp.Body.Close()
-
- return response
+ resp, _ := http.PostForm(
+ "https://browserid.org/verify",
+ url.Values{
+ "assertion": {assertion},
+ "audience": {audience},
+ })
+ response := personaResponseFromJson(resp.Body)
+ resp.Body.Close()
+
+ return response
}
func personaResponseFromJson(r io.Reader) (resp PersonaResponse) {
- body, err := ioutil.ReadAll(r)
+ body, err := ioutil.ReadAll(r)
- if err != nil {
- log.Fatal(err)
- }
+ if err != nil {
+ log.Fatal(err)
+ }
- err = json.Unmarshal(body, &resp)
+ err = json.Unmarshal(body, &resp)
- if err != nil {
- log.Fatal(err)
- }
+ if err != nil {
+ log.Fatal(err)
+ }
- return resp
+ return resp
}
-type PersonaAuth bool
+type PersonaAuth bool
func (pa PersonaAuth) CheckLogin(name, pw string) error {
return nil
diff --git a/core.go b/core.go
index 31bbbf3..f6bc5e3 100644
--- a/core.go
+++ b/core.go
@@ -15,22 +15,22 @@ type Offer struct {
Sku string `json:"sku"`
Url string `json:"distributor_url"`
Comment string `json:"comment"`
- Available uint32 `json:"avail"`
+ Available uint32 `json:"avail"`
Prices []OfferPrice `json:"prices"`
}
type LineItem struct {
- Manufacturer string `json:"manufacturer"`
- Mpn string `json:"mpn"`
- Description string `json:"description"`
- FormFactor string `json:"form_factor"` // type:string
- Specs string `json:"specs"` // comma seperated list
- Comment string `json:"comment"`
- Tag string `json:"tag"` // comma seperated list
- Category string `json:"category"` // hierarchy as comma seperated list
- Elements []string `json:"elements"`
- Offers []Offer `json:"offers"`
- AggregateInfo map[string]string `json:"miscinfo"`
+ Manufacturer string `json:"manufacturer"`
+ Mpn string `json:"mpn"`
+ Description string `json:"description"`
+ FormFactor string `json:"form_factor"` // type:string
+ Specs string `json:"specs"` // comma seperated list
+ Comment string `json:"comment"`
+ Tag string `json:"tag"` // comma seperated list
+ Category string `json:"category"` // hierarchy as comma seperated list
+ Elements []string `json:"elements"`
+ Offers []Offer `json:"offers"`
+ AggregateInfo map[string]string `json:"miscinfo"`
}
func (li *LineItem) Id() string {
@@ -117,6 +117,6 @@ func makeTestBom() (*BomMeta, *Bom) {
b.AddLineItem(&li)
b.AddLineItem(&li)
b.AddLineItem(&li)
- bm := &BomMeta{Name: "Some Bom", Owner: "Some Owner", Description: "This is such a thing!", HeadVersion: b.Version, Homepage: "http://bommom.com", IsPublicView: true, IsPublicEdit: false}
+ bm := &BomMeta{Name: "Some Bom", Owner: "Some Owner", Description: "This is such a thing!", HeadVersion: b.Version, Homepage: "http://bommom.com", IsPublicView: true, IsPublicEdit: false}
return bm, b
}
diff --git a/core_test.go b/core_test.go
index b89e23f..d1905cb 100644
--- a/core_test.go
+++ b/core_test.go
@@ -8,7 +8,7 @@ import (
)
func TestNewBom(t *testing.T) {
- b := makeTestBom()
+ b, _ := makeTestBom()
if b == nil {
t.Errorf("Something went wrong")
}
@@ -16,7 +16,7 @@ func TestNewBom(t *testing.T) {
func TestBomJSONDump(t *testing.T) {
- b := makeTestBom()
+ b, _ := makeTestBom()
enc := json.NewEncoder(os.Stdout)
if err := enc.Encode(b); err != nil {
diff --git a/formats.go b/formats.go
index 3afe788..a1d6146 100644
--- a/formats.go
+++ b/formats.go
@@ -100,8 +100,8 @@ func LoadBomFromCSV(input io.Reader) (*Bom, error) {
header, err := reader.Read()
if err != nil {
- log.Printf("error parsing .csv: %s", err)
- return nil, err
+ log.Printf("error parsing .csv: %s", err)
+ return nil, err
}
var li *LineItem
var el_count int
@@ -151,9 +151,9 @@ func LoadBomFromCSV(input io.Reader) (*Bom, error) {
el_count = len(li.Elements)
// XXX: kludge
if n > 99999 || el_count > 99999 {
- err = Error("too large a quantity of elements passed")
- log.Printf("error parsing .csv: %s", err)
- return nil, err
+ err = Error("too large a quantity of elements passed")
+ log.Printf("error parsing .csv: %s", err)
+ return nil, err
} else if el_count > n {
if *verbose {
log.Println("more symbols than qty, taking all symbols")
diff --git a/octopart.go b/octopart.go
index 367bc99..654c03d 100644
--- a/octopart.go
+++ b/octopart.go
@@ -1,12 +1,12 @@
package main
import (
- "net/http"
- "net/url"
- "encoding/json"
- "bytes"
- "log"
- //"io/ioutil"
+ "bytes"
+ "encoding/json"
+ "log"
+ "net/http"
+ "net/url"
+ //"io/ioutil"
)
/*
@@ -17,143 +17,176 @@ LineItems.
var pricingSource *OctopartClient
type OctopartClient struct {
- ApiKey string
- RemoteHost string
- client *http.Client
- infoCache map[string]interface{}
+ ApiKey string
+ RemoteHost string
+ client *http.Client
+ infoCache map[string]interface{}
}
func NewOctopartClient(apikey string) *OctopartClient {
- oc := &OctopartClient{ApiKey: apikey,
- RemoteHost: "https://octopart.com"}
- oc.client = &http.Client{}
- oc.infoCache = make(map[string]interface{})
- return oc
+ oc := &OctopartClient{ApiKey: apikey,
+ RemoteHost: "https://octopart.com"}
+ oc.client = &http.Client{}
+ oc.infoCache = make(map[string]interface{})
+ return oc
}
func openPricingSource() {
- // TODO: pass through octopart API key here
- pricingSource = NewOctopartClient("")
+ // TODO: pass through octopart API key here
+ pricingSource = NewOctopartClient("")
}
func (oc *OctopartClient) apiCall(method string, params map[string]string) (map[string]interface{}, error) {
- paramString := "?apikey=" + oc.ApiKey
- // TODO: assert clean-ness of params
- // TODO: use url.Values instead...
- for key := range params {
- paramString += "&" + url.QueryEscape(key) + "=" + url.QueryEscape(params[key])
- }
- paramStringUnescaped, _ := url.QueryUnescape(paramString) // TODO: err
- log.Println("Fetching: " + oc.RemoteHost + "/api/v2/" + method + paramStringUnescaped)
- resp, err := oc.client.Get(oc.RemoteHost + "/api/v2/" + method + paramString)
- if err != nil {
- return nil, err
- }
- if resp.StatusCode != 200 {
- return nil, Error("Octopart API call error: " + resp.Status)
- }
- result := make(map[string]interface{})
- defer resp.Body.Close()
- //body, err := ioutil.ReadAll(resp.Body)
- //if err != nil {
- // return nil, err
- //}
- //body = append(body, '\n')
- //dec := json.NewDecoder(bytes.NewReader(body))
- dec := json.NewDecoder(resp.Body)
- if err = dec.Decode(&result); err != nil {
- return nil, err
- }
- return result, nil
+ paramString := "?apikey=" + oc.ApiKey
+ // TODO: assert clean-ness of params
+ // TODO: use url.Values instead...
+ for key := range params {
+ paramString += "&" + url.QueryEscape(key) + "=" + url.QueryEscape(params[key])
+ }
+ paramStringUnescaped, _ := url.QueryUnescape(paramString) // TODO: err
+ log.Println("Fetching: " + oc.RemoteHost + "/api/v2/" + method + paramStringUnescaped)
+ resp, err := oc.client.Get(oc.RemoteHost + "/api/v2/" + method + paramString)
+ if err != nil {
+ return nil, err
+ }
+ if resp.StatusCode != 200 {
+ return nil, Error("Octopart API call error: " + resp.Status)
+ }
+ result := make(map[string]interface{})
+ defer resp.Body.Close()
+ //body, err := ioutil.ReadAll(resp.Body)
+ //if err != nil {
+ // return nil, err
+ //}
+ //body = append(body, '\n')
+ //dec := json.NewDecoder(bytes.NewReader(body))
+ dec := json.NewDecoder(resp.Body)
+ if err = dec.Decode(&result); err != nil {
+ return nil, err
+ }
+ return result, nil
}
// this method doesn't check internal cache, but it does append to it
func (oc *OctopartClient) bomApiCall(manufacturers, mpns []string) ([]map[string]interface{}, error) {
- // TODO: check len(mpns) == len(manufacturers)
- queryList := make([]map[string]string, len(mpns))
- listItem := make(map[string]string)
- for i, _ := range mpns {
- listItem = make(map[string]string)
- listItem["mpn_or_sku"] = mpns[i]
- listItem["manufacturer"] = manufacturers[i]
- listItem["limit"] = "1"
- listItem["reference"] = manufacturers[i] + "|" + mpns[i]
- queryList[i] = listItem
- }
+ // TODO: check len(mpns) == len(manufacturers)
+ queryList := make([]map[string]string, len(mpns))
+ listItem := make(map[string]string)
+ for i, _ := range mpns {
+ listItem = make(map[string]string)
+ listItem["mpn_or_sku"] = mpns[i]
+ listItem["manufacturer"] = manufacturers[i]
+ listItem["limit"] = "1"
+ listItem["reference"] = manufacturers[i] + "|" + mpns[i]
+ queryList[i] = listItem
+ }
- linesBuffer := new(bytes.Buffer)
- enc := json.NewEncoder(linesBuffer)
- if err := enc.Encode(queryList); err != nil {
- return nil, err
- }
+ linesBuffer := new(bytes.Buffer)
+ enc := json.NewEncoder(linesBuffer)
+ if err := enc.Encode(queryList); err != nil {
+ return nil, err
+ }
- response, err := oc.apiCall("bom/match", map[string]string{"lines": linesBuffer.String()})
- if err != nil {
- return nil, err
- }
- // TODO: just grabbing first result for now; user can make better specification later
- ret := make([]map[string]interface{}, len(mpns))
- for i, rawresult := range response["results"].([]interface{}) {
- result := rawresult.(map[string]interface{})
- hits := int(result["hits"].(float64))
- reference := result["reference"].(string)
- if hits == 0 {
- ret[i] = nil
- oc.infoCache[reference] = nil
- } else {
- ret[i] = result["items"].([]interface{})[0].(map[string]interface{})
- oc.infoCache[reference] = ret[i]
- }
- }
- return ret, nil
+ response, err := oc.apiCall("bom/match", map[string]string{"lines": linesBuffer.String()})
+ if err != nil {
+ return nil, err
+ }
+ // TODO: just grabbing first result for now; user can make better specification later
+ ret := make([]map[string]interface{}, len(mpns))
+ for i, rawresult := range response["results"].([]interface{}) {
+ result := rawresult.(map[string]interface{})
+ hits := int(result["hits"].(float64))
+ reference := result["reference"].(string)
+ if hits == 0 {
+ ret[i] = nil
+ oc.infoCache[reference] = nil
+ } else {
+ ret[i] = result["items"].([]interface{})[0].(map[string]interface{})
+ oc.infoCache[reference] = ret[i]
+ }
+ }
+ return ret, nil
}
-func (oc *OctopartClient) GetMarketInfo(manufacturers, mpns []string) ([]interface{}, error) {
- if len(mpns) < 1 {
- return nil, Error("no mpns strings passed in")
- }
- if len(mpns) != len(manufacturers) {
- return nil, Error("number of mpns doesn't match number of manufacturers")
- }
- if len(mpns) > 100 {
- return nil, Error("can't handle more than 100 queries at a time (yet)")
- }
- mpnToQuery := make([]string, 0)
- manufacturersToQuery := make([]string, 0)
- queryHash := ""
- // check for queryHashes in internal cache
- for i, _ := range mpns {
- queryHash = manufacturers[i] + "|" + mpns[i]
- if _, hasKey := oc.infoCache[queryHash]; hasKey != true {
- manufacturersToQuery = append(manufacturersToQuery, manufacturers[i])
- mpnToQuery = append(mpnToQuery, mpns[i])
- }
- }
- // if necessary, fetch missing queryHashes to internal cache
- if len(mpnToQuery) > 0 {
- if _, err := oc.bomApiCall(manufacturersToQuery, mpnToQuery); err != nil {
- return nil, err
- }
- }
- // construct list of return info
- result := make([]interface{}, len(mpns))
- for i, _ := range mpns {
- queryHash = manufacturers[i] + "|" + mpns[i]
- value, hasKey := oc.infoCache[queryHash]
- if hasKey != true {
- return nil, Error("key should be in cache, but isn't: " + queryHash)
- }
- result[i] = value
- }
- return result, nil
+// this method checks the API query cache
+func (oc *OctopartClient) GetMarketInfoList(manufacturers, mpns []string) ([]interface{}, error) {
+ if len(mpns) < 1 {
+ return nil, Error("no mpns strings passed in")
+ }
+ if len(mpns) != len(manufacturers) {
+ return nil, Error("number of mpns doesn't match number of manufacturers")
+ }
+ if len(mpns) > 100 {
+ return nil, Error("can't handle more than 100 queries at a time (yet)")
+ }
+ mpnToQuery := make([]string, 0)
+ manufacturersToQuery := make([]string, 0)
+ queryHash := ""
+ // check for queryHashes in internal cache
+ for i, _ := range mpns {
+ queryHash = manufacturers[i] + "|" + mpns[i]
+ if _, hasKey := oc.infoCache[queryHash]; hasKey != true {
+ manufacturersToQuery = append(manufacturersToQuery, manufacturers[i])
+ mpnToQuery = append(mpnToQuery, mpns[i])
+ }
+ }
+ // if necessary, fetch missing queryHashes remotely
+ if len(mpnToQuery) > 0 {
+ if _, err := oc.bomApiCall(manufacturersToQuery, mpnToQuery); err != nil {
+ return nil, err
+ }
+ }
+ // construct list of return info
+ result := make([]interface{}, len(mpns))
+ for i, _ := range mpns {
+ queryHash = manufacturers[i] + "|" + mpns[i]
+ value, hasKey := oc.infoCache[queryHash]
+ if hasKey != true {
+ return nil, Error("key should be in cache, but isn't: " + queryHash)
+ }
+ result[i] = value
+ }
+ return result, nil
}
-func (oc *OctopartClient) GetReducedPricing(mpn, manufacturer string) (interface{}, error) {
- marketInfo, err := oc.GetMarketInfo([]string{mpn}, []string{manufacturer})
+func (oc *OctopartClient) GetMarketInfo(manufacturer, mpn string) (map[string]interface{}, error) {
+ info, err := oc.GetMarketInfoList([]string{manufacturer}, []string{mpn})
if err != nil {
return nil, err
}
- // reduce marketInfo to pricing
- return marketInfo[0], nil
+ return info[0].(map[string]interface{}), nil
+}
+
+func (oc *OctopartClient) GetExtraInfo(manufacturer, mpn string) (map[string]string, error) {
+ marketInfo, err := oc.GetMarketInfo(manufacturer, mpn)
+ if err != nil {
+ return nil, err
+ }
+ // extract market price, total avail, and "availability factor" from
+ // market info
+ log.Println(marketInfo)
+ ret := make(map[string]string)
+ ret["MarketPrice"] = marketInfo["avg_price"].(string)
+ ret["MarketFactor"] = marketInfo["market_availability"].(string)
+ ret["MarketTotalAvailable"] = marketInfo["total_avail"].(string)
+ return ret, nil
}
+func (oc *OctopartClient) AttachMarketInfo(li *LineItem) error {
+ if li.AggregateInfo == nil {
+ li.AggregateInfo = make(map[string]string)
+ }
+ extraInfo, err := oc.GetExtraInfo(li.Manufacturer, li.Mpn)
+ if err != nil {
+ log.Println(err.Error())
+ return err
+ }
+ for key := range extraInfo {
+ li.AggregateInfo[key] = string(extraInfo[key])
+ }
+ return nil
+}
+
+func (oc *OctopartClient) AttachMarketInfoBom(b *Bom) error {
+ return nil
+}
diff --git a/octopart_test.go b/octopart_test.go
index fdbd9b0..d2c8fbd 100644
--- a/octopart_test.go
+++ b/octopart_test.go
@@ -1,52 +1,63 @@
package main
import (
+ "log"
+ "os"
"testing"
- "log"
)
func TestApiCall(t *testing.T) {
- oc := NewOctopartClient("")
- result, err := oc.apiCall("parts/search", map[string]string{"q": "ne555", "limit": "2"})
- if err != nil {
- t.Errorf("Error with api call: " + err.Error())
- }
- log.Println(result["hits"])
+ oc := NewOctopartClient("")
+ result, err := oc.apiCall("parts/search", map[string]string{"q": "ne555", "limit": "2"})
+ if err != nil {
+ t.Errorf("Error with api call: " + err.Error())
+ }
+ log.Println(result["hits"])
}
-func TestGetMarketInfo(t *testing.T) {
- oc := NewOctopartClient("")
- log.Println("Running the first time...")
- result, err := oc.GetMarketInfo([]string{"ti", "atmel", "atmel"}, []string{"ne555", "attiny*", "avrtiny123qqq?"})
- if err != nil {
- t.Errorf("Error with api call: " + err.Error())
- }
- for i, r := range result {
- if r == nil {
- log.Printf("\t%d: %s", i, "nil")
- } else {
- log.Printf("\t%d: %s", i, r.(map[string]interface{})["detail_url"])
- }
- }
- log.Println("Running a second time, results should be cached...")
- result, err = oc.GetMarketInfo([]string{"ti", "atmel", "atmel"}, []string{"ne555", "attiny*", "avrtiny123qqq?"})
- if err != nil {
- t.Errorf("Error with api call: " + err.Error())
- }
- for i, r := range result {
- if r == nil {
- log.Printf("\t%d: %s", i, "nil")
- } else {
- log.Printf("\t%d: %s", i, r.(map[string]interface{})["detail_url"])
- }
+func TestGetMarketInfoList(t *testing.T) {
+ oc := NewOctopartClient("")
+ log.Println("Running the first time...")
+ result, err := oc.GetMarketInfoList([]string{"ti", "atmel", "atmel"}, []string{"ne555", "attiny*", "avrtiny123qqq?"})
+ if err != nil {
+ t.Errorf("Error with api call: " + err.Error())
+ }
+ for i, r := range result {
+ if r == nil {
+ log.Printf("\t%d: %s", i, "nil")
+ } else {
+ log.Printf("\t%d: %s", i, r.(map[string]interface{})["detail_url"])
+ }
+ }
+ log.Println("Running a second time, results should be cached...")
+ result, err = oc.GetMarketInfoList([]string{"ti", "atmel", "atmel"}, []string{"ne555", "attiny*", "avrtiny123qqq?"})
+ if err != nil {
+ t.Errorf("Error with api call: " + err.Error())
+ }
+ for i, r := range result {
+ if r == nil {
+ log.Printf("\t%d: %s", i, "nil")
+ } else {
+ log.Printf("\t%d: %s", i, r.(map[string]interface{})["detail_url"])
+ }
+ }
+ log.Println("Running in single mode, result should be cached...")
+ result_single, err := oc.GetMarketInfo("ti", "ne555")
+ if err != nil {
+ t.Errorf("Error with api call: " + err.Error())
+ }
+ if result_single == nil {
+ log.Printf("\t%d: %s", "nil")
+ } else {
+ log.Printf("\t%d: %s", result_single["detail_url"])
}
}
func TestAttachInfo(t *testing.T) {
- _, b := makeTestBom()
- bm := &BomMeta{}
- oc := NewOctopartClient("")
- oc.AttachMarketInfo(oc)
- DumpBomAsText(bm, b, os.Stdout)
+ _, b := makeTestBom()
+ bm := &BomMeta{}
+ oc := NewOctopartClient("")
+ oc.AttachMarketInfoBom(b)
+ t.Errorf("unimplemented")
+ DumpBomAsText(bm, b, os.Stdout)
}
-
diff --git a/serve.go b/serve.go
index d47a60e..e6eaca7 100644
--- a/serve.go
+++ b/serve.go
@@ -1,14 +1,14 @@
package main
import (
+ "code.google.com/p/gorilla/sessions"
"fmt"
"html/template"
"log"
"net/http"
+ "path/filepath"
"regexp"
- "path/filepath"
- "time"
- "code.google.com/p/gorilla/sessions"
+ "time"
)
var (
@@ -57,10 +57,10 @@ func baseHandler(w http.ResponseWriter, r *http.Request) {
}
func homeController(w http.ResponseWriter, r *http.Request) (err error) {
- session, _ := store.Get(r, "bommom")
+ session, _ := store.Get(r, "bommom")
context := make(map[string]interface{})
context["Session"] = session.Values
- log.Printf("%s\n", session.Values["UserName"])
+ log.Printf("%s\n", session.Values["UserName"])
context["BomList"], err = bomstore.ListBoms("")
if err != nil {
return
@@ -70,49 +70,49 @@ func homeController(w http.ResponseWriter, r *http.Request) (err error) {
}
func loginController(w http.ResponseWriter, r *http.Request) (err error) {
- session, _ := store.Get(r, "bommom")
- context := make(map[string]interface{})
- context["ActionLogin"] = true
- context["Session"] = session.Values
- if r.Method == "POST" {
- if isShortName(r.FormValue("UserName")) != true {
- context["Problem"] = "Ugh, need to use a SHORTNAME!"
- err = tmplAccount.Execute(w, context)
- return
- }
- audience := "http://localhost:7070"
- vResponse := VerifyPersonaAssertion(r.FormValue("assertion"), audience)
- if vResponse.Okay() {
- session.Values["UserName"] = r.FormValue("UserName")
- session.Values["Email"] = vResponse.Email
- session.Save(r, w)
- context["Session"] = session.Values
- http.Redirect(w, r, "/", 302)
- return
- } else {
- context["Problem"] = vResponse.Reason
- err = tmplAccount.Execute(w, context)
- return
- }
- }
+ session, _ := store.Get(r, "bommom")
+ context := make(map[string]interface{})
+ context["ActionLogin"] = true
+ context["Session"] = session.Values
+ if r.Method == "POST" {
+ if isShortName(r.FormValue("UserName")) != true {
+ context["Problem"] = "Ugh, need to use a SHORTNAME!"
+ err = tmplAccount.Execute(w, context)
+ return
+ }
+ audience := "http://localhost:7070"
+ vResponse := VerifyPersonaAssertion(r.FormValue("assertion"), audience)
+ if vResponse.Okay() {
+ session.Values["UserName"] = r.FormValue("UserName")
+ session.Values["Email"] = vResponse.Email
+ session.Save(r, w)
+ context["Session"] = session.Values
+ http.Redirect(w, r, "/", 302)
+ return
+ } else {
+ context["Problem"] = vResponse.Reason
+ err = tmplAccount.Execute(w, context)
+ return
+ }
+ }
err = tmplAccount.Execute(w, context)
return
}
func logoutController(w http.ResponseWriter, r *http.Request) (err error) {
- session, _ := store.Get(r, "bommom")
- context := make(map[string]interface{})
- delete(session.Values, "UserName")
- delete(session.Values, "Email")
- session.Save(r, w)
- context["Session"] = session.Values
- context["ActionLogout"] = true
+ session, _ := store.Get(r, "bommom")
+ context := make(map[string]interface{})
+ delete(session.Values, "UserName")
+ delete(session.Values, "Email")
+ session.Save(r, w)
+ context["Session"] = session.Values
+ context["ActionLogout"] = true
err = tmplAccount.Execute(w, context)
return
}
func userController(w http.ResponseWriter, r *http.Request, user, extra string) (err error) {
- session, _ := store.Get(r, "bommom")
+ session, _ := store.Get(r, "bommom")
if !isShortName(user) {
http.Error(w, "invalid username: "+user, 400)
return
@@ -124,9 +124,9 @@ func userController(w http.ResponseWriter, r *http.Request, user, extra string)
}
context := make(map[string]interface{})
context["BomList"], err = bomstore.ListBoms(ShortName(user))
- if user == "common" {
- context["IsCommon"] = true
- }
+ if user == "common" {
+ context["IsCommon"] = true
+ }
context["UserName"] = user
context["Session"] = session.Values
if err != nil {
@@ -137,7 +137,7 @@ func userController(w http.ResponseWriter, r *http.Request, user, extra string)
}
func bomController(w http.ResponseWriter, r *http.Request, user, name string) (err error) {
- session, _ := store.Get(r, "bommom")
+ session, _ := store.Get(r, "bommom")
if !isShortName(user) {
http.Error(w, "invalid username: "+user, 400)
return
@@ -150,7 +150,7 @@ func bomController(w http.ResponseWriter, r *http.Request, user, name string) (e
context["BomMeta"], context["Bom"], err = bomstore.GetHead(ShortName(user), ShortName(name))
context["Session"] = session.Values
if err != nil {
- http.Error(w, "404 couldn't open bom: " + user + "/" + name, 404)
+ http.Error(w, "404 couldn't open bom: "+user+"/"+name, 404)
return nil
}
err = tmplBomView.Execute(w, context)
@@ -158,7 +158,7 @@ func bomController(w http.ResponseWriter, r *http.Request, user, name string) (e
}
func bomUploadController(w http.ResponseWriter, r *http.Request, user, name string) (err error) {
- session, _ := store.Get(r, "bommom")
+ session, _ := store.Get(r, "bommom")
if !isShortName(user) {
http.Error(w, "invalid username: "+user, 400)
@@ -170,94 +170,93 @@ func bomUploadController(w http.ResponseWriter, r *http.Request, user, name stri
}
context := make(map[string]interface{})
context["Session"] = session.Values
- context["user"] = ShortName(user)
- context["name"] = ShortName(name)
+ context["user"] = ShortName(user)
+ context["name"] = ShortName(name)
context["BomMeta"], context["Bom"], err = bomstore.GetHead(ShortName(user), ShortName(name))
- switch r.Method {
+ switch r.Method {
case "POST":
- err := r.ParseMultipartForm(1024*1024*2)
- if err != nil {
- log.Println(err)
- http.Error(w, err.Error(), 400)
- return nil
- }
- file, fileheader, err := r.FormFile("bomfile")
- if err != nil {
- log.Println(err)
- context["error"] = "bomfile was nil!"
- err = tmplBomUpload.Execute(w, context)
- return err
- }
- if file == nil {
- log.Println("bomfile was nil")
- context["error"] = "bomfile was nil!"
- err = tmplBomUpload.Execute(w, context)
- return err
- }
- versionStr := r.FormValue("version")
- if len(versionStr) == 0 || isShortName(versionStr) == false {
- context["error"] = "Version must be specified and a ShortName!"
- context["version"] = versionStr
- err = tmplBomUpload.Execute(w, context)
- return err
- }
+ err := r.ParseMultipartForm(1024 * 1024 * 2)
+ if err != nil {
+ log.Println(err)
+ http.Error(w, err.Error(), 400)
+ return nil
+ }
+ file, fileheader, err := r.FormFile("bomfile")
+ if err != nil {
+ log.Println(err)
+ context["error"] = "bomfile was nil!"
+ err = tmplBomUpload.Execute(w, context)
+ return err
+ }
+ if file == nil {
+ log.Println("bomfile was nil")
+ context["error"] = "bomfile was nil!"
+ err = tmplBomUpload.Execute(w, context)
+ return err
+ }
+ versionStr := r.FormValue("version")
+ if len(versionStr) == 0 || isShortName(versionStr) == false {
+ context["error"] = "Version must be specified and a ShortName!"
+ context["version"] = versionStr
+ err = tmplBomUpload.Execute(w, context)
+ return err
+ }
- //contentType := fileheader.Header["Content-Type"][0]
- var b *Bom
- var bm *BomMeta
+ //contentType := fileheader.Header["Content-Type"][0]
+ var b *Bom
+ var bm *BomMeta
- switch filepath.Ext(fileheader.Filename) {
- case ".json":
- bm, b, err = LoadBomFromJSON(file)
- if err != nil {
- context["error"] = "Problem loading JSON file"
- err = tmplBomUpload.Execute(w, context)
- return err
- }
- case ".csv":
- b, err = LoadBomFromCSV(file)
- bm = &BomMeta{}
- if err != nil {
- context["error"] = "Problem loading CSV file: " + err.Error()
- err = tmplBomUpload.Execute(w, context)
- return err
- }
- case ".xml":
- bm, b, err = LoadBomFromXML(file)
- if err != nil {
- context["error"] = "Problem loading XML file"
- err = tmplBomUpload.Execute(w, context)
- return err
- }
- default:
- context["error"] = "Unknown file type: " + string(fileheader.Filename)
- log.Fatal(context["error"])
- err = tmplBomUpload.Execute(w, context)
- return err
- }
- bm.Owner = user
- bm.Name = name
- b.Progeny = "File uploaded from " + fileheader.Filename
- b.Created = time.Now()
- b.Version = string(versionStr)
- if err := bomstore.Persist(bm, b, ShortName(versionStr)); err != nil {
- context["error"] = "Problem saving to datastore: " + err.Error()
- err = tmplBomUpload.Execute(w, context)
- }
- http.Redirect(w, r, "//" + user + "/" + name + "/", 302)
- return err
+ switch filepath.Ext(fileheader.Filename) {
+ case ".json":
+ bm, b, err = LoadBomFromJSON(file)
+ if err != nil {
+ context["error"] = "Problem loading JSON file"
+ err = tmplBomUpload.Execute(w, context)
+ return err
+ }
+ case ".csv":
+ b, err = LoadBomFromCSV(file)
+ bm = &BomMeta{}
+ if err != nil {
+ context["error"] = "Problem loading CSV file: " + err.Error()
+ err = tmplBomUpload.Execute(w, context)
+ return err
+ }
+ case ".xml":
+ bm, b, err = LoadBomFromXML(file)
+ if err != nil {
+ context["error"] = "Problem loading XML file"
+ err = tmplBomUpload.Execute(w, context)
+ return err
+ }
+ default:
+ context["error"] = "Unknown file type: " + string(fileheader.Filename)
+ log.Fatal(context["error"])
+ err = tmplBomUpload.Execute(w, context)
+ return err
+ }
+ bm.Owner = user
+ bm.Name = name
+ b.Progeny = "File uploaded from " + fileheader.Filename
+ b.Created = time.Now()
+ b.Version = string(versionStr)
+ if err := bomstore.Persist(bm, b, ShortName(versionStr)); err != nil {
+ context["error"] = "Problem saving to datastore: " + err.Error()
+ err = tmplBomUpload.Execute(w, context)
+ }
+ http.Redirect(w, r, "//"+user+"/"+name+"/", 302)
+ return err
case "GET":
- err = tmplBomUpload.Execute(w, context)
- return err
- default:
- http.Error(w, "bad method", 405)
- return nil
- }
+ err = tmplBomUpload.Execute(w, context)
+ return err
+ default:
+ http.Error(w, "bad method", 405)
+ return nil
+ }
return
}
-
func serveCmd() {
var err error