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 )
0 commit comments