Last active
October 25, 2017 19:32
-
-
Save peterhellberg/8d9906e4e2ebc72b5199cb3e9a10aa18 to your computer and use it in GitHub Desktop.
Tagbox combined with imagesnap using Go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"bufio" | |
"bytes" | |
"context" | |
"encoding/json" | |
"flag" | |
"fmt" | |
"io" | |
"log" | |
"net/http" | |
"net/url" | |
"os" | |
"os/exec" | |
"time" | |
"github.com/machinebox/sdk-go/tagbox" | |
) | |
var ( | |
images = map[string][]byte{} | |
imageURL *url.URL | |
tbox *tagbox.Client | |
) | |
func main() { | |
var ip, port, tb string | |
flag.StringVar(&ip, "ip", "10.0.0.86", "") | |
flag.StringVar(&port, "port", "8081", "") | |
flag.StringVar(&tb, "tb", "http://localhost:8080", "Tagbox URL") | |
flag.Parse() | |
imageURL = &url.URL{Scheme: "http", Host: ip + ":" + port, Path: "/image"} | |
http.HandleFunc("/image", image) | |
http.HandleFunc("/", index) | |
tbox = tagbox.New(tb) | |
fmt.Fprintf(os.Stderr, "Listening on http://0.0.0.0:%s\n", port) | |
http.ListenAndServe(":"+port, nil) | |
} | |
func snap(ctx context.Context, w io.Writer) error { | |
cmd := exec.CommandContext(ctx, "imagesnap", "-w", "1", "-") | |
cmd.Stdout = w | |
return cmd.Run() | |
} | |
func image(w http.ResponseWriter, r *http.Request) { | |
at := requestAt(r, time.Now().UTC()) | |
if b, found := images[at]; found { | |
w.Write(b) | |
return | |
} | |
var buf bytes.Buffer | |
bw := bufio.NewWriter(&buf) | |
if err := snap(r.Context(), bw); err != nil { | |
log.Println("[ERROR] capturing webcam", err) | |
return | |
} | |
bw.Flush() | |
b := buf.Bytes() | |
images[at] = b | |
w.Write(b) | |
} | |
func index(w http.ResponseWriter, r *http.Request) { | |
timestamp := time.Now().UTC() | |
meta := Meta{"timestamp": timestamp} | |
u := imageURL | |
u.RawQuery = "at=" + requestAt(r, timestamp) | |
fmt.Fprintf(os.Stderr, "Checking %s\n", u.String()) | |
tags, err := tbox.CheckURL(u) | |
if err != nil { | |
log.Println("[ERROR]", err) | |
writeJSON(w, errorResponse(err, 500, meta), 500) | |
return | |
} | |
resp := Response{ | |
Meta: meta, | |
Data: Data{ | |
"image": u.String(), | |
"tags": tags, | |
}, | |
} | |
go func() { | |
for _, tag := range tags { | |
if tag.Confidence > 0.3 { | |
exec.Command("say", tag.Tag, "-v", "Samantha", "-r", "160").Run() | |
break | |
} | |
} | |
}() | |
json.NewEncoder(os.Stdout).Encode(resp) | |
writeJSON(w, resp) | |
} | |
func requestAt(r *http.Request, t time.Time) string { | |
if at := r.URL.Query().Get("at"); at != "" { | |
return at | |
} | |
return fmt.Sprintf("%d", t.Nanosecond()) | |
} | |
func writeJSON(w http.ResponseWriter, v interface{}, statuses ...int) { | |
w.Header().Set("Content-Type", "application/json; charset=utf-8") | |
w.Header().Add("Vary", "Accept-Encoding") | |
if len(statuses) > 0 { | |
w.WriteHeader(statuses[0]) | |
} | |
enc := json.NewEncoder(w) | |
enc.SetIndent("", " ") | |
enc.Encode(v) | |
} | |
type Response struct { | |
Meta Meta `json:"meta,omitempty"` | |
Data Data `json:"data,omitempty"` | |
Errors []Error `json:"errors,omitempty"` | |
} | |
func errorResponse(err error, status int, meta Meta) Response { | |
return Response{ | |
Meta: meta, | |
Errors: []Error{ | |
{ | |
Status: status, | |
Title: http.StatusText(status), | |
Detail: err.Error(), | |
}, | |
}, | |
} | |
} | |
// Meta is a meta object that contains non-standard meta-information. | |
type Meta map[string]interface{} | |
// Data is the primary data of the Response | |
type Data map[string]interface{} | |
// Error objects provide additional information about problems encountered while performing an operation. | |
type Error struct { | |
Status int `json:"status"` | |
Title string `json:"title"` | |
Detail string `json:"detail,omitempty"` | |
} |
Author
peterhellberg
commented
Sep 1, 2017
{
"meta": {
"timestamp": "2017-09-01T18:06:32.109913137Z"
},
"data": {
"image": "http://10.0.0.86:8081/image?at=109913137",
"tags": [
{
"Tag": "coffee_mug",
"Confidence": 0.7345199584960938
},
{
"Tag": "cup",
"Confidence": 0.1498795747756958
},
{
"Tag": "toilet_tissue",
"Confidence": 0.027606995776295662
},
{
"Tag": "cowboy_hat",
"Confidence": 0.023174552246928215
},
{
"Tag": "sombrero",
"Confidence": 0.018557647243142128
}
]
}
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment