diff options
-rw-r--r-- | bommom.go | 9 | ||||
-rw-r--r-- | formats.go | 9 | ||||
-rw-r--r-- | serve.go | 70 | ||||
-rw-r--r-- | templates/base.html | 2 | ||||
-rw-r--r-- | templates/bom_view.html | 37 | ||||
-rw-r--r-- | templates/home.html | 9 | ||||
-rw-r--r-- | templates/user.html | 11 |
7 files changed, 129 insertions, 18 deletions
@@ -82,6 +82,11 @@ func openBomStore() { } } +func openAuthStore() { + // defaults to dummy auth system + auth = DummyAuth(true) +} + func dumpOut(fname string, bm *BomMeta, b *Bom) { var outFile io.Writer if fname == "" { @@ -202,10 +207,8 @@ func dumpCmd() { } openBomStore() + openAuthStore() - if auth == nil { - auth = DummyAuth(true) - } bm, b, err := bomstore.GetHead(ShortName(userStr), ShortName(nameStr)) if err != nil { log.Fatal(err) @@ -86,9 +86,10 @@ func DumpBomAsCSV(b *Bom, out io.Writer) { func appendField(existing, next *string) { if *existing == "" { + *existing = strings.TrimSpace(*next) + } else { *existing += " " + strings.TrimSpace(*next) } - *existing = strings.TrimSpace(*next) } func LoadBomFromCSV(input io.Reader) (*Bom, error) { @@ -118,16 +119,16 @@ func LoadBomFromCSV(input io.Reader) (*Bom, error) { appendField(&li.Mpn, &records[i]) case "mfg", "manufacturer": appendField(&li.Manufacturer, &records[i]) - case "element", "id", "circuit element", "symbol_id", "symbol id": + case "element", "id", "circuit element", "symbol_id", "symbol id", "symbols": for _, symb := range strings.Split(records[i], ",") { symb = strings.TrimSpace(symb) if !isShortName(symb) { li.Elements = append(li.Elements, symb) } else if *verbose { - log.Println("symbol not a ShortName, skipped: " + symb) + log.Println("element id not a ShortName, skipped: " + symb) } } - case "function", "purpose", "role", "subsystem": + case "function", "purpose", "role", "subsystem", "description": appendField(&li.Function, &records[i]) case "formfactor", "form_factor", "form factor", "case/package", "package", "symbol", "footprint": appendField(&li.FormFactor, &records[i]) @@ -9,25 +9,25 @@ import ( ) var ( - tmplHome, tmplView *template.Template + tmplHome, tmplView, tmplUser, tmplBomView *template.Template ) func baseHandler(w http.ResponseWriter, r *http.Request) { var err error log.Printf("serving %s\n", r.URL.Path) - bomUrlPattern := regexp.MustCompile("^/([a-zA-Z][a-zA-Z0-9_]*)/([a-zA-Z][a-zA-Z0-9_]*)/(.*)$") + bomUrlPattern := regexp.MustCompile("^/([a-zA-Z][a-zA-Z0-9_]*)/([a-zA-Z][a-zA-Z0-9_]*)(/.*)$") userUrlPattern := regexp.MustCompile("^/([a-zA-Z][a-zA-Z0-9_]*)/$") switch { case r.URL.Path == "/": - err = tmplHome.Execute(w, nil) + err = homeController(w, r) case bomUrlPattern.MatchString(r.URL.Path): match := bomUrlPattern.FindStringSubmatch(r.URL.Path) - bomController(w, r, match[1], match[2], match[3]) + err = bomController(w, r, match[1], match[2], match[3]) case userUrlPattern.MatchString(r.URL.Path): match := userUrlPattern.FindStringSubmatch(r.URL.Path) - fmt.Fprintf(w, "will show BOM list here for user %s", match[1]) + err = userController(w, r, match[1], "") default: // 404 log.Println("warning: 404") @@ -41,20 +41,72 @@ func baseHandler(w http.ResponseWriter, r *http.Request) { } } -func bomController(w http.ResponseWriter, r *http.Request, user, name, extra string) { - fmt.Fprintf(w, "will show BOM %s/%s here?", user, name) +func homeController(w http.ResponseWriter, r *http.Request) (err error) { + context := make(map[string]interface{}) + context["BomList"], err = bomstore.ListBoms("") + if err != nil { + return + } + err = tmplHome.Execute(w, context) + return +} + +func userController(w http.ResponseWriter, r *http.Request, user, extra string) (err error) { + if !isShortName(user) { + http.Error(w, "invalid username: "+user, 400) + return + } + var email string + email, err = auth.GetEmail(user) + if err != nil { + // no such user + http.NotFound(w, r) + return + } + context := make(map[string]interface{}) + context["BomList"], err = bomstore.ListBoms(ShortName(user)) + context["Email"] = email + context["UserName"] = user + if err != nil { + return + } + err = tmplUser.Execute(w, context) + return +} + +func bomController(w http.ResponseWriter, r *http.Request, user, name, extra string) (err error) { + if !isShortName(user) { + http.Error(w, "invalid username: "+user, 400) + return + } + if !isShortName(name) { + http.Error(w, "invalid bom name: "+name, 400) + return + } + context := make(map[string]interface{}) + context["BomMeta"], context["Bom"], err = bomstore.GetHead(ShortName(user), ShortName(name)) + if err != nil { + return + } + err = tmplBomView.Execute(w, context) + return } func serveCmd() { var err error // load and parse templates - baseTmplPath := *templatePath + "/base.html" - tmplHome = template.Must(template.ParseFiles(*templatePath + "/home.html", baseTmplPath)) + baseTmplPath := *templatePath + "/base.html" + tmplHome = template.Must(template.ParseFiles(*templatePath+"/home.html", baseTmplPath)) + tmplUser = template.Must(template.ParseFiles(*templatePath+"/user.html", baseTmplPath)) + tmplBomView = template.Must(template.ParseFiles(*templatePath+"/bom_view.html", baseTmplPath)) if err != nil { log.Fatal(err) } + openBomStore() + openAuthStore() + // serve template static assets (images, CSS, JS) http.Handle("/static/", http.FileServer(http.Dir(*templatePath+"/"))) http.Handle("/favicon.ico", http.FileServer(http.Dir(*templatePath+"/static/"))) diff --git a/templates/base.html b/templates/base.html index 538d7db..c455815 100644 --- a/templates/base.html +++ b/templates/base.html @@ -1,6 +1,6 @@ {{ define "HEADER" }}<html> <head> -<title>bombom</title> +<title>bommom</title> <link rel="stylesheet" type="text/css" href="/static/default.css"></link> </head> <body>{{ end }} diff --git a/templates/bom_view.html b/templates/bom_view.html new file mode 100644 index 0000000..2606217 --- /dev/null +++ b/templates/bom_view.html @@ -0,0 +1,37 @@ +{{ template "HEADER" }} +<h1>{{ .BomMeta.Name }} is a bom.</h1> +<b>Owner: </b>{{ .BomMeta.Owner }}<br> +{{ if .BomMeta.Homepage }}<b>Homepage: </b>{{ .BomMeta.Homepage }}<br>{{ end }} +{{ if .BomMeta.Description }}<b>Description: </b>{{ .BomMeta.Description }}<br>{{ end }} +<b>Version: </b>{{ .BomMeta.HeadVersion }} (at head)<br> +<b>Created: </b>{{ .Bom.Created }}<br> +{{ if .Bom.Progeny}}<b>Source: </b>{{ .Bom.Progeny }}<br>{{ end }} +<table> +<tr> + <th>qty + <th>elements + <th>manufacturer + <th>mpn + <th>function + <th>form_factor + <th>specs + <th>category + <th>tag + <th>comment +</tr> +{{ range .Bom.LineItems }} +<tr> + <td>{{ len .Elements }} + <td>{{ range .Elements }}{{ if . }}{{ . }} {{ end }}{{ end }} + <td>{{ .Manufacturer }} + <td>{{ .Mpn }} + <td>{{ .Function }} + <td>{{ .FormFactor }} + <td>{{ .Specs }} + <td>{{ .Category }} + <td>{{ .Tag }} + <td>{{ .Comment }} +</tr> +{{ end }} +</table> +{{ template "FOOTER" }} diff --git a/templates/home.html b/templates/home.html index 1298241..1b328c3 100644 --- a/templates/home.html +++ b/templates/home.html @@ -1,3 +1,10 @@ {{ template "HEADER" }} -<h1>Home Page</h1> +<h1>this is bomom.</h1> +<ul> +{{ range .BomList }} +<li><a href="/{{ .Owner }}/">{{ .Owner }}</a>/<a href="/{{ .Owner }}/{{ .Name }}/">{{ .Name }}</a> +{{ else }} +No Boms found! +{{ end }} +</ul> {{ template "FOOTER" }} diff --git a/templates/user.html b/templates/user.html new file mode 100644 index 0000000..f5c8983 --- /dev/null +++ b/templates/user.html @@ -0,0 +1,11 @@ +{{ template "HEADER" }} +<h1>{{ .User }} is a bommom user.</h1> +<b>Email:</b> <a href="mailto:{{ .Email }}">{{ .Email }}</a> +<ul> +{{ range .BomList }} +<li><a href="/{{ .Owner }}/{{ .Name }}/">{{ .Name }}</a> +{{ else }} +No Boms found! +{{ end }} +</ul> +{{ template "FOOTER" }} |