|
| 1 | +package main |
| 2 | + |
| 3 | +import ( |
| 4 | + "bytes" |
| 5 | + "fmt" |
| 6 | + "io/ioutil" |
| 7 | + "math/rand" |
| 8 | + "net/http" |
| 9 | + "os" |
| 10 | + "os/exec" |
| 11 | + "path/filepath" |
| 12 | + "strings" |
| 13 | + "time" |
| 14 | + |
| 15 | + "github.com/labstack/gommon/color" |
| 16 | + "github.com/savaki/jq" |
| 17 | + filetype "gopkg.in/h2non/filetype.v1" |
| 18 | +) |
| 19 | + |
| 20 | +var replaceSpace = strings.NewReplacer(" ", "_") |
| 21 | +var replaceComma = strings.NewReplacer(",", "") |
| 22 | + |
| 23 | +const charset = "abcdefghijklmnopqrstuvwxyz" + |
| 24 | + "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" |
| 25 | + |
| 26 | +var seededRand = rand.New(rand.NewSource(time.Now().UnixNano())) |
| 27 | + |
| 28 | +func randString(length int, charset string) string { |
| 29 | + b := make([]byte, length) |
| 30 | + for i := range b { |
| 31 | + b[i] = charset[seededRand.Intn(len(charset))] |
| 32 | + } |
| 33 | + return string(b) |
| 34 | +} |
| 35 | + |
| 36 | +func renameFile(path string, name string, response string) { |
| 37 | + originalName := filepath.Base(path) |
| 38 | + absPath, _ := filepath.Abs(path) |
| 39 | + dirPath := filepath.Dir(absPath) |
| 40 | + newName := response + "_" + originalName |
| 41 | + if len(path) > 100 { |
| 42 | + extension := path[len(path)-4:] |
| 43 | + newName = response + "_" + randString(11, charset) + extension |
| 44 | + } |
| 45 | + err := os.Rename(path, dirPath+"/"+newName) |
| 46 | + |
| 47 | + if err != nil { |
| 48 | + fmt.Println(err) |
| 49 | + stopDeepDetect(name) |
| 50 | + return |
| 51 | + } |
| 52 | +} |
| 53 | + |
| 54 | +func parseResponse(rawResponse []byte) string { |
| 55 | + op, _ := jq.Parse(".body.predictions.[0].classes.[0].cat") |
| 56 | + value, _ := op.Apply(rawResponse) |
| 57 | + class := strings.Split(string(value), " ") |
| 58 | + class = class[1:len(class)] |
| 59 | + result := strings.Join(class, " ") |
| 60 | + result = replaceSpace.Replace(result) |
| 61 | + result = replaceComma.Replace(result) |
| 62 | + result = result[:len(result)-1] |
| 63 | + return (result) |
| 64 | +} |
| 65 | + |
| 66 | +func getClass(path string, name string) { |
| 67 | + url := "http://localhost:8080/predict" |
| 68 | + var jsonStr = []byte(`{"service":"imageserv","parameters":{"input":{"width":224,"height":224},"output":{"best":1},"mllib":{"gpu":false}},"data":["` + "/" + path + `"]}`) |
| 69 | + // DEBUG |
| 70 | + //fmt.Println("Request: " + string(jsonStr)) |
| 71 | + req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonStr)) |
| 72 | + req.Close = true |
| 73 | + client := &http.Client{} |
| 74 | + resp, err := client.Do(req) |
| 75 | + if err != nil { |
| 76 | + stopDeepDetect(name) |
| 77 | + panic(err) |
| 78 | + } |
| 79 | + defer resp.Body.Close() |
| 80 | + |
| 81 | + body, _ := ioutil.ReadAll(resp.Body) |
| 82 | + parsedResponse := parseResponse(body) |
| 83 | + color.Println(color.Yellow("[") + color.Cyan(path) + color.Yellow("]") + color.Yellow(" Response: ") + color.Green(parsedResponse)) |
| 84 | + renameFile(path, name, parsedResponse) |
| 85 | +} |
| 86 | + |
| 87 | +func runRecursively(name string) ([]string, error) { |
| 88 | + searchDir := "Images" |
| 89 | + |
| 90 | + fileList := make([]string, 0) |
| 91 | + e := filepath.Walk(searchDir, func(path string, f os.FileInfo, err error) error { |
| 92 | + fileList = append(fileList, path) |
| 93 | + return err |
| 94 | + }) |
| 95 | + |
| 96 | + if e != nil { |
| 97 | + stopDeepDetect(name) |
| 98 | + panic(e) |
| 99 | + } |
| 100 | + |
| 101 | + for _, file := range fileList { |
| 102 | + buf, _ := ioutil.ReadFile(file) |
| 103 | + if filetype.IsImage(buf) { |
| 104 | + getClass(file, name) |
| 105 | + } |
| 106 | + } |
| 107 | + |
| 108 | + return fileList, nil |
| 109 | +} |
| 110 | + |
| 111 | +func startDeepDetect(path string) string { |
| 112 | + // Starting the DeepDetect docker image |
| 113 | + name := randString(11, charset) |
| 114 | + path, _ = filepath.Abs(path) |
| 115 | + cmd := "docker" |
| 116 | + args := []string{"run", "-d", "-p", "8080:8080", "-v", path + ":/Images", "--name", name, "beniz/deepdetect_cpu"} |
| 117 | + if err := exec.Command(cmd, args...).Run(); err != nil { |
| 118 | + fmt.Fprintln(os.Stderr, err) |
| 119 | + os.Exit(1) |
| 120 | + } |
| 121 | + color.Println(color.Yellow("[") + color.Cyan("CONTAINER: "+name) + color.Yellow("] ") + color.Green("Successfully started DeepDetect. ")) |
| 122 | + // Starting the image classification service |
| 123 | + time.Sleep(time.Second) |
| 124 | + url := "http://localhost:8080/services/imageserv" |
| 125 | + var jsonStr = []byte(`{"mllib":"caffe","description":"image classification service","type":"supervised","parameters":{"input":{"connector":"image"},"mllib":{"nclasses":1000}},"model":{"repository":"/opt/models/ggnet/"}}`) |
| 126 | + req, err := http.NewRequest("PUT", url, bytes.NewBuffer(jsonStr)) |
| 127 | + client := &http.Client{} |
| 128 | + resp, err := client.Do(req) |
| 129 | + if err != nil { |
| 130 | + panic(err) |
| 131 | + } |
| 132 | + defer resp.Body.Close() |
| 133 | + if resp.Status != "201 Created" { |
| 134 | + stopDeepDetect(name) |
| 135 | + os.Exit(1) |
| 136 | + } |
| 137 | + color.Println(color.Yellow("[") + color.Cyan("CONTAINER: "+name) + color.Yellow("] ") + color.Green("Successfully started the image classification service. ")) |
| 138 | + return name |
| 139 | +} |
| 140 | + |
| 141 | +func stopDeepDetect(name string) { |
| 142 | + // Stopping the DeepDetect docker image |
| 143 | + cmd := "docker" |
| 144 | + args := []string{"stop", name} |
| 145 | + if err := exec.Command(cmd, args...).Run(); err != nil { |
| 146 | + fmt.Fprintln(os.Stderr, err) |
| 147 | + os.Exit(1) |
| 148 | + } |
| 149 | +} |
| 150 | + |
| 151 | +func main() { |
| 152 | + start := time.Now() |
| 153 | + name := startDeepDetect(os.Args[1]) |
| 154 | + color.Println(color.Yellow("[") + color.Cyan("CONTAINER: "+name) + color.Yellow("] ") + color.Yellow("Starting image classification.. ")) |
| 155 | + runRecursively(name) |
| 156 | + stopDeepDetect(name) |
| 157 | + color.Println(color.Yellow("[") + color.Cyan("CONTAINER: "+name) + color.Yellow("] ") + color.Green("Successfully stopped DeepDetect. ")) |
| 158 | + color.Println(color.Cyan("Done in ") + color.Yellow(time.Since(start)) + color.Cyan("!")) |
| 159 | +} |
0 commit comments