e2e face recognition
diff --git a/photos-ui/main.go b/photos-ui/main.go
index 879ef0b..97e0126 100644
--- a/photos-ui/main.go
+++ b/photos-ui/main.go
@@ -5,27 +5,57 @@
"fmt"
"log"
"net/http"
+ "net/http/httputil"
+ "net/url"
+ "text/template"
)
-var port = flag.Int("port", 3000, "Port to listen on")
+var port = flag.Int("port", 3000, "Port to listen on.")
+var pcloudApiServer = flag.String("pcloud_api_server", "", "PCloud API Server address.")
func handle_gallery(w http.ResponseWriter, r *http.Request) {
http.ServeFile(w, r, "./gallery.html")
}
func handle_photo(w http.ResponseWriter, r *http.Request) {
- http.ServeFile(w, r, "./photo.html")
+ err := r.ParseForm()
+ if err != nil {
+ http.Error(w, "Could not read query", http.StatusInternalServerError)
+ return
+ }
+ id, ok := r.Form["id"]
+ if !ok {
+ http.Error(w, "Photo id must be provided", http.StatusBadRequest)
+ return
+ }
+ t, err := template.ParseFiles("photo.html")
+ if err != nil {
+ log.Print(err)
+ http.Error(w, "Could not process page", http.StatusInternalServerError)
+ return
+ }
+ err = t.Execute(w, struct{ Id string }{id[0]})
+ if err != nil {
+ log.Print(err)
+ http.Error(w, "Could not process page", http.StatusInternalServerError)
+ return
+ }
}
-func handle_graphql(w http.ResponseWriter, r *http.Request) {
- http.Redirect(w, r, "http://localhost:8080/graphql?query={queryImage(){id objectPath}}", http.StatusMovedPermanently)
+func newGqlProxy(pcloudApiServer string) *httputil.ReverseProxy {
+ u, err := url.Parse(pcloudApiServer)
+ if err != nil {
+ panic(err)
+ }
+ return httputil.NewSingleHostReverseProxy(u)
}
func main() {
flag.Parse()
fs := http.FileServer(http.Dir("./static"))
http.Handle("/static/", http.StripPrefix("/static/", fs))
- http.HandleFunc("/graphql", handle_graphql)
+ http.Handle("/graphql", newGqlProxy(*pcloudApiServer))
+ http.HandleFunc("/photo", handle_photo)
http.HandleFunc("/", handle_gallery)
log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", *port), nil))
}
diff --git a/photos-ui/photo.html b/photos-ui/photo.html
index 8628549..d41bb29 100644
--- a/photos-ui/photo.html
+++ b/photos-ui/photo.html
@@ -4,7 +4,8 @@
<title>Photos</title>
</head>
<script src="static/photos.js"></script>
- <body onload="initPhoto('gallery')">
- <div id="gallery" />
+ <body onload="initImg('photo', '{{ .Id }}')">
+ <img id="photo" onload="drawFaces('photo', 'faces', '{{ .Id }}')" src=""></img>
+ <canvas id="faces"></canvas>
</body>
</html>
diff --git a/photos-ui/static/photos.js b/photos-ui/static/photos.js
index ccadb4b..6f46a19 100644
--- a/photos-ui/static/photos.js
+++ b/photos-ui/static/photos.js
@@ -1,7 +1,29 @@
async function fetchAllPhotos() {
- return await fetch("/graphql?query={queryImage(){objectPath}}")
+ return await fetch("/graphql?query={queryImage(){id objectPath}}")
.then(resp => resp.json())
- .then(resp => resp.data.queryImage)
+ .then(resp => resp.queryImage)
+ .catch(error => {
+ alert(error);
+ return [];
+ });
+
+}
+
+async function fetchImage(id) {
+ return await fetch("/graphql?query={getImage(id: \"" + id + "\"){id objectPath}}")
+ .then(resp => resp.json())
+ .then(resp => resp.getImage)
+ .catch(error => {
+ alert(error);
+ return {};
+ });
+
+}
+
+async function fetchAllImageSegments(id) {
+ return await fetch("/graphql?query={getImage(id: \"" + id + "\"){segments { upperLeftX upperLeftY lowerRightX lowerRightY }}}")
+ .then(resp => resp.json())
+ .then(resp => resp.getImage.segments)
.catch(error => {
alert(error);
return [];
@@ -11,12 +33,38 @@
async function initGallery(gallery_elem_id) {
imgs = await fetchAllPhotos();
- console.log(imgs);
img_list = "<ul>";
for (img of imgs) {
- img_list += "<li><a href='/photo/" + img.id + "'><img style='max-width: 300px' src='http://localhost:9000/" + img.objectPath + "' /></a></li>";
+ img_list += "<li><a href='/photo?id=" + img.id + "'><img style='max-width: 300px' src='http://localhost:9000/" + img.objectPath + "' /></a></li>";
}
img_list += "</ul>";
- console.log(img_list);
document.getElementById(gallery_elem_id).innerHTML = img_list;
}
+
+async function initImg(img_elem_id, id) {
+ img = await fetchImage(id);
+ document.getElementById(img_elem_id).setAttribute("src", "http://localhost:9000/" + img.objectPath);
+}
+
+async function drawFaces(photo_elem_id, faces_canvas_elem_id, id){
+ console.log(id);
+ faces = await fetchAllImageSegments(id);
+
+ var img = document.getElementById(photo_elem_id);
+ var cnvs = document.getElementById(faces_canvas_elem_id);
+
+ cnvs.style.position = "absolute";
+ cnvs.style.left = img.offsetLeft + "px";
+ cnvs.style.top = img.offsetTop + "px";
+ cnvs.width = img.width;
+ cnvs.height = img.height;
+
+ var ctx = cnvs.getContext("2d");
+ for (f of faces) {
+ ctx.beginPath();
+ ctx.lineWidth = 2;
+ ctx.strokeStyle = 'red';
+ ctx.rect(f.upperLeftX, f.upperLeftY, f.lowerRightX - f.upperLeftX, f.lowerRightY - f.upperLeftY);
+ ctx.stroke();
+ }
+}