github.com/pmoroney/dnscontrol@v0.2.4-0.20171024134423-fad98f73f44a/docs/flattener/js.go (about) 1 // +build js 2 3 package main 4 5 import ( 6 "encoding/json" 7 "fmt" 8 "net/http" 9 "strings" 10 11 "github.com/StackExchange/dnscontrol/pkg/spflib" 12 "github.com/gopherjs/jquery" 13 ) 14 15 type gResolver struct{} 16 17 type gResp struct { 18 Status int 19 Answer []struct { 20 Data string `json:"data"` 21 } 22 } 23 24 func (g gResolver) GetTxt(fqdn string) ([]string, error) { 25 resp, err := http.Get("https://dns.google.com/resolve?type=txt&name=" + fqdn) 26 if err != nil { 27 return nil, err 28 } 29 30 defer resp.Body.Close() 31 dec := json.NewDecoder(resp.Body) 32 dat := &gResp{} 33 if err = dec.Decode(dat); err != nil { 34 return nil, err 35 } 36 list := []string{} 37 for _, a := range dat.Answer { 38 list = append(list, strings.Trim(a.Data, "\"")) 39 } 40 return list, nil 41 } 42 43 var jq = jquery.NewJQuery 44 var parsed *spflib.SPFRecord 45 var domain string 46 47 func main() { 48 jq(func() { 49 jq("#lookup_btn").On(jquery.CLICK, func(e jquery.Event) { 50 go func() { 51 domain = jq("#domain").Val() 52 rec, err := spflib.Lookup(domain, gResolver{}) 53 if err != nil { 54 panic(err) 55 } 56 parsed, err = spflib.Parse(rec, gResolver{}) 57 if err != nil { 58 // todo: show a better error 59 panic(err) 60 } 61 jq("#results").SetHtml(buildHTML(parsed, domain)) 62 jq(".cb").On(jquery.CHANGE, func(e jquery.Event) { 63 updateDisabledChecks() 64 renderResults() 65 }) 66 updateDisabledChecks() 67 renderResults() 68 }() 69 }) 70 }) 71 } 72 73 func updateDisabledChecks() { 74 jq("input:checkbox").Each(func(i int, el interface{}) { 75 fmt.Println(jq(el).Prop("disabled")) 76 jq(el).SetProp("disabled", false) 77 }) 78 jq("input:checkbox:not(:checked)").Each(func(i int, el interface{}) { 79 fmt.Println(jq(el).Attr("id")) 80 jq(el).Next().Next().Find("input:checkbox").Each(func(i int, el interface{}) { 81 fmt.Println("^^", jq(el).Attr("id")) 82 jq(el).SetProp("disabled", true) 83 }) 84 }) 85 } 86 87 func renderResults() { 88 content := "" 89 addFlattened := func(mode string, filter string) { 90 flat := parsed.Flatten(filter) 91 lookups := 0 92 if filter != "*" { 93 lookups = parsed.Lookups() - len(strings.Split(filter, ",")) 94 } 95 content += fmt.Sprintf(` 96 <h3> %s flattened (length %d, %d lookups)</h3><code>%s</code> 97 `, mode, len(flat.TXT()), lookups, flat.TXT()) 98 split := flat.TXTSplit("_spf%d." + domain) 99 if len(split) > 1 { 100 lookups += len(split) - 1 101 content += fmt.Sprintf("<h3>%s flattened split (%d lookups)</h3>", mode, lookups) 102 for k, v := range split { 103 content += fmt.Sprintf("<h4>%s</h4><code>%s</code>", k, v) 104 } 105 } 106 } 107 addFlattened("Fully", "*") 108 109 // look for selected divs 110 filters := []string{} 111 jq("input:checked").Each(func(i int, el interface{}) { 112 filters = append(filters, jq(el).Attr("id")) 113 }) 114 if len(filters) > 0 { 115 addFlattened("Selectively", strings.Join(filters, ",")) 116 } 117 118 jq("#flattened").SetHtml(content) 119 } 120 121 func buildHTML(rec *spflib.SPFRecord, domain string) string { 122 h := "<h1>" + domain + "</h1>" 123 h += fmt.Sprintf("<h2>%d lookups</h2>", rec.Lookups()) 124 return h + genRoot(rec) 125 } 126 127 // html based on https://codepen.io/khoama/pen/hpljA 128 func genRoot(rec *spflib.SPFRecord) string { 129 h := fmt.Sprintf(` 130 <ul> 131 <li class='root'>%s</li> 132 `, rec.TXT()) 133 for _, p := range rec.Parts { 134 h += genPart(p) 135 } 136 h += "</ul>" 137 return h 138 } 139 140 func genPart(rec *spflib.SPFPart) string { 141 if !rec.IsLookup { 142 return fmt.Sprintf(`<li>%s</li>`, rec.Text) 143 } 144 h := fmt.Sprintf(`<li> 145 <input type="checkbox" class='cb' id="%s" name="%s" /> 146 <label for="%s">%s(%d lookups)</label>`, rec.IncludeDomain, rec.IncludeDomain, rec.IncludeDomain, rec.Text, rec.IncludeRecord.Lookups()+1) 147 h += fmt.Sprintf("<ul>") 148 for _, p := range rec.IncludeRecord.Parts { 149 h += genPart(p) 150 } 151 h += "</ul>" 152 h += "</li>" 153 return h 154 }