6
0
Эх сурвалжийг харах

Merge branch '44-send-bounding-boxes-to-server' into 'master'

Resolve "send bounding boxes to server"

Closes #44

See merge request troebs/pycs!44
Eric Tröbs 4 жил өмнө
parent
commit
8046c73ab9

+ 21 - 3
pycs/frontend/WebServer.py

@@ -177,11 +177,29 @@ class WebServer:
             file_directory, file_name = target_object.get_file()
 
             # return data
-            print(file_directory, file_name)
-            print(path.join(file_directory, file_name))
-            print(path.exists(path.join(file_directory, file_name)))
             return send_from_directory(file_directory, file_name)
 
+        @self.__flask.route('/projects/<project_identifier>/data/<file_identifier>', methods=['POST'])
+        def add_result(project_identifier, file_identifier):
+            # abort if project id is not valid
+            if project_identifier not in app_status['projects'].keys():
+                return make_response('project does not exist', 500)
+
+            project = app_status['projects'][project_identifier]
+
+            # abort if file id is not valid
+            if file_identifier not in project['data'].keys():
+                return make_response('file does not exist', 500)
+
+            target_object = project['data'][file_identifier]
+
+            # add result
+            result = request.get_json(force=True)
+            target_object.add_result(result)
+
+            # return default success response
+            return response()
+
         # finally start web server
         host = app_status['settings']['frontend']['host']
         port = app_status['settings']['frontend']['port']

+ 5 - 0
pycs/projects/MediaFile.py

@@ -1,4 +1,5 @@
 from os import path, getcwd
+from uuid import uuid1
 
 from PIL import Image
 
@@ -18,6 +19,10 @@ class MediaFile(ObservableDict):
     def get_file(self):
         return self.__get_file(self['id'])
 
+    def add_result(self, result):
+        result['id'] = str(uuid1())
+        self['predictionResults'][result['id']] = result
+
     def resize(self, maximum_width):
         # check if resized file already exists
         resized = MediaFile(self, self.parent)

+ 4 - 1
webui/src/App.vue

@@ -79,7 +79,10 @@ export default {
         io: io(window.location.protocol + '//' + window.location.hostname + ':5000'),
         // http methods
         post: function(name, value) {
-          return fetch(this.baseurl + name, {
+          if (!name.startsWith('http'))
+            name = this.baseurl + name;
+
+          return fetch(name, {
             method: 'POST',
             body: JSON.stringify(value)
           });

+ 14 - 12
webui/src/components/media/annotated-image.vue

@@ -9,8 +9,9 @@
                     :image="image"
                     :position="current"/>
 
-    <annotation-box v-for="result in data.predictionResults"
-                    v-bind:key="result"
+    <annotation-box v-for="(result, index) in predictions"
+                    type="server"
+                    :key="index"
                     :image="image"
                     :position="result"/>
   </div>
@@ -54,16 +55,19 @@ export default {
     }
   },
   computed: {
-    mediaUrl: function() {
+    mediaUrl: function () {
       return this.socket.media(this.project.id, this.data.id);
     },
-    mediaUrlSet: function() {
+    mediaUrlSet: function () {
       return this.sizes.map(e => this.mediaUrl + '/' + e + ' ' + e + 'w').join(',');
     },
-    mediaUrlSizes: function() {
+    mediaUrlSizes: function () {
       return this.sizes.map(e => '(max-width: ' + e + 'px) ' + e + 'px').join(',');
     },
-    events: function() {
+    predictions: function () {
+      return Object.keys(this.data.predictionResults).map(k => this.data.predictionResults[k]);
+    },
+    events: function () {
       return {
         'touchstart': this.press,
         'touchmove': this.track,
@@ -120,7 +124,7 @@ export default {
         y: this.getY(event)
       };
     },
-    track: function(event) {
+    track: function (event) {
       if (this.start) {
         const x = this.getX(event);
         const y = this.getY(event);
@@ -129,12 +133,10 @@ export default {
       }
 
     },
-    release: function(event) {
-      console.log('release', event);
-
-      // TODO send to server
+    release: function () {
+      this.socket.post(this.mediaUrl, this.current);
       this.start = false;
-      // this.current = this.buildRectangle(this.start.x, this.start.y, this.getX(event), this.getY(event));
+      this.current = false;
     }
   }
 }

+ 12 - 4
webui/src/components/media/annotation-box.vue

@@ -7,9 +7,18 @@
 <script>
 export default {
   name: "annotation-box",
-  props: ['image', 'position'],
+  props: ['type', 'image', 'position'],
   computed: {
-    style: function() {
+    backgroundColor: function () {
+      switch (this.type) {
+        case 'server':
+          return 'rgba(255, 0, 0, 0.3)';
+
+        default:
+          return 'rgba(255, 255, 255, 0.3)';
+      }
+    },
+    style: function () {
       const left = this.image.left;
       const top = this.image.top;
       const width = this.image.width;
@@ -20,6 +29,7 @@ export default {
         top: (top + this.position.y * height) + 'px',
         width: (this.position.w * width) + 'px',
         height: (this.position.h * height) + 'px',
+        backgroundColor: this.backgroundColor
       }
     }
   }
@@ -29,7 +39,5 @@ export default {
 <style scoped>
 .annotation-box {
   position: absolute;
-  background-color: rgba(255, 255, 255, 0.3);
-
 }
 </style>

+ 1 - 1
webui/src/components/projects/project-data-view-window.vue

@@ -16,4 +16,4 @@ export default {
 
 <style scoped>
 
-</style>
+</style>