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" }} | 
