package gojenkins import ( "io" "strconv" "strings" "golang.org/x/net/html" ) // Parse jenkins ajax response in order find the current jenkins build history func parseBuildHistory(d io.Reader) []*History { z := html.NewTokenizer(d) depth := 0 buildRowCellDepth := -1 builds := make([]*History, 0) var curBuild *History for { tt := z.Next() switch tt { case html.ErrorToken: if z.Err() == io.EOF { return builds } case html.SelfClosingTagToken: tn, hasAttr := z.TagName() // fmt.Println("START__", string(tn), hasAttr) if hasAttr { a := attr(z) // Failed > Console Output if string(tn) == "img" { if hasCSSClass(a, "icon-sm") && buildRowCellDepth > -1 { if alt, found := a["alt"]; found { curBuild.BuildStatus = strings.Fields(alt)[0] } } } } case html.StartTagToken: depth++ tn, hasAttr := z.TagName() // fmt.Println("START__", string(tn), hasAttr) if hasAttr { a := attr(z) // if string(tn) == "td" { if hasCSSClass(a, "build-row-cell") { buildRowCellDepth = depth curBuild = &History{} builds = append(builds, curBuild) } } // #227 if string(tn) == "a" { if hasCSSClass(a, "build-link") && buildRowCellDepth > -1 { if href, found := a["href"]; found { parts := strings.Split(href, "/") if num, err := strconv.Atoi(parts[len(parts)-2]); err == nil { curBuild.BuildNumber = num } } } } //
...
if string(tn) == "div" { if hasCSSClass(a, "build-details") && buildRowCellDepth > -1 { if t, found := a["time"]; found { if msec, err := strconv.ParseInt(t, 10, 0); err == nil { curBuild.BuildTimestamp = msec / 1000 } } } } } case html.EndTagToken: tn, _ := z.TagName() if string(tn) == "td" && depth == buildRowCellDepth { buildRowCellDepth = -1 curBuild = nil } depth-- } } } func attr(z *html.Tokenizer) map[string]string { a := make(map[string]string) for { k, v, more := z.TagAttr() if k != nil && v != nil { a[string(k)] = string(v) } if !more { break } } return a } func hasCSSClass(a map[string]string, className string) bool { if classes, found := a["class"]; found { for _, class := range strings.Fields(classes) { if class == className { return true } } } return false }