From 96c572d67ea44242a34be4dae359c35677b25098 Mon Sep 17 00:00:00 2001 From: ab Date: Wed, 30 Oct 2019 16:52:16 -0400 Subject: ibm server request works! --- src/client/apis/IBM_Recommender.ts | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 src/client/apis/IBM_Recommender.ts (limited to 'src/client/apis') diff --git a/src/client/apis/IBM_Recommender.ts b/src/client/apis/IBM_Recommender.ts new file mode 100644 index 000000000..4043342f4 --- /dev/null +++ b/src/client/apis/IBM_Recommender.ts @@ -0,0 +1,38 @@ +import { Opt } from "../../new_fields/Doc"; + +const NaturalLanguageUnderstandingV1 = require('ibm-watson/natural-language-understanding/v1'); +const { IamAuthenticator } = require('ibm-watson/auth'); + +export namespace IBM_Recommender { + + const naturalLanguageUnderstanding = new NaturalLanguageUnderstandingV1({ + version: '2019-07-12', + authenticator: new IamAuthenticator({ + apikey: 'tLiYwbRim3CnBcCO4phubpf-zEiGcub1uh0V-sD9OKhw', + }), + url: 'https://gateway-wdc.watsonplatform.net/natural-language-understanding/api' + }); + + const analyzeParams = { + 'url': 'www.ibm.com', + 'features': { + 'keywords': { + 'sentiment': true, + 'emotion': true, + 'limit': 3 + } + } + }; + + export const analyze = async (_parameters: any): Promise> => { + try { + const response = await naturalLanguageUnderstanding.analyze(analyzeParams); + console.log(response); + return (JSON.stringify(response, null, 2)); + } catch (err) { + console.log('error: ', err); + return undefined; + } + }; + +} \ No newline at end of file -- cgit v1.2.3-70-g09d2 From d26e058019d878d3058cb3806855281076b8d411 Mon Sep 17 00:00:00 2001 From: ab Date: Mon, 4 Nov 2019 10:01:17 -0500 Subject: idk --- src/client/apis/IBM_Recommender.ts | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/client/apis') diff --git a/src/client/apis/IBM_Recommender.ts b/src/client/apis/IBM_Recommender.ts index 4043342f4..5f80f5126 100644 --- a/src/client/apis/IBM_Recommender.ts +++ b/src/client/apis/IBM_Recommender.ts @@ -5,6 +5,8 @@ const { IamAuthenticator } = require('ibm-watson/auth'); export namespace IBM_Recommender { + // pass to IBM account is Browngfx1 + const naturalLanguageUnderstanding = new NaturalLanguageUnderstandingV1({ version: '2019-07-12', authenticator: new IamAuthenticator({ -- cgit v1.2.3-70-g09d2 From e103be2d58da2a6809dd4ad5f0b5f445d8d6c96b Mon Sep 17 00:00:00 2001 From: ab Date: Sat, 16 Nov 2019 16:45:41 -0500 Subject: ibm integrated, bing search -> server next time --- package.json | 7 ++- src/client/ClientRecommender.tsx | 66 ++++++++++++++++++++-- src/client/apis/IBM_Recommender.ts | 6 +- .../collectionFreeForm/CollectionFreeFormView.tsx | 5 -- src/client/views/nodes/DocumentView.tsx | 2 +- src/server/index.ts | 2 +- 6 files changed, 70 insertions(+), 18 deletions(-) (limited to 'src/client/apis') diff --git a/package.json b/package.json index 80b65cc68..d41119a47 100644 --- a/package.json +++ b/package.json @@ -57,9 +57,9 @@ "@hig/theme-context": "^2.1.3", "@hig/theme-data": "^2.3.3", "@tensorflow-models/universal-sentence-encoder": "^1.2.0", - "@tensorflow/tfjs": "^1.3.1", + "@tensorflow/tfjs-converter": "^1.3.2", "@tensorflow/tfjs-core": "^1.3.1", - "@tensorflow/tfjs-node": "^1.3.1", + "@tensorflow/tfjs-node": "1.3.1", "@trendmicro/react-dropdown": "^1.3.0", "@types/adm-zip": "^0.4.32", "@types/animejs": "^2.0.2", @@ -238,8 +238,9 @@ "url-loader": "^1.1.2", "uuid": "^3.3.2", "wikijs": "^6.0.1", + "word2vec": "^1.1.4", "words-to-numbers": "^1.5.1", "xoauth2": "^1.2.0", "youtube": "^0.1.0" } -} \ No newline at end of file +} diff --git a/src/client/ClientRecommender.tsx b/src/client/ClientRecommender.tsx index 364ec0fe0..a37434c0d 100644 --- a/src/client/ClientRecommender.tsx +++ b/src/client/ClientRecommender.tsx @@ -8,6 +8,7 @@ import { observable, action, computed, reaction } from "mobx"; var assert = require('assert'); var sw = require('stopword'); var FeedParser = require('feedparser'); +var https = require('https'); import "./ClientRecommender.scss"; import { JSXElement } from "babel-types"; import { RichTextField } from "../new_fields/RichTextField"; @@ -111,7 +112,7 @@ export class ClientRecommender extends React.Component { } ); let doclist = Array.from(ClientRecommender.Instance.docVectors); - if (distance_metric == "euclidian") { + if (distance_metric === "euclidian") { doclist.sort((a: RecommenderDocument, b: RecommenderDocument) => a.score - b.score); } else { @@ -245,7 +246,27 @@ export class ClientRecommender extends React.Component { if (kp_string.length > 2) kp_string = kp_string.substring(0, kp_string.length - 2); console.log("kp string: ", kp_string); let values = ""; - if (!internal) values = await this.sendRequest(highKP); + if (!internal) { + const parameters: any = { + 'language': 'en', + 'text': data, + 'features': { + 'keywords': { + 'sentiment': true, + 'emotion': true, + 'limit': 3 + } + } + }; + await Identified.PostToServer("/IBMAnalysis", parameters).then(response => { + const sorted_keywords = response.result.keywords; + if (sorted_keywords.length > 0) { + console.log("IBM keyphrase", sorted_keywords[0]); + highKP = [sorted_keywords[0].text]; + } + }); + values = await this.sendRequest(highKP, "bing"); + } return { keyterms: keyterms, external_recommendations: values, kp_string: [kp_string] }; }; if (data !== "") { @@ -290,11 +311,46 @@ export class ClientRecommender extends React.Component { * API for sending arXiv request. */ - private async sendRequest(keywords: string[]) { + private async sendRequest(keywords: string[], api: string) { let query = ""; keywords.forEach((kp: string) => query += " " + kp); - return new Promise(resolve => { - this.arxivrequest(query).then(resolve); + if (api === "arxiv") { + return new Promise(resolve => { + this.arxivrequest(query).then(resolve); + }); + } + else if (api === "bing") { + await this.bingWebSearch(query); + } + else { + return new Promise(resolve => { + this.arxivrequest(query).then(resolve); + }); + } + + } + + bingWebSearch = async (query: string) => { + https.get({ + hostname: 'api.cognitive.microsoft.com', + path: '/bing/v5.0/search?q=' + encodeURIComponent(query), + headers: { 'Ocp-Apim-Subscription-Key': process.env.BING }, + }, (res: any) => { + let body = ''; + res.on('data', (part: any) => body += part); + res.on('end', () => { + for (var header in res.headers) { + if (header.startsWith("bingapis-") || header.startsWith("x-msedge-")) { + console.log(header + ": " + res.headers[header]) + } + } + console.log('\nJSON Response:\n'); + console.dir(JSON.parse(body), { colors: false, depth: null }); + }) + res.on('error', (e: any) => { + console.log('Error: ' + e.message); + throw e; + }); }); } diff --git a/src/client/apis/IBM_Recommender.ts b/src/client/apis/IBM_Recommender.ts index 5f80f5126..da6257f28 100644 --- a/src/client/apis/IBM_Recommender.ts +++ b/src/client/apis/IBM_Recommender.ts @@ -16,19 +16,19 @@ export namespace IBM_Recommender { }); const analyzeParams = { - 'url': 'www.ibm.com', + 'text': 'this is a test of the keyword extraction feature I am integrating into the program', 'features': { 'keywords': { 'sentiment': true, 'emotion': true, 'limit': 3 - } + }, } }; export const analyze = async (_parameters: any): Promise> => { try { - const response = await naturalLanguageUnderstanding.analyze(analyzeParams); + const response = await naturalLanguageUnderstanding.analyze(_parameters); console.log(response); return (JSON.stringify(response, null, 2)); } catch (err) { diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index bb5d99a28..bfec545c6 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -34,11 +34,6 @@ import { CollectionFreeFormRemoteCursors } from "./CollectionFreeFormRemoteCurso import "./CollectionFreeFormView.scss"; import { MarqueeView } from "./MarqueeView"; import React = require("react"); -import v5 = require("uuid/v5"); -import { ClientRecommender } from "../../../ClientRecommender"; -import { SearchUtil } from "../../../util/SearchUtil"; -import { RouteStore } from "../../../../server/RouteStore"; -import { string, number, elementType } from "prop-types"; import { DocServer } from "../../../DocServer"; import { documentSchema, positionSchema } from "../../../../new_fields/documentSchemas"; import { DocumentViewProps } from "../../nodes/DocumentView"; diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 55063a52c..c6ad2f9d7 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -772,7 +772,7 @@ export class DocumentView extends DocComponent(Docu } render() { if (!this.props.Document) return (null); - trace(); + //trace(); const animDims = this.Document.animateToDimensions ? Array.from(this.Document.animateToDimensions) : undefined; const ruleColor = this.props.ruleProvider ? StrCast(this.props.ruleProvider["ruleColor_" + this.Document.heading]) : undefined; const ruleRounding = this.props.ruleProvider ? StrCast(this.props.ruleProvider["ruleRounding_" + this.Document.heading]) : undefined; diff --git a/src/server/index.ts b/src/server/index.ts index 2a669f147..45fc7fc07 100644 --- a/src/server/index.ts +++ b/src/server/index.ts @@ -1086,7 +1086,7 @@ addSecureRoute({ const batched = BatchedArray.from(media, { batchSize: 25 }); const newMediaItems = await batched.batchedMapPatientInterval( { magnitude: 100, unit: TimeUnit.Milliseconds }, - async (batch, collector) => { + async (batch: any, collector: any): Promise => { for (let index = 0; index < batch.length; index++) { const { url, description } = batch[index]; const uploadToken = await GooglePhotosUploadUtils.DispatchGooglePhotosUpload(url); -- cgit v1.2.3-70-g09d2 From bfebed91e12abca324d7a638adeb1da9755a9057 Mon Sep 17 00:00:00 2001 From: bob Date: Wed, 22 Jan 2020 15:41:04 -0500 Subject: basic cleanup for warnings --- src/client/apis/youtube/YoutubeBox.tsx | 2 +- src/client/util/ProseMirrorEditorView.tsx | 74 ---------------------- src/client/util/RichTextMenu.tsx | 68 ++++++++++---------- src/client/util/RichTextSchema.tsx | 2 +- src/client/views/EditableView.tsx | 2 +- src/client/views/MainView.tsx | 2 +- .../views/collections/CollectionPivotView.tsx | 11 ++-- .../views/collections/CollectionTreeView.tsx | 2 +- .../views/collections/CollectionViewChromes.tsx | 3 +- .../collectionFreeForm/CollectionFreeFormView.tsx | 4 +- .../collectionFreeForm/MarqueeOptionsMenu.tsx | 3 + src/client/views/linking/LinkMenu.tsx | 2 +- src/client/views/nodes/WebBox.tsx | 2 +- src/client/views/search/SearchItem.tsx | 1 - src/new_fields/Doc.ts | 10 +-- src/new_fields/documentSchemas.ts | 1 + src/server/Websocket/Websocket.ts | 2 - 17 files changed, 59 insertions(+), 132 deletions(-) delete mode 100644 src/client/util/ProseMirrorEditorView.tsx (limited to 'src/client/apis') diff --git a/src/client/apis/youtube/YoutubeBox.tsx b/src/client/apis/youtube/YoutubeBox.tsx index fd3d9e2f1..d654e2530 100644 --- a/src/client/apis/youtube/YoutubeBox.tsx +++ b/src/client/apis/youtube/YoutubeBox.tsx @@ -46,7 +46,7 @@ export class YoutubeBox extends React.Component { * When component mounts, last search's results are laoded in based on the back up stored * in the document of the props. */ - async componentWillMount() { + async componentDidMount() { //DocServer.getYoutubeChannels(); const castedSearchBackUp = Cast(this.props.Document.cachedSearchResults, Doc); const awaitedBackUp = await castedSearchBackUp; diff --git a/src/client/util/ProseMirrorEditorView.tsx b/src/client/util/ProseMirrorEditorView.tsx deleted file mode 100644 index b42adfbb4..000000000 --- a/src/client/util/ProseMirrorEditorView.tsx +++ /dev/null @@ -1,74 +0,0 @@ -import React from "react"; -import { EditorView } from "prosemirror-view"; -import { EditorState } from "prosemirror-state"; - -export interface ProseMirrorEditorViewProps { - /* EditorState instance to use. */ - editorState: EditorState; - /* Called when EditorView produces new EditorState. */ - onEditorState: (editorState: EditorState) => any; -} - -/** - * This wraps ProseMirror's EditorView into React component. - * This code was found on https://discuss.prosemirror.net/t/using-with-react/904 - */ -export class ProseMirrorEditorView extends React.Component { - - private _editorView?: EditorView; - - _createEditorView = (element: HTMLDivElement | null) => { - if (element !== null) { - this._editorView = new EditorView(element, { - state: this.props.editorState, - dispatchTransaction: this.dispatchTransaction, - }); - } - } - - dispatchTransaction = (tx: any) => { - // In case EditorView makes any modification to a state we funnel those - // modifications up to the parent and apply to the EditorView itself. - const editorState = this.props.editorState.apply(tx); - if (this._editorView) { - this._editorView.updateState(editorState); - } - this.props.onEditorState(editorState); - } - - focus() { - if (this._editorView) { - this._editorView.focus(); - } - } - - componentWillReceiveProps(nextProps: { editorState: EditorState; }) { - // In case we receive new EditorState through props — we apply it to the - // EditorView instance. - if (this._editorView) { - if (nextProps.editorState !== this.props.editorState) { - this._editorView.updateState(nextProps.editorState); - } - } - } - - componentWillUnmount() { - if (this._editorView) { - this._editorView.destroy(); - } - } - - shouldComponentUpdate() { - // Note that EditorView manages its DOM itself so we'd ratrher don't mess - // with it. - return false; - } - - render() { - // Render just an empty div which is then used as a container for an - // EditorView instance. - return ( -
- ); - } -} \ No newline at end of file diff --git a/src/client/util/RichTextMenu.tsx b/src/client/util/RichTextMenu.tsx index f070589ae..eb5c90654 100644 --- a/src/client/util/RichTextMenu.tsx +++ b/src/client/util/RichTextMenu.tsx @@ -73,7 +73,7 @@ export default class RichTextMenu extends AntimodeMenu { this.fontSizeOptions = [ { mark: schema.marks.pFontSize.create({ fontSize: 7 }), title: "Set font size", label: "7pt", command: this.changeFontSize }, { mark: schema.marks.pFontSize.create({ fontSize: 8 }), title: "Set font size", label: "8pt", command: this.changeFontSize }, - { mark: schema.marks.pFontSize.create({ fontSize: 9 }), title: "Set font size", label: "8pt", command: this.changeFontSize }, + { mark: schema.marks.pFontSize.create({ fontSize: 9 }), title: "Set font size", label: "9pt", command: this.changeFontSize }, { mark: schema.marks.pFontSize.create({ fontSize: 10 }), title: "Set font size", label: "10pt", command: this.changeFontSize }, { mark: schema.marks.pFontSize.create({ fontSize: 12 }), title: "Set font size", label: "12pt", command: this.changeFontSize }, { mark: schema.marks.pFontSize.create({ fontSize: 14 }), title: "Set font size", label: "14pt", command: this.changeFontSize }, @@ -312,22 +312,22 @@ export default class RichTextMenu extends AntimodeMenu { } return ( - ); } - createMarksDropdown(activeOption: string, options: { mark: Mark | null, title: string, label: string, command: (mark: Mark, view: EditorView) => void, hidden?: boolean, style?: {} }[]): JSX.Element { + createMarksDropdown(activeOption: string, options: { mark: Mark | null, title: string, label: string, command: (mark: Mark, view: EditorView) => void, hidden?: boolean, style?: {} }[], key: string): JSX.Element { const items = options.map(({ title, label, hidden, style }) => { if (hidden) { return label === activeOption ? - : - ; + : + ; } return label === activeOption ? - : - ; + : + ; }); const self = this; @@ -340,19 +340,19 @@ export default class RichTextMenu extends AntimodeMenu { } }); } - return ; + return ; } - createNodesDropdown(activeOption: string, options: { node: NodeType | any | null, title: string, label: string, command: (node: NodeType | any) => void, hidden?: boolean, style?: {} }[]): JSX.Element { + createNodesDropdown(activeOption: string, options: { node: NodeType | any | null, title: string, label: string, command: (node: NodeType | any) => void, hidden?: boolean, style?: {} }[], key: string): JSX.Element { const items = options.map(({ title, label, hidden, style }) => { if (hidden) { return label === activeOption ? - : - ; + : + ; } return label === activeOption ? - : - ; + : + ; }); const self = this; @@ -363,7 +363,7 @@ export default class RichTextMenu extends AntimodeMenu { } }); } - return ; + return ; } changeFontSize = (mark: Mark, view: EditorView) => { @@ -472,7 +472,7 @@ export default class RichTextMenu extends AntimodeMenu {
; return ( - + ); } @@ -535,21 +535,21 @@ export default class RichTextMenu extends AntimodeMenu { ; const dropdownContent = -
+

Change font color:

{this.fontColors.map(color => { if (color) { return this.activeFontColor === color ? - : - ; + : + ; } })}
; return ( - + ); } @@ -582,7 +582,7 @@ export default class RichTextMenu extends AntimodeMenu { } const button = - ; @@ -594,15 +594,15 @@ export default class RichTextMenu extends AntimodeMenu { {this.highlightColors.map(color => { if (color) { return this.activeHighlightColor === color ? - : - ; + : + ; } })}
; return ( - + ); } @@ -635,7 +635,7 @@ export default class RichTextMenu extends AntimodeMenu { ; return ( - + ); } @@ -773,7 +773,7 @@ export default class RichTextMenu extends AntimodeMenu { render() { - const row1 =
{[ + const row1 =
{[ this.createButton("bold", "Bold", this.boldActive, toggleMark(schema.marks.strong)), this.createButton("italic", "Italic", this.italicsActive, toggleMark(schema.marks.em)), this.createButton("underline", "Underline", this.underlineActive, toggleMark(schema.marks.underline)), @@ -787,14 +787,14 @@ export default class RichTextMenu extends AntimodeMenu { this.createButton("indent", "Summarize", undefined, this.insertSummarizer), ]}
; - const row2 =
-
- {[this.createMarksDropdown(this.activeFontSize, this.fontSizeOptions), - this.createMarksDropdown(this.activeFontFamily, this.fontFamilyOptions), - this.createNodesDropdown(this.activeListType, this.listTypeOptions)]} + const row2 =
+
+ {[this.createMarksDropdown(this.activeFontSize, this.fontSizeOptions, "font size"), + this.createMarksDropdown(this.activeFontFamily, this.fontFamilyOptions, "font family"), + this.createNodesDropdown(this.activeListType, this.listTypeOptions, "nodes")]}
-
- {this.getDragger()} @@ -864,12 +864,12 @@ class ButtonDropdown extends React.Component { : <> {this.props.button} - } - {this.showDropdown ? this.props.dropdownContent : <>} + {this.showDropdown ? this.props.dropdownContent : (null)}
); } diff --git a/src/client/util/RichTextSchema.tsx b/src/client/util/RichTextSchema.tsx index 1f70cafc4..5751c8c7e 100644 --- a/src/client/util/RichTextSchema.tsx +++ b/src/client/util/RichTextSchema.tsx @@ -306,7 +306,7 @@ export const marks: { [index: string]: MarkSpec } = { } }], toDOM(node: any) { - return node.attrs.color ? ['span', { style: 'color:' + node.attrs.color }] : ['span', { style: 'color: black' }]; + return node.attrs.color ? ['span', { style: 'color:' + node.attrs.color }] : ['span', 0]; } }, diff --git a/src/client/views/EditableView.tsx b/src/client/views/EditableView.tsx index 0d677b8ce..394caba72 100644 --- a/src/client/views/EditableView.tsx +++ b/src/client/views/EditableView.tsx @@ -66,7 +66,7 @@ export class EditableView extends React.Component { } @action - componentWillReceiveProps(nextProps: EditableProps) { + componentDidUpdate(nextProps: EditableProps) { // this is done because when autosuggest is turned on, the suggestions are passed in as a prop, // so when the suggestions are passed in, and no editing prop is passed in, it used to set it // to false. this will no longer do so -syip diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 0958c434a..79e0cfea5 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -64,7 +64,7 @@ export class MainView extends React.Component { public isPointerDown = false; - componentWillMount() { + componentDidMount() { const tag = document.createElement('script'); tag.src = "https://www.youtube.com/iframe_api"; diff --git a/src/client/views/collections/CollectionPivotView.tsx b/src/client/views/collections/CollectionPivotView.tsx index f23540529..aa68cc18f 100644 --- a/src/client/views/collections/CollectionPivotView.tsx +++ b/src/client/views/collections/CollectionPivotView.tsx @@ -28,6 +28,7 @@ export class CollectionPivotView extends CollectionSubView(doc => doc) { if (!this.props.Document.facetCollection) { const facetCollection = Docs.Create.TreeDocument([], { title: "facetFilters", yMargin: 0, treeViewHideTitle: true }); facetCollection.target = this.props.Document; + facetCollection.dontCopyOnAlias = true; const scriptText = "setDocFilter(containingTreeView.target, heading, this.title, checked)"; const script = CompileScript(scriptText, { @@ -122,8 +123,8 @@ export class CollectionPivotView extends CollectionSubView(doc => doc) { const facetCollection = Cast(this.props.Document?.facetCollection, Doc, null); const flyout = (
- {this._allFacets.map(facet =>