Skip to content

Commit 57fdbac

Browse files
committed
Currently deployed version v10 merged from branch 'develop' into 'master'
Conflicts: README.md
2 parents ffc86c9 + 889fd2b commit 57fdbac

File tree

8 files changed

+355
-133
lines changed

8 files changed

+355
-133
lines changed

Code.gs

Lines changed: 189 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -102,54 +102,35 @@ function getSelectedText() {
102102
}
103103
}
104104

105-
/**
106-
* Fetches the recommendations for the given text.
107-
*
108-
* @param {Array<String>} text for which the recommendations should be fetched
109-
* @return {String} The response as JSON string.
110-
*/
111-
function fetchRecommendations(text) {
112-
return callProxy(getTerms(text));
113-
}
114-
115-
/**
116-
* Gets the recommendations from the selected user text.
117-
*
118-
* @param {Array<String>} text The text entered by the user as array.
119-
*
120-
* @return {Array<String>} The terms as an array.
121-
*/
122-
function getTerms(text) {
123-
var terms = [];
124-
125-
// Split the text into terms
126-
for(t in text) {
127-
var tmp = text[t].split(" ");
128-
for(i in tmp) {
129-
// Replace multiple whitespaces and punctuation marks from the terms
130-
terms.push(tmp[i].replace(/\s/g, "").replace(/[\.,#-\/!$%\^&\*;:{}=\-_`~()]/g,""));
131-
}
132-
}
133-
134-
return terms;
135-
}
105+
var serverUrl = "https://eexcess.joanneum.at/eexcess-privacy-proxy-issuer-1.0-SNAPSHOT/issuer/";
106+
var origin = {
107+
"clientType": "EEXCESS - Google Docs AddOn",
108+
"clientVersion": "8.0", //the deployment version in the webstore
109+
"module": "Sidebar",
110+
"userID": Utilities.computeDigest(Utilities.DigestAlgorithm.SHA_256, Session.getActiveUser().getEmail()).toString() // hash value of uid here: MD5(User-Mail)
111+
};
136112

137113
/**
138-
* Calls the privacy proxy
114+
* Calls the privacy proxy for fetching the recommendations for the given keywords.
139115
*
140-
* @param {Array<String>} terms The single terms.
116+
* @param {Array<String>} keywords The single keywords.
141117
*
142118
* @return {String} The response as JSON string.
143119
*/
144-
function callProxy(terms) {
120+
function fetchRecommendations(keywords) {
145121
// privacy proxy URL
146-
var url = "http://eexcess-dev.joanneum.at/eexcess-privacy-proxy-1.0-SNAPSHOT/api/v1/recommend";
122+
var url = serverUrl + "recommend";
147123

148124
// get result number
149125
var numResults = getResultNumber();
150126

151127
// POST payload
152-
var data = {"numResults": numResults, "partnerList": [], "contextKeywords": []};
128+
var data = {
129+
"numResults": numResults,
130+
"partnerList": [],
131+
"contextKeywords": [],
132+
"origin": origin
133+
};
153134

154135
// set partners
155136
var partners = getPartnerSettings();
@@ -163,15 +144,14 @@ function callProxy(terms) {
163144
}
164145

165146
// Fill the context array
166-
for (i in terms) {
167-
data["contextKeywords"].push({"weight": 1.0 / terms.length, "text": terms[i]});
147+
for (i in keywords) {
148+
data["contextKeywords"].push({"text": keywords[i]});
168149
}
169150

170151
// Options object, that specifies the method, content type and payload of the HTTPRequest
171152
var options = {
172153
"method": "POST",
173154
"contentType": "application/json",
174-
"origin": "gdocs",
175155
"headers": {
176156
"Accept": "application/json"
177157
},
@@ -185,28 +165,46 @@ function callProxy(terms) {
185165
}
186166
}
187167

168+
var DEFAULT_LOCALE = 'en';
169+
188170
/**
189-
* Returns the internationalized message corresponding to the given key. Default language English will be chosen if
190-
* user's locale is not supported.
171+
* Returns the user's current locale. If his locale is not supported the DEFAULT_LOCALE will be chosen.
172+
*
173+
* @returns {String} user's locale
174+
*/
175+
function getLocale() {
176+
var locale = Session.getActiveUserLocale();
177+
178+
if (locale === 'de') {
179+
return locale;
180+
} else { // return default locale
181+
return DEFAULT_LOCALE;
182+
}
183+
}
184+
185+
var messages;
186+
var defaultMessages;
187+
188+
/**
189+
* Returns the internationalized message corresponding to the given key. DEFAULT_LOCALE will be chosen if no translation
190+
* is available for the user's locale.
191191
*
192192
* @param key message's key
193193
* @returns {String} internationalized message
194194
*/
195195
function msg(key) {
196-
if (!this.messages){
197-
var locale = Session.getActiveUserLocale();
198-
var file;
199-
200-
if (locale == 'de') {
201-
file = 'messages_de';
202-
} else { // use default locale 'en'
203-
file = 'messages'
204-
}
196+
if (!messages){
197+
messages = JSON.parse(HtmlService.createTemplateFromFile('messages_' + getLocale()).evaluate().getContent());
198+
defaultMessages = JSON.parse(HtmlService.createTemplateFromFile('messages_' + DEFAULT_LOCALE).evaluate().getContent());
199+
}
200+
201+
var msg = messages[key];
205202

206-
this.messages = JSON.parse(HtmlService.createTemplateFromFile(file).evaluate().getContent());
203+
if (!msg) {
204+
msg = defaultMessages[key];
207205
}
208206

209-
return this.messages[key];
207+
return msg
210208
}
211209

212210
/**
@@ -224,14 +222,22 @@ function openSettingsDialog() {
224222
/**
225223
* Fetches the supported providers from the privacy proxy.
226224
*
227-
* @returns {*} supported providers
225+
* @returns {String} supported providers
228226
*/
229227
function fetchProviders() {
230228
// privacy proxy URL
231-
var url = "http://eexcess-dev.joanneum.at/eexcess-privacy-proxy-1.0-SNAPSHOT/api/v1/getRegisteredPartners";
229+
var url = serverUrl + "getRegisteredPartners";
230+
231+
// Options object, that specifies the method and accepted response type of the HTTPRequest
232+
var options = {
233+
"method": "GET",
234+
"headers": {
235+
"Accept": "application/json"
236+
}
237+
};
232238

233239
try {
234-
var response = UrlFetchApp.fetch(url);
240+
var response = UrlFetchApp.fetch(url, options);
235241
return response.getContentText();
236242
} catch (err) {
237243
throw msg('ERROR');
@@ -288,6 +294,8 @@ function setProperty(key, value) {
288294

289295
/**
290296
* Returns the partner settings.
297+
*
298+
* @returns {String} partner settings
291299
*/
292300
function getPartnerSettings() {
293301
// get all available partners
@@ -347,54 +355,79 @@ function inArray( elem, arr, arrKey) {
347355
return -1;
348356
}
349357

350-
function insertLink(link, displayName) {
358+
/**
359+
* Inserts a link right after the current cursor position/selection and logs this event.
360+
*
361+
* @param displayName link's name to display
362+
* @param documentBadge documentBadge needed for logging containing the link's uri
363+
* @param queryID current query's id needed for logging
364+
*/
365+
function insertLink(displayName, documentBadge, queryID) {
366+
var uri = documentBadge.uri;
367+
351368
var doc = DocumentApp.getActiveDocument();
352-
var body = doc.getBody();
353-
var paragraphIndex;
354369

355370
var cursor = doc.getCursor();
356371
var paragraph;
357372

358373
if (cursor) {
359-
paragraph = cursor.getElement();
374+
var surroundingText = cursor.getSurroundingText().getText();
375+
var surroundingTextOffset = cursor.getSurroundingTextOffset();
376+
377+
cursor.insertText(' ');
378+
379+
var element = cursor.insertText(displayName);
380+
element.setLinkUrl(uri);
381+
382+
// If the cursor follows a non-space character, insert a space and then the link.
383+
if (surroundingTextOffset > 0 && surroundingText.charAt(surroundingTextOffset - 1) != ' ')
384+
cursor.insertText(' ');
385+
386+
return;
360387
}
361388

362389
var selection = doc.getSelection();
363390

364391
if (selection) {
365-
var selectedElements = selection.getSelectedElements();
366-
var selectedElement = selectedElements[0];
392+
var elements = selection.getRangeElements();
393+
var element = elements[elements.length - 1];
367394

368-
//holds the paragraph
369-
var paragraph = selectedElement.getElement();
370-
}
395+
var text = element.getElement().editAsText();
371396

372-
if (paragraph) {
373-
while (paragraph.getType() !== DocumentApp.ElementType.PARAGRAPH) {
374-
paragraph = paragraph.getParent();
375-
}
376-
377-
//get the index of the paragraph in the body
378-
paragraphIndex = body.getChildIndex(paragraph) + 1;
397+
if (text) {
398+
var offset = element.getEndOffsetInclusive() + 1;
379399

380-
body.insertParagraph(paragraphIndex, '').appendText(displayName).setLinkUrl(link);
400+
text.insertText(offset, ' ' + displayName);
401+
text.setLinkUrl(offset + 1, offset + displayName.length, uri);
402+
}
381403
}
404+
405+
logItemCitedAsHyperlink(documentBadge, queryID);
382406
}
383407

384-
function insertImage(uri) {
408+
/**
409+
* Inserts an image specified by its uri to a new paragraph after the current cursor position/selection and logs this
410+
* event.
411+
*
412+
* @param date current date for image citation string
413+
* @param image image's uri
414+
* @param documentBadge documentBadge needed for logging
415+
* @param queryID current query's id needed for logging
416+
*/
417+
function insertImage(date, image, documentBadge, queryID) {
385418
var doc = DocumentApp.getActiveDocument();
386-
var body = doc.getBody();
387-
var img = UrlFetchApp.fetch(uri).getBlob();
388-
var paragraphIndex;
389-
390419
var cursor = doc.getCursor();
391420
var paragraph;
392421

393422
if (cursor) {
394423
paragraph = cursor.getElement();
395424
}
396425

397-
var selection = doc.getSelection();
426+
var selection;
427+
428+
if (!paragraph) {
429+
selection = doc.getSelection();
430+
}
398431

399432
if (selection) {
400433
var selectedElements = selection.getSelectedElements();
@@ -410,8 +443,84 @@ function insertImage(uri) {
410443
}
411444

412445
//get the index of the paragraph in the body
413-
paragraphIndex = body.getChildIndex(paragraph) + 1;
446+
var body = doc.getBody();
447+
var paragraphIndex = body.getChildIndex(paragraph) + 1;
448+
449+
// insert image
450+
var insertedParagraph = body.insertParagraph(paragraphIndex, '');
451+
var img = UrlFetchApp.fetch(image).getBlob();
452+
insertedParagraph.appendInlineImage(img);
453+
454+
// insert citation with current date
455+
insertedParagraph.appendText('\r' + msg('CITATION_IMAGE_RETRIEVED') + " " + date + " " + msg('CITATION_IMAGE_AT') + " ");
456+
insertedParagraph.appendText(image).setLinkUrl(image);
457+
}
458+
459+
logItemCitedAsImage(documentBadge, queryID);
460+
}
461+
462+
/**
463+
* Logs that the given item was opened by the user.
464+
*
465+
* @param documentBadge item's document badge
466+
* @param queryID current query's id
467+
*/
468+
function logItemOpened(documentBadge, queryID) {
469+
logEvent("itemOpened", documentBadge, queryID);
470+
}
471+
472+
/**
473+
* Logs that the given item was cited in a document as image.
474+
*
475+
* @param documentBadge item's document badge
476+
* @param queryID current query's id
477+
*/
478+
function logItemCitedAsImage(documentBadge, queryID) {
479+
logEvent("itemCitedAsImage", documentBadge, queryID);
480+
}
481+
482+
/**
483+
* Logs that the given item was cited in a document as hyperlink.
484+
*
485+
* @param documentBadge item's document badge
486+
* @param queryID current query's id
487+
*/
488+
function logItemCitedAsHyperlink(documentBadge, queryID) {
489+
logEvent("itemCitedAsHyperlink", documentBadge, queryID);
490+
}
491+
492+
/**
493+
* Logs a given event for a specified item.
494+
*
495+
* @param event event's name to complete the server url
496+
* @param documentBadge item's document badge
497+
* @param queryID current query's id
498+
*/
499+
function logEvent(event, documentBadge, queryID) {
500+
// privacy proxy URL
501+
var url = serverUrl + "log/" + event;
502+
503+
// POST payload
504+
var data = {
505+
"content": {
506+
"documentBadge": documentBadge
507+
},
508+
"origin": origin,
509+
"queryID": queryID
510+
};
414511

415-
body.insertParagraph(paragraphIndex, '').appendInlineImage(img);
512+
// Options object, that specifies the method, content type and payload of the HTTPRequest
513+
var options = {
514+
"method": "POST",
515+
"contentType": "application/json",
516+
"headers": {
517+
"Accept": "application/json"
518+
},
519+
"payload": JSON.stringify(data)
520+
};
521+
try {
522+
UrlFetchApp.fetch(url, options);
523+
} catch (err) {
524+
// suppress error -> not relevant for end user
416525
}
417526
}

0 commit comments

Comments
 (0)