2020-05-10 16:45:29 +00:00
package main
import (
"io/ioutil"
"log"
2020-05-10 23:19:55 +00:00
"net/http"
2020-05-10 16:45:29 +00:00
"os"
"path/filepath"
"regexp"
"strings"
2020-05-10 23:19:55 +00:00
"text/template"
2020-05-10 16:45:29 +00:00
"git.nils.zone/nils/prettify"
"github.com/sergi/go-diff/diffmatchpatch"
"gopkg.in/yaml.v2"
)
2020-05-10 23:19:55 +00:00
// constants
const (
//root = "/srv/fwuploads/"
root = "./images/"
)
2020-05-10 16:45:29 +00:00
// structs
2020-05-10 23:19:55 +00:00
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
}
2020-05-10 16:45:29 +00:00
type firmware struct {
2020-05-10 23:19:55 +00:00
Community string
domain string
2020-05-10 16:45:29 +00:00
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" `
}
2020-05-10 23:19:55 +00:00
type data struct {
Name string
Title string
Body string
Skills skills
}
type skills [ ] struct {
Name string
}
2020-05-10 16:45:29 +00:00
// 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
2020-05-10 23:19:55 +00:00
var firmwares [ ] firmware
2020-05-10 16:45:29 +00:00
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 {
2020-05-10 23:19:55 +00:00
prefix := getImagePrefix ( folder )
//fmt.Println(folder)
2020-05-10 16:45:29 +00:00
// 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" ) {
2020-05-10 23:19:55 +00:00
// get Firmware Data for file
2020-05-10 16:45:29 +00:00
getFirmwareData ( file . Name ( ) , prefix )
}
}
}
}
}
func getFirmwareData ( image string , prefix string ) {
// create firmware variable
var fw firmware
2020-05-10 23:19:55 +00:00
//fmt.Println(">" + prefix + "<")
2020-05-10 16:45:29 +00:00
//fmt.Println(image)
2020-05-10 23:19:55 +00:00
//fmt.Println(currentBranch, currentMethod)
2020-05-10 16:45:29 +00:00
// 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
2020-05-10 23:19:55 +00:00
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]
2020-05-10 16:45:29 +00:00
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
}
2020-05-10 23:19:55 +00:00
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 ]
}
2020-05-10 16:45:29 +00:00
// 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 )
}
2020-05-10 23:19:55 +00:00
firmwares = append ( firmwares , fw )
2020-05-10 16:45:29 +00:00
}
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
2020-05-10 23:19:55 +00:00
if folder == root {
2020-05-10 16:45:29 +00:00
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 )
2020-05-10 23:19:55 +00:00
//fmt.Printf("there are %v files in folder %v\n", len(files), folder)
var prefix string
2020-05-10 16:45:29 +00:00
for _ , file := range files {
2020-05-10 23:19:55 +00:00
// 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 )
}
2020-05-10 16:45:29 +00:00
}
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
}
2020-05-10 23:19:55 +00:00
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 )
}
2020-05-10 16:45:29 +00:00
func main ( ) {
// get all assignments from file
assign = getAssignments ( )
// start script in images folder
2020-05-10 23:19:55 +00:00
getSubdirectory ( root )
//fmt.Println(branches)
//prettify.Print(assign)
startServer ( )
2020-05-10 16:45:29 +00:00
}