Skip to content

Commit 34a7ff4

Browse files
committed
work on microsoft academic query support AND some nice livel_inspector enhancements
SQUASHED: AUTO-COMMIT-doc-journal-2020-09-11.md-index.md,AUTO-COMMIT-doc-journal-2020-09-11.md-microsoft_academics_interpretations.png,AUTO-COMMIT-src-client-protocols-academic-scheme.js,AUTO-COMMIT-src-components-tools-lively-inspector.js,
1 parent 5520589 commit 34a7ff4

File tree

4 files changed

+236
-4
lines changed

4 files changed

+236
-4
lines changed

doc/journal/2020-09-11.md/index.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,3 +54,30 @@ json.pr.map(ea => ({
5454

5555

5656
![](microsoft_academic_works.png)
57+
58+
### And with the Proper API
59+
60+
For using the API one needs a key for Project Academic Knowledge: <https://msr-apis.portal.azure-api.net/developer>
61+
62+
There is even a fancy [interpret API](https://docs.microsoft.com/en-us/academic-services/project-academic-knowledge/reference-interpret-method) that will generate the query for you:
63+
64+
```javascript
65+
var query = "paper: jens lincke 2009 ContextJS"
66+
fetch(`https://api.labs.cognitive.microsoft.com/academic/v1.0/interpret?query=`
67+
+ encodeURI(query)
68+
+ `&complete=1&count=2&subscription-key=90...`).then(r => r.json())
69+
```
70+
71+
72+
![](microsoft_academics_interpretations.png)
73+
74+
75+
This specific query can then be evaluated using this [API](https://docs.microsoft.com/en-us/academic-services/project-academic-knowledge/reference-evaluate-method)
76+
77+
78+
79+
80+
81+
82+
83+
149 KB
Loading
Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
import {Scheme} from "src/client/poid.js"
2+
import PolymorphicIdentifier from "src/client/poid.js"
3+
import focalStorage from "src/external/focalStorage.js"
4+
import {parseQuery, getDeepProperty} from 'utils'
5+
6+
import FileIndex from "src/client/fileindex.js"
7+
8+
import _ from 'src/external/lodash/lodash.js'
9+
/*MD
10+
# Microsoft Academic Search
11+
MD*/
12+
13+
/*MD
14+
<style>* {background-color:lightgray}</style>
15+
16+
### Example:
17+
18+
```javascript{.example}
19+
import {MicrosoftAcademicEntities} from "src/client/protocols/academic-scheme.js"
20+
MicrosoftAcademicEntities.schemas()
21+
```
22+
23+
### Microsoft Academic Raw Query:
24+
25+
```javascript{.example}
26+
fetch("https://academic.microsoft.com/api/search", {
27+
method: "POST",
28+
headers: {
29+
"content-type": "application/json; charset=utf-8"
30+
},
31+
body: JSON.stringify({
32+
query: "",
33+
queryExpression: "Composite(AA.AuN='jens lincke')",
34+
filters: [],
35+
orderBy: 0,
36+
skip: 0,
37+
sortAscending: true,
38+
take: 10})
39+
}).then(r => r.json())
40+
```
41+
42+
43+
### And with our Scheme
44+
45+
```javascript
46+
fetch("academic://Jens Lincke 2009", {
47+
method: "GET",
48+
headers: {
49+
"content-type": "application/json"
50+
}
51+
}).then(r => r.json())
52+
```
53+
54+
55+
56+
57+
MD*/
58+
59+
60+
import MarkdownIt from "src/external/markdown-it.js"
61+
62+
63+
export class MicrosoftAcademicEntities {
64+
65+
static get baseURL() {
66+
return "https://raw.githubusercontent.com/MicrosoftDocs/microsoft-academic-services/live/academic-services/project-academic-knowledge/"
67+
68+
}
69+
70+
static async generateSchema(entityName) {
71+
var md = new MarkdownIt();
72+
var content = await fetch(this.baseURL + "reference-" + entityName+"-entity-attributes.md").then(r => r.text())
73+
var html= md.render(content);
74+
var div = <div></div>
75+
div.innerHTML = html
76+
var tbody = div.querySelector("tbody")
77+
return tbody ? Array.from(tbody.querySelectorAll("tr")
78+
.map(ea => Array.from(ea.querySelectorAll("td").map(td => td.textContent)))
79+
.map(ea => ({name: ea[0], description: ea[1], type: ea[2], operations: ea[3]}))) : []
80+
}
81+
82+
static async allSchemas() {
83+
var all = {}
84+
for (var ea of ["affiliation","author","conference-instance","conference-series","field-of-study","journal","paper"]) {
85+
var list = await this.generateSchema(ea)
86+
var obj = {}
87+
for(var item of list) {
88+
obj[item.name] = item
89+
}
90+
91+
all[ea] = obj
92+
}
93+
return all
94+
}
95+
96+
static async schemas() {
97+
// window.lively4academicSchemas = null
98+
if (!window.lively4academicSchemas) {
99+
window.lively4academicSchemas = await this.allSchemas()
100+
}
101+
return window.lively4academicSchemas
102+
}
103+
104+
}
105+
106+
107+
108+
export default class AcademicScheme extends Scheme {
109+
110+
get scheme() {
111+
return "academic"
112+
}
113+
114+
resolve() {
115+
return true
116+
}
117+
118+
119+
120+
response(content, contentType="text/html") {
121+
return new Response(content, {
122+
headers: {
123+
"content-type": contentType,
124+
},
125+
status: 200,
126+
})
127+
}
128+
async rawQuery(queryString) {
129+
return await fetch("https://academic.microsoft.com/api/search", {
130+
method: "POST",
131+
headers: {
132+
"content-type": "application/json; charset=utf-8"
133+
},
134+
body: JSON.stringify({
135+
query: queryString,
136+
queryExpression: "",
137+
filters: [],
138+
orderBy: 0,
139+
skip: 0,
140+
sortAscending: true,
141+
attributes: "dn",
142+
take: 1}) // feeling lucky
143+
}).then(r => r.json())
144+
}
145+
146+
async paperQuery(queryString) {
147+
var raw = await this.rawQuery(queryString)
148+
var paper = raw && raw.pr && raw.pr[0] && raw.pr[0].paper
149+
if (paper) {
150+
// does not fit entirely.... shit!
151+
// var schema = (await MicrosoftAcademicEntities.schemas()).paper
152+
return {
153+
type: "paper",
154+
entity: paper,
155+
}
156+
} return {type: "none", error: "no paper found"}
157+
}
158+
159+
160+
161+
async content(queryString) {
162+
var content = `<h2>${this.scheme}: ${queryString}</h2>`
163+
164+
var json = this.paperQuery(queryString)
165+
166+
content += "<pre>" +JSON.stringify(json, undefined, 2) + "</pre>"
167+
return content
168+
}
169+
170+
async GET(options) {
171+
var query = this.url.replace(new RegExp(this.scheme + "\:\/\/"),"")
172+
if (query.length < 2) return this.response(`{"error": "query to short"}`)
173+
174+
175+
176+
if (options && options.headers) {
177+
var headers = new Headers(options.headers) // #Refactor we should unify options before
178+
if (headers.get("content-type") == "application/json") {
179+
var json = await this.paperQuery(query)
180+
return this.response(JSON.stringify(json), "application/json")
181+
}
182+
}
183+
184+
query = decodeURI(query)
185+
var content = await this.content(query)
186+
187+
return this.response(content)
188+
}
189+
190+
async OPTIONS(options) {
191+
var content = JSON.stringify({}, undefined, 2)
192+
return new Response(content, {
193+
headers: {
194+
"content-type": "application/json",
195+
},
196+
status: 200,
197+
})
198+
}
199+
200+
}
201+
202+
PolymorphicIdentifier.register(AcademicScheme)

src/components/tools/lively-inspector.js

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -103,12 +103,14 @@ export default class Inspector extends Morph {
103103
node.appendChild(<span class=''> {obj.name} </span>);
104104
node.appendChild(<span class=''>{truncateString(obj.toString(), 20, '...')}</span>);
105105
} else {
106-
node.appendChild(<a id='tagname' class='tagname'>{className}</a>)
106+
node.appendChild(<a id='tagname' class='tagname'>{
107+
(className !== "Object" && className != "Array") ? className : ""
108+
}</a>)
107109
}
108110
node.appendChild(<span>
109-
<span class="syntax">&#123;</span>{
111+
<span class="syntax">{className == "Array" ? "[" : "{"}</span>{
110112
this.contentTemplate()
111-
}<span class="syntax">&#125;</span>
113+
}<span class="syntax">{className == "Array" ? "]" : "}"}</span>
112114
</span>)
113115

114116
this.attachHandlers(node, obj, name, "renderObject");
@@ -515,7 +517,8 @@ export default class Inspector extends Morph {
515517
// }
516518
keys = allOwn;
517519
if (!this.isAstMode()) {
518-
if (obj && this.allKeys(obj.__proto__).length > 0)
520+
521+
if (obj && this.allKeys(obj.__proto__).length > 0 && (obj.__proto__ !== Object.prototype))
519522
keys.push("__proto__")
520523
}
521524
return _.sortBy(keys)

0 commit comments

Comments
 (0)