aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/cognitive_services/CognitiveServices.ts134
-rw-r--r--src/server/RouteStore.ts3
2 files changed, 137 insertions, 0 deletions
diff --git a/src/client/cognitive_services/CognitiveServices.ts b/src/client/cognitive_services/CognitiveServices.ts
new file mode 100644
index 000000000..1a002e025
--- /dev/null
+++ b/src/client/cognitive_services/CognitiveServices.ts
@@ -0,0 +1,134 @@
+import * as request from "request-promise";
+import { Doc, Field } from "../../new_fields/Doc";
+import { Cast } from "../../new_fields/Types";
+import { ImageField } from "../../new_fields/URLField";
+import { values } from "mobx";
+import { List } from "../../new_fields/List";
+import { Docs } from "../documents/Documents";
+import { Result } from "../northstar/model/idea/idea";
+import { RouteStore } from "../../server/RouteStore";
+import { Utils } from "../../Utils";
+
+export enum Services {
+ ComputerVision,
+ Face
+}
+
+export enum Confidence {
+ Yikes = 0.0,
+ Unlikely = 0.2,
+ Poor = 0.4,
+ Fair = 0.6,
+ Good = 0.8,
+ Excellent = 0.95
+}
+
+export type Tag = { name: string, confidence: number };
+export type Rectangle = { top: number, left: number, width: number, height: number };
+export type Face = { faceAttributes: any, faceId: string, faceRectangle: Rectangle };
+export type Converter = (results: any) => Field;
+
+/**
+ * A file that handles all interactions with Microsoft Azure's Cognitive
+ * Services APIs. These machine learning endpoints allow basic data analytics for
+ * various media types.
+ */
+export namespace CognitiveServices {
+
+ export namespace Image {
+
+ export const analyze = async (imageUrl: string, service: Services) => {
+ return fetch(Utils.prepend(RouteStore.cognitiveServices + service)).then(async response => {
+ let apiKey = await response.text();
+ if (apiKey) {
+ return;
+ }
+ let uriBase;
+ let parameters;
+
+ switch (service) {
+ case Services.Face:
+ uriBase = 'face/v1.0/detect';
+ parameters = {
+ 'returnFaceId': 'true',
+ 'returnFaceLandmarks': 'false',
+ 'returnFaceAttributes': 'age,gender,headPose,smile,facialHair,glasses,' +
+ 'emotion,hair,makeup,occlusion,accessories,blur,exposure,noise'
+ };
+ break;
+ case Services.ComputerVision:
+ uriBase = 'vision/v2.0/analyze';
+ parameters = {
+ 'visualFeatures': 'Categories,Description,Color,Objects,Tags,Adult',
+ 'details': 'Celebrities,Landmarks',
+ 'language': 'en',
+ };
+ break;
+ }
+
+ const options = {
+ uri: 'https://eastus.api.cognitive.microsoft.com/' + uriBase,
+ qs: parameters,
+ body: `{"url": "${imageUrl}"}`,
+ headers: {
+ 'Content-Type': 'application/json',
+ 'Ocp-Apim-Subscription-Key': apiKey
+ }
+ };
+
+ let results: any;
+ try {
+ results = await request.post(options).then(response => JSON.parse(response));
+ } catch (e) {
+ results = undefined;
+ }
+ return results;
+ });
+ };
+
+ const analyzeDocument = async (target: Doc, service: Services, converter: Converter, storageKey: string) => {
+ let imageData = Cast(target.data, ImageField);
+ if (!imageData || await Cast(target[storageKey], Doc)) {
+ return;
+ }
+ let toStore: any;
+ let results = await analyze(imageData.url.href, service);
+ if (!results) {
+ toStore = "Cognitive Services could not process the given image URL.";
+ } else {
+ if (!results.length) {
+ toStore = converter(results);
+ } else {
+ toStore = results.length > 0 ? converter(results) : "Empty list returned.";
+ }
+ }
+ target[storageKey] = toStore;
+ };
+
+ export const generateMetadata = async (target: Doc, threshold: Confidence = Confidence.Excellent) => {
+ let converter = (results: any) => {
+ let tagDoc = new Doc;
+ results.tags.map((tag: Tag) => {
+ if (tag.confidence >= +threshold) {
+ tagDoc[tag.name] = tag.confidence;
+ }
+ });
+ tagDoc.title = "Generated Tags";
+ tagDoc.confidenceThreshold = threshold.toString();
+ return tagDoc;
+ };
+ analyzeDocument(target, Services.ComputerVision, converter, "generatedTags");
+ };
+
+ export const extractFaces = async (target: Doc) => {
+ let converter = (results: any) => {
+ let faceDocs = new List<Doc>();
+ results.map((face: Face) => faceDocs.push(Docs.Get.DocumentHierarchyFromJson(face, `Face: ${face.faceId}`)!));
+ return faceDocs;
+ };
+ analyzeDocument(target, Services.Face, converter, "faces");
+ };
+
+ }
+
+} \ No newline at end of file
diff --git a/src/server/RouteStore.ts b/src/server/RouteStore.ts
index 5c13495ff..96bd62e23 100644
--- a/src/server/RouteStore.ts
+++ b/src/server/RouteStore.ts
@@ -29,4 +29,7 @@ export enum RouteStore {
forgot = "/forgotpassword",
reset = "/reset/:token",
+ // APIS
+ cognitiveServices = "/cognitiveservices/"
+
} \ No newline at end of file