package main import ( "io/ioutil" "log" "net/http" "os" "path/filepath" "regexp" "strings" "text/template" "git.nils.zone/nils/prettify" "github.com/sergi/go-diff/diffmatchpatch" "gopkg.in/yaml.v2" ) // constants const ( //root = "/srv/fwuploads/" root = "./images/" ) // structs type branch struct { Name string } type method struct { Name string branch []branch } type version struct { Name string method []method } type model struct { Name string Version []version } type vendor struct { Name string Models []model } type firmware struct { Community string domain string Hersteller string Modell string Version string Erstinstallation string Entwicklungsstadium string } type image struct { Name string `json:"name"` Prettyname string `json:"prettyname"` } type city struct { Name string `json:"name"` Images []image `json:"images"` } type manufacturer struct { Name string `json:"name"` Prettyname string `json:"prettyname"` } type assignments struct { Cities []city `json:"cities"` Manufacturers []manufacturer `json:"manufacturers"` } type data struct { Name string Title string Body string Skills skills } type skills []struct { Name string } // global variables var branches = []string{"stable", "beta", "experimental"} var installMethod = []string{"sysupgrade", "factory"} var community string var domains []string var assign assignments var currentBranch string // holds info of the current branch var currentMethod string // holds info of the current install method var firmwares []firmware func stringInSlice(a string, list []string) bool { for _, b := range list { if b == a { return true } } return false } func getFirmwareImages(folder string) { // get all files in folder files := getFilesOrFolders(folder) // check if files exist //fmt.Println(files) if files != nil { prefix := getImagePrefix(folder) //fmt.Println(folder) // loop through all files for _, file := range files { // check if file really is a file if !file.IsDir() { // check if file starts with gluon if strings.HasPrefix(file.Name(), "gluon") { // get Firmware Data for file getFirmwareData(file.Name(), prefix) } } } } } func getFirmwareData(image string, prefix string) { // create firmware variable var fw firmware //fmt.Println(">" + prefix + "<") //fmt.Println(image) //fmt.Println(currentBranch, currentMethod) // set the branch of firmware fw.Entwicklungsstadium = currentBranch // set install method of firmware fw.Erstinstallation = currentMethod // cut away the prefix of this folder fw.Modell = strings.Split(image, prefix)[1] // cut away the extension fw.Modell = strings.TrimSuffix(fw.Modell, filepath.Ext(fw.Modell)) // this has issues with img.gz use below until we have an image with a "." in it // quickfix for .img.gz if filepath.Ext(fw.Modell) == ".img" { // remove .img as well fw.Modell = strings.TrimSuffix(fw.Modell, filepath.Ext(fw.Modell)) } // remove sysupgrade suffix if strings.HasSuffix(fw.Modell, "-sysupgrade") { fw.Modell = strings.TrimSuffix(fw.Modell, "-sysupgrade") } //fmt.Println(fw.Modell) //fw.Modell = strings.Split(fw.Modell, ".")[0] for _, manufacturer := range assign.Manufacturers { // check if image is from manufacturer if strings.HasPrefix(fw.Modell, manufacturer.Name) { // image is from manufacturer fw.Hersteller = manufacturer.Name break } } // debug output message var out bool // check if manufacturer was not found if fw.Hersteller == "" { // guess the manufacturer (word(s) before first "-") fw.Hersteller = strings.Split(fw.Modell, "-")[0] log.Printf("I had to guess the manufacturer, sorry! I think it is >%v<\nIf you think this is wrong please change assignments.yml on our git repository\n\n", fw.Hersteller) // set debug output message to true out = true } if strings.Contains(fw.Modell, "-") { // assemble new image name (cut away manufacturer) fw.Modell = strings.Split(fw.Modell, fw.Hersteller+"-")[1] } else { fw.Modell = strings.Split(fw.Modell, fw.Hersteller)[1] } // compile regex for hw revisions r, err := regexp.Compile("(v[0-9]{1,2}$)|([-]*rev-\\w*$)|(-[a-zA-Z][0-9]{0,1}$)") if err != nil { panic(err) } // find hardware revision in image name fw.Version = r.FindString(fw.Modell) if fw.Version != "" { // cut hardware version from image name fw.Modell = strings.Split(fw.Modell, fw.Version)[0] } else { fw.Version = "Alle" } // check if hardware version starts with a dash if strings.HasPrefix(fw.Version, "-") { // cut away "-" fw.Version = fw.Version[1:] } //out, err := yaml.Marshal(fw) //if err != nil { // panic(err) //} //fmt.Println(len(out)) //fmt.Println(string(out)) //fmt.Println(image) /* os.Exit(0) // compile regex for branches r, err := regexp.Compile("(stable\\b|beta\\b|experimental\\b)") if err != nil { panic(err) } branch := r.Find([]byte(image)) fmt.Println(string(branch)) os.Exit(0) */ // check if out was set and if so print out all info we have on the device if out { log.Println(image) prettify.Print(fw) } firmwares = append(firmwares, fw) } func getSubdirectory(folder string) { subFolders := getFilesOrFolders(folder) // go through all subFolder for _, f := range subFolders { // check if entry is a directory if f.IsDir() { // check if we are at root if folder == root { community = f.Name() //fmt.Println(community) } //fmt.Println(f.Name()) // check if we are a branch if stringInSlice(f.Name(), branches) { //fmt.Println(f.Name()) currentBranch = f.Name() domain := filepath.Base(folder) domains = append(domains, domain) //fmt.Println("\t" + f.Name()) } else if stringInSlice(f.Name(), installMethod) { // check if we are stable/beta/experimental currentMethod = f.Name() } // recursive call getSubdirectory(folder + "/" + f.Name()) } } // at the end of the tunnel if stringInSlice(filepath.Base(folder), installMethod) { //fmt.Println("\t\t" + filepath.Base(folder)) firmwareFolder, err := filepath.Abs(folder) if err != nil { panic(err) } //fmt.Println(firmwareFolder) getFirmwareImages(firmwareFolder) } } func getFilesOrFolders(folder string) []os.FileInfo { // get all files in folder files, err := ioutil.ReadDir(folder) if err != nil { log.Fatal(err) } if len(files) == 0 { //fmt.Println(len(files)) return nil } return files } func getImagePrefix(folder string) string { files := getFilesOrFolders(folder) //fmt.Printf("there are %v files in folder %v\n", len(files), folder) var prefix string for _, file := range files { // check if file starts with gluon if strings.HasPrefix(file.Name(), "gluon") { // set prefix as file name first if prefix == "" { prefix = file.Name() } // diff the prefix until it is correct prefix = diffStrings(file.Name(), prefix) } } return prefix } func diffStrings(text1 string, text2 string) string { dmp := diffmatchpatch.New() length := dmp.DiffCommonPrefix(text1, text2) return text1[0:length] } func getAssignments() assignments { // declare returning variable var a assignments // load assignments from file file, err := ioutil.ReadFile("assignments.yml") if err != nil { panic(err) } // unmarshal file onto assignment err = yaml.Unmarshal(file, &a) if err != nil { panic(err) } return a } func handler(w http.ResponseWriter, r *http.Request) { t, _ := template.ParseFiles("tmpl/index.html") //t.Execute(w, assign) t.Execute(w, firmwares) } func startServer() { http.HandleFunc("/", handler) http.ListenAndServe(":8080", nil) } func main() { // get all assignments from file assign = getAssignments() // start script in images folder getSubdirectory(root) //fmt.Println(branches) //prettify.Print(assign) startServer() }