ffrs-fw-dl/main.go

368 lines
7.8 KiB
Go

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()
}