From d6cef0815815c2587b9cc791e6a37c742aba1b45 Mon Sep 17 00:00:00 2001
From: Sam Wilkins <samwilkins333@gmail.com>
Date: Thu, 25 Jul 2019 03:31:34 -0400
Subject: cognitive services refactor, buxton python script fixes, covered up
 imagebox context menu bug

---
 .../views/collections/collectionFreeForm/CollectionFreeFormView.tsx     | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx')

diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index bd5c6f84b..4b7ddd49d 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -519,7 +519,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
                 if (!data) {
                     return;
                 }
-                CognitiveServices.Inking.analyze(data.inkData, Doc.GetProto(this.props.Document));
+                CognitiveServices.Inking.Manager.applier(Doc.GetProto(this.props.Document), data.inkData);
             }
         });
     }
-- 
cgit v1.2.3-70-g09d2


From 1846c217adb814a2b0297b8ab808c2f587741936 Mon Sep 17 00:00:00 2001
From: Sam Wilkins <samwilkins333@gmail.com>
Date: Thu, 25 Jul 2019 09:26:33 -0400
Subject: final cognitive services refactor

---
 src/client/cognitive_services/CognitiveServices.ts | 84 +++++++++++-----------
 .../collectionFreeForm/CollectionFreeFormView.tsx  |  4 +-
 2 files changed, 47 insertions(+), 41 deletions(-)

(limited to 'src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx')

diff --git a/src/client/cognitive_services/CognitiveServices.ts b/src/client/cognitive_services/CognitiveServices.ts
index d689b424d..0cda17325 100644
--- a/src/client/cognitive_services/CognitiveServices.ts
+++ b/src/client/cognitive_services/CognitiveServices.ts
@@ -10,9 +10,10 @@ import { CompileScript } from "../util/Scripting";
 import { ComputedField } from "../../new_fields/ScriptField";
 import { InkData } from "../../new_fields/InkField";
 
-type APIManager<D> = { requester: RequestExecutor<D>, applier: AnalysisApplier };
-type RequestExecutor<D> = (apiKey: string, data: D, service: Service) => Promise<string>;
-type AnalysisApplier = (target: Doc, ...args: any) => any;
+type APIManager<D> = { converter: BodyConverter<D>, requester: RequestExecutor, analyzer: AnalysisApplier };
+type RequestExecutor = (apiKey: string, body: string, service: Service) => Promise<string>;
+type AnalysisApplier = (target: Doc, relevantKeys: string[], ...args: any) => any;
+type BodyConverter<D> = (data: D) => string;
 type Converter = (results: any) => Field;
 
 export type Tag = { name: string, confidence: number };
@@ -40,7 +41,7 @@ export enum Confidence {
  */
 export namespace CognitiveServices {
 
-    const executeQuery = async <D, R>(service: Service, executor: RequestExecutor<D>, data: D): Promise<Opt<R>> => {
+    const executeQuery = async <D, R>(service: Service, manager: APIManager<D>, data: D): Promise<Opt<R>> => {
         return fetch(Utils.prepend(`${RouteStore.cognitiveServices}/${service}`)).then(async response => {
             let apiKey = await response.text();
             if (!apiKey) {
@@ -49,7 +50,7 @@ export namespace CognitiveServices {
 
             let results: Opt<R>;
             try {
-                results = await executor(apiKey, data, service).then(json => JSON.parse(json));
+                results = await manager.requester(apiKey, manager.converter(data), service).then(json => JSON.parse(json));
             } catch {
                 results = undefined;
             }
@@ -61,7 +62,9 @@ export namespace CognitiveServices {
 
         export const Manager: APIManager<string> = {
 
-            requester: (async (apiKey: string, imageUrl: string, service: Service) => {
+            converter: (imageUrl: string) => JSON.stringify({ url: imageUrl }),
+
+            requester: async (apiKey: string, body: string, service: Service) => {
                 let uriBase;
                 let parameters;
 
@@ -88,7 +91,7 @@ export namespace CognitiveServices {
                 const options = {
                     uri: 'https://eastus.api.cognitive.microsoft.com/' + uriBase,
                     qs: parameters,
-                    body: `{"url": "${imageUrl}"}`,
+                    body: body,
                     headers: {
                         'Content-Type': 'application/json',
                         'Ocp-Apim-Subscription-Key': apiKey
@@ -96,15 +99,16 @@ export namespace CognitiveServices {
                 };
 
                 return request.post(options);
-            }) as RequestExecutor<string>,
+            },
 
-            applier: (async (target: Doc, service: Service, converter: Converter, storageKey: string) => {
+            analyzer: async (target: Doc, keys: string[], service: Service, converter: Converter) => {
                 let imageData = Cast(target.data, ImageField);
+                let storageKey = keys[0];
                 if (!imageData || await Cast(target[storageKey], Doc)) {
                     return;
                 }
                 let toStore: any;
-                let results = await executeQuery<string, any>(service, Manager.requester, imageData.url.href);
+                let results = await executeQuery<string, any>(service, Manager, imageData.url.href);
                 if (!results) {
                     toStore = "Cognitive Services could not process the given image URL.";
                 } else {
@@ -115,7 +119,7 @@ export namespace CognitiveServices {
                     }
                 }
                 target[storageKey] = toStore;
-            }) as AnalysisApplier
+            }
 
         };
 
@@ -134,7 +138,7 @@ export namespace CognitiveServices {
                 tagDoc.confidence = threshold;
                 return tagDoc;
             };
-            Manager.applier(target, Service.ComputerVision, converter, "generatedTags");
+            Manager.analyzer(target, ["generatedTags"], Service.ComputerVision, converter);
         };
 
         export const extractFaces = async (target: Doc) => {
@@ -143,7 +147,7 @@ export namespace CognitiveServices {
                 results.map((face: Face) => faceDocs.push(Docs.Get.DocumentHierarchyFromJson(face, `Face: ${face.faceId}`)!));
                 return faceDocs;
             };
-            Manager.applier(target, Service.Face, converter, "faces");
+            Manager.analyzer(target, ["faces"], Service.Face, converter);
         };
 
     }
@@ -152,7 +156,26 @@ export namespace CognitiveServices {
 
         export const Manager: APIManager<InkData> = {
 
-            requester: (async (apiKey: string, inkData: InkData) => {
+            converter: (inkData: InkData): string => {
+                let entries = inkData.entries(), next = entries.next();
+                let strokes: AzureStrokeData[] = [], id = 0;
+                while (!next.done) {
+                    strokes.push({
+                        id: id++,
+                        points: next.value[1].pathData.map(point => `${point.x},${point.y}`).join(","),
+                        language: "en-US"
+                    });
+                    next = entries.next();
+                }
+                return JSON.stringify({
+                    version: 1,
+                    language: "en-US",
+                    unit: "mm",
+                    strokes: strokes
+                });
+            },
+
+            requester: async (apiKey: string, body: string) => {
                 let xhttp = new XMLHttpRequest();
                 let serverAddress = "https://api.cognitive.microsoft.com";
                 let endpoint = serverAddress + "/inkrecognizer/v1.0-preview/recognize";
@@ -174,22 +197,22 @@ export namespace CognitiveServices {
                     xhttp.open("PUT", endpoint, true);
                     xhttp.setRequestHeader('Ocp-Apim-Subscription-Key', apiKey);
                     xhttp.setRequestHeader('Content-Type', 'application/json');
-                    xhttp.send(format(inkData));
+                    xhttp.send(body);
                 };
 
                 return new Promise<any>(promisified);
-            }) as RequestExecutor<InkData>,
+            },
 
-            applier: (async (target: Doc, inkData: InkData) => {
-                let results = await executeQuery<InkData, any>(Service.Handwriting, Manager.requester, inkData);
+            analyzer: async (target: Doc, keys: string[], inkData: InkData) => {
+                let results = await executeQuery<InkData, any>(Service.Handwriting, Manager, inkData);
                 if (results) {
                     results.recognitionUnits && (results = results.recognitionUnits);
-                    target.inkAnalysis = Docs.Get.DocumentHierarchyFromJson(results, "Ink Analysis");
+                    target[keys[0]] = Docs.Get.DocumentHierarchyFromJson(results, "Ink Analysis");
                     let recognizedText = results.map((item: any) => item.recognizedText);
                     let individualWords = recognizedText.filter((text: string) => text && text.split(" ").length === 1);
-                    target.handwriting = individualWords.join(" ");
+                    target[keys[1]] = individualWords.join(" ");
                 }
-            }) as AnalysisApplier
+            }
 
         };
 
@@ -206,25 +229,6 @@ export namespace CognitiveServices {
             strokes: AzureStrokeData[];
         }
 
-        const format = (inkData: InkData): string => {
-            let entries = inkData.entries(), next = entries.next();
-            let strokes: AzureStrokeData[] = [], id = 0;
-            while (!next.done) {
-                strokes.push({
-                    id: id++,
-                    points: next.value[1].pathData.map(point => `${point.x},${point.y}`).join(","),
-                    language: "en-US"
-                });
-                next = entries.next();
-            }
-            return JSON.stringify({
-                version: 1,
-                language: "en-US",
-                unit: "mm",
-                strokes: strokes
-            });
-        };
-
     }
 
 }
\ No newline at end of file
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 4b7ddd49d..d39d6f255 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -519,7 +519,9 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
                 if (!data) {
                     return;
                 }
-                CognitiveServices.Inking.Manager.applier(Doc.GetProto(this.props.Document), data.inkData);
+                let target = Doc.GetProto(this.props.Document);
+                let relevantKeys = ["inkAnalysis", "handwriting"];
+                CognitiveServices.Inking.Manager.analyzer(target, relevantKeys, data.inkData);
             }
         });
     }
-- 
cgit v1.2.3-70-g09d2


From b4888c53bcc4eb9a37ed4b3dac740bfffc64d3c5 Mon Sep 17 00:00:00 2001
From: Sam Wilkins <samwilkins333@gmail.com>
Date: Thu, 25 Jul 2019 11:46:28 -0400
Subject: postponed dealing with circular import bug imagebox

---
 src/client/DocServer.ts                                             | 1 -
 .../views/collections/collectionFreeForm/CollectionFreeFormView.tsx | 5 ++++-
 src/client/views/nodes/ImageBox.tsx                                 | 6 +++---
 3 files changed, 7 insertions(+), 5 deletions(-)

(limited to 'src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx')

diff --git a/src/client/DocServer.ts b/src/client/DocServer.ts
index 077c8e5ba..df9828029 100644
--- a/src/client/DocServer.ts
+++ b/src/client/DocServer.ts
@@ -5,7 +5,6 @@ import { Utils, emptyFunction } from '../Utils';
 import { SerializationHelper } from './util/SerializationHelper';
 import { RefField } from '../new_fields/RefField';
 import { Id, HandleUpdate } from '../new_fields/FieldSymbols';
-import { CurrentUserUtils } from '../server/authentication/models/current_user_utils';
 
 /**
  * This class encapsulates the transfer and cross-client synchronization of
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index d39d6f255..701574cfc 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -32,7 +32,10 @@ import { OverlayView, OverlayElementOptions } from "../../OverlayView";
 import { ScriptBox } from "../../ScriptBox";
 import { CompileScript } from "../../../util/Scripting";
 import { CognitiveServices } from "../../../cognitive_services/CognitiveServices";
+import { library } from "@fortawesome/fontawesome-svg-core";
+import { faEye } from "@fortawesome/free-regular-svg-icons";
 
+library.add(faEye);
 
 export const panZoomSchema = createSchema({
     panX: "number",
@@ -522,7 +525,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
                 let target = Doc.GetProto(this.props.Document);
                 let relevantKeys = ["inkAnalysis", "handwriting"];
                 CognitiveServices.Inking.Manager.analyzer(target, relevantKeys, data.inkData);
-            }
+            }, icon: "eye"
         });
     }
 
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index 3d77696fe..c0c64b6d5 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -216,9 +216,9 @@ export class ImageBox extends DocComponent<FieldViewProps, ImageDocument>(ImageD
             });
 
             let modes: ContextMenuProps[] = [];
-            // let dataDoc = Doc.GetProto(this.Document);
-            modes.push({ description: "Generate Tags", event: () => CognitiveServices.Image.generateMetadata(this.Document), icon: "tag" });
-            modes.push({ description: "Find Faces", event: () => CognitiveServices.Image.extractFaces(this.Document), icon: "camera" });
+            let dataDoc = Doc.GetProto(this.props.Document);
+            modes.push({ description: "Generate Tags", event: () => CognitiveServices.Image.generateMetadata(dataDoc), icon: "tag" });
+            modes.push({ description: "Find Faces", event: () => CognitiveServices.Image.extractFaces(dataDoc), icon: "camera" });
 
             ContextMenu.Instance.addItem({ description: "Image Funcs...", subitems: funcs });
             ContextMenu.Instance.addItem({ description: "Analyze...", subitems: modes });
-- 
cgit v1.2.3-70-g09d2

