mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2024-10-23 02:55:48 +00:00
Initial Commit
This commit is contained in:
parent
1cac177211
commit
585c7339de
@ -20,6 +20,11 @@ exports.before = ["story"];
|
|||||||
exports.synchronous = true;
|
exports.synchronous = true;
|
||||||
|
|
||||||
exports.startup = function() {
|
exports.startup = function() {
|
||||||
|
// Install the HTTP client event handler
|
||||||
|
$tw.httpClient = new $tw.utils.HttpClient();
|
||||||
|
$tw.rootWidget.addEventListener("tm-http-request",function(event) {
|
||||||
|
$tw.httpClient.handleHttpRequest(event);
|
||||||
|
});
|
||||||
// Install the modal message mechanism
|
// Install the modal message mechanism
|
||||||
$tw.modal = new $tw.utils.Modal($tw.wiki);
|
$tw.modal = new $tw.utils.Modal($tw.wiki);
|
||||||
$tw.rootWidget.addEventListener("tm-modal",function(event) {
|
$tw.rootWidget.addEventListener("tm-modal",function(event) {
|
||||||
|
@ -3,7 +3,7 @@ title: $:/core/modules/utils/dom/http.js
|
|||||||
type: application/javascript
|
type: application/javascript
|
||||||
module-type: utils
|
module-type: utils
|
||||||
|
|
||||||
Browser HTTP support
|
HTTP support
|
||||||
|
|
||||||
\*/
|
\*/
|
||||||
(function(){
|
(function(){
|
||||||
@ -13,11 +13,127 @@ Browser HTTP support
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
A quick and dirty HTTP function; to be refactored later. Options are:
|
Manage tm-http-request events. Options are:
|
||||||
|
wiki - the wiki object to use
|
||||||
|
*/
|
||||||
|
function HttpClient(options) {
|
||||||
|
options = options || {};
|
||||||
|
}
|
||||||
|
|
||||||
|
HttpClient.prototype.handleHttpRequest = function(event) {
|
||||||
|
console.log("Initiating an HTTP request",event)
|
||||||
|
var self = this,
|
||||||
|
wiki = event.widget.wiki,
|
||||||
|
paramObject = event.paramObject || {},
|
||||||
|
url = paramObject.url,
|
||||||
|
completionActions = paramObject.oncompletion || "",
|
||||||
|
progressActions = paramObject.onprogress || "",
|
||||||
|
bindStatus = paramObject["bind-status"],
|
||||||
|
bindProgress = paramObject["bind-progress"],
|
||||||
|
method = paramObject.method || "GET",
|
||||||
|
HEADER_PARAMETER_PREFIX = "header-",
|
||||||
|
QUERY_PARAMETER_PREFIX = "query-",
|
||||||
|
PASSWORD_HEADER_PARAMETER_PREFIX = "password-header-",
|
||||||
|
PASSWORD_QUERY_PARAMETER_PREFIX = "password-query-",
|
||||||
|
CONTEXT_VARIABLE_PARAMETER_PREFIX = "var-",
|
||||||
|
requestHeaders = {},
|
||||||
|
contextVariables = {},
|
||||||
|
setBinding = function(title,text) {
|
||||||
|
if(title) {
|
||||||
|
wiki.addTiddler(new $tw.Tiddler({title: title, text: text}));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if(url) {
|
||||||
|
setBinding(bindStatus,"pending");
|
||||||
|
setBinding(bindProgress,"0");
|
||||||
|
$tw.utils.each(paramObject,function(value,name) {
|
||||||
|
// Look for query- parameters
|
||||||
|
if(name.substr(0,QUERY_PARAMETER_PREFIX.length) === QUERY_PARAMETER_PREFIX) {
|
||||||
|
url = $tw.utils.setQueryStringParameter(url,name.substr(QUERY_PARAMETER_PREFIX.length),value);
|
||||||
|
}
|
||||||
|
// Look for header- parameters
|
||||||
|
if(name.substr(0,HEADER_PARAMETER_PREFIX.length) === HEADER_PARAMETER_PREFIX) {
|
||||||
|
requestHeaders[name.substr(HEADER_PARAMETER_PREFIX.length)] = value;
|
||||||
|
}
|
||||||
|
// Look for password-header- parameters
|
||||||
|
if(name.substr(0,PASSWORD_QUERY_PARAMETER_PREFIX.length) === PASSWORD_QUERY_PARAMETER_PREFIX) {
|
||||||
|
url = $tw.utils.setQueryStringParameter(url,name.substr(PASSWORD_QUERY_PARAMETER_PREFIX.length),$tw.utils.getPassword(value) || "");
|
||||||
|
}
|
||||||
|
// Look for password-query- parameters
|
||||||
|
if(name.substr(0,PASSWORD_HEADER_PARAMETER_PREFIX.length) === PASSWORD_HEADER_PARAMETER_PREFIX) {
|
||||||
|
requestHeaders[name.substr(PASSWORD_HEADER_PARAMETER_PREFIX.length)] = $tw.utils.getPassword(value) || "";
|
||||||
|
}
|
||||||
|
// Look for var- parameters
|
||||||
|
if(name.substr(0,CONTEXT_VARIABLE_PARAMETER_PREFIX.length) === CONTEXT_VARIABLE_PARAMETER_PREFIX) {
|
||||||
|
contextVariables[name.substr(CONTEXT_VARIABLE_PARAMETER_PREFIX.length)] = value;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// Set the request tracker tiddler
|
||||||
|
var requestTrackerTitle = wiki.generateNewTitle("$:/temp/HttpRequest");
|
||||||
|
wiki.addTiddler({
|
||||||
|
title: requestTrackerTitle,
|
||||||
|
tags: "$:/tags/HttpRequest",
|
||||||
|
text: JSON.stringify({
|
||||||
|
url: url,
|
||||||
|
type: method,
|
||||||
|
status: "inprogress",
|
||||||
|
headers: requestHeaders,
|
||||||
|
data: paramObject.body
|
||||||
|
})
|
||||||
|
});
|
||||||
|
$tw.utils.httpRequest({
|
||||||
|
url: url,
|
||||||
|
type: method,
|
||||||
|
headers: requestHeaders,
|
||||||
|
data: paramObject.body,
|
||||||
|
callback: function(err,data,xhr) {
|
||||||
|
var success = (xhr.status >= 200 && xhr.status < 300) ? "complete" : "error",
|
||||||
|
headers = {};
|
||||||
|
$tw.utils.each(xhr.getAllResponseHeaders().split("\r\n"),function(line) {
|
||||||
|
var pos = line.indexOf(":");
|
||||||
|
if(pos !== -1) {
|
||||||
|
headers[line.substr(0,pos)] = line.substr(pos + 1).trim();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
setBinding(bindStatus,success);
|
||||||
|
setBinding(bindProgress,"100");
|
||||||
|
var results = {
|
||||||
|
status: xhr.status.toString(),
|
||||||
|
statusText: xhr.statusText,
|
||||||
|
error: (err || "").toString(),
|
||||||
|
data: (data || "").toString(),
|
||||||
|
headers: JSON.stringify(headers)
|
||||||
|
};
|
||||||
|
// Update the request tracker tiddler
|
||||||
|
wiki.addTiddler(new $tw.Tiddler(wiki.getTiddler(requestTrackerTitle),{
|
||||||
|
status: success,
|
||||||
|
}));
|
||||||
|
wiki.invokeActionString(completionActions,undefined,$tw.utils.extend({},contextVariables,results),{parentWidget: $tw.rootWidget});
|
||||||
|
// console.log("Back!",err,data,xhr);
|
||||||
|
},
|
||||||
|
progress: function(lengthComputable,loaded,total) {
|
||||||
|
if(lengthComputable) {
|
||||||
|
setBinding(bindProgress,"" + Math.floor((loaded/total) * 100))
|
||||||
|
}
|
||||||
|
wiki.invokeActionString(progressActions,undefined,{
|
||||||
|
lengthComputable: lengthComputable ? "yes" : "no",
|
||||||
|
loaded: loaded,
|
||||||
|
total: total
|
||||||
|
},{parentWidget: $tw.rootWidget});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.HttpClient = HttpClient;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Make an HTTP request. Options are:
|
||||||
url: URL to retrieve
|
url: URL to retrieve
|
||||||
headers: hashmap of headers to send
|
headers: hashmap of headers to send
|
||||||
type: GET, PUT, POST etc
|
type: GET, PUT, POST etc
|
||||||
callback: function invoked with (err,data,xhr)
|
callback: function invoked with (err,data,xhr)
|
||||||
|
progress: optional function invoked with (lengthComputable,loaded,total)
|
||||||
returnProp: string name of the property to return as first argument of callback
|
returnProp: string name of the property to return as first argument of callback
|
||||||
*/
|
*/
|
||||||
exports.httpRequest = function(options) {
|
exports.httpRequest = function(options) {
|
||||||
@ -83,8 +199,16 @@ exports.httpRequest = function(options) {
|
|||||||
options.callback($tw.language.getString("Error/XMLHttpRequest") + ": " + this.status,null,this);
|
options.callback($tw.language.getString("Error/XMLHttpRequest") + ": " + this.status,null,this);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
// Handle progress
|
||||||
|
if(options.progress) {
|
||||||
|
request.onprogress = function(event) {
|
||||||
|
console.log("Progress event",event)
|
||||||
|
options.progress(event.lengthComputable,event.loaded,event.total);
|
||||||
|
};
|
||||||
|
}
|
||||||
// Make the request
|
// Make the request
|
||||||
request.open(type,url,true);
|
request.open(type,url,true);
|
||||||
|
// Headers
|
||||||
if(headers) {
|
if(headers) {
|
||||||
$tw.utils.each(headers,function(header,headerTitle,object) {
|
$tw.utils.each(headers,function(header,headerTitle,object) {
|
||||||
request.setRequestHeader(headerTitle,header);
|
request.setRequestHeader(headerTitle,header);
|
||||||
@ -96,6 +220,7 @@ exports.httpRequest = function(options) {
|
|||||||
if(!hasHeader("X-Requested-With") && !isSimpleRequest(type,headers)) {
|
if(!hasHeader("X-Requested-With") && !isSimpleRequest(type,headers)) {
|
||||||
request.setRequestHeader("X-Requested-With","TiddlyWiki");
|
request.setRequestHeader("X-Requested-With","TiddlyWiki");
|
||||||
}
|
}
|
||||||
|
// Send data
|
||||||
try {
|
try {
|
||||||
request.send(data);
|
request.send(data);
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
@ -104,4 +229,19 @@ exports.httpRequest = function(options) {
|
|||||||
return request;
|
return request;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
exports.setQueryStringParameter = function(url,paramName,paramValue) {
|
||||||
|
var URL = $tw.browser ? window.URL : require("url").URL,
|
||||||
|
newUrl;
|
||||||
|
try {
|
||||||
|
newUrl = new URL(url);
|
||||||
|
} catch(e) {
|
||||||
|
}
|
||||||
|
if(newUrl && paramName) {
|
||||||
|
newUrl.searchParams.set(paramName,paramValue || "");
|
||||||
|
return newUrl.toString();
|
||||||
|
} else {
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
@ -1415,6 +1415,14 @@ exports.checkTiddlerText = function(title,targetText,options) {
|
|||||||
return text === targetText;
|
return text === targetText;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Execute an action string without an associated context widget
|
||||||
|
*/
|
||||||
|
exports.invokeActionString = function(actions,event,variables,options) {
|
||||||
|
var widget = this.makeWidget(null,{parentWidget: options.parentWidget});
|
||||||
|
widget.invokeActionString(actions,null,event,variables);
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Read an array of browser File objects, invoking callback(tiddlerFieldsArray) once they're all read
|
Read an array of browser File objects, invoking callback(tiddlerFieldsArray) once they're all read
|
||||||
*/
|
*/
|
||||||
|
@ -0,0 +1,112 @@
|
|||||||
|
title: WidgetMessage: tm-http-request Example - Zotero
|
||||||
|
tags: $:/tags/Macro
|
||||||
|
|
||||||
|
\procedure select-zotero-group()
|
||||||
|
Specify the Zotero group ID to import
|
||||||
|
<$edit-text tiddler="$:/config/zotero-group" tag="input"/> or
|
||||||
|
<$select tiddler="$:/config/zotero-group">
|
||||||
|
<option value="4813312">com216</option>
|
||||||
|
<option value="4913310">pos252</option>
|
||||||
|
<option value="4747244">idt575</option>
|
||||||
|
</$select>
|
||||||
|
\end
|
||||||
|
|
||||||
|
\procedure zotero-save-item(item)
|
||||||
|
<$action-createtiddler
|
||||||
|
$basetitle={{{ =[[_zotero_import ]] =[<item>jsonget[key]] =[[ ]] =[<item>jsonget[title]] +[join[]] }}}
|
||||||
|
text={{{ [<item>jsonget[title]] }}}
|
||||||
|
tags="$:/tags/ZoteroImport"
|
||||||
|
>
|
||||||
|
<$action-setmultiplefields $tiddler=<<createTiddler-title>> $fields="[<item>jsonindexes[]addprefix[zotero-]]" $values="[<item>jsonindexes[]] :map[<item>jsonget<currentTiddler>else[.XXXXX.]]"/>
|
||||||
|
<$list filter="[<item>jsonindexes[creators]]" variable="creatorIndex">
|
||||||
|
<$action-setmultiplefields $tiddler=<<createTiddler-title>> $fields="[<item>jsonget[creators],<creatorIndex>,[creatorType]addprefix[zotero-]]" $values="[<item>jsonget[creators],<creatorIndex>,[lastName]] [<item>jsonget[creators],<creatorIndex>,[firstName]] +[join[, ]] :else[<item>jsonget[creators],<creatorIndex>,[name]] "/>
|
||||||
|
</$list>
|
||||||
|
</$action-createtiddler>
|
||||||
|
\end zotero-save-item
|
||||||
|
|
||||||
|
\procedure zotero-save-items(data)
|
||||||
|
<$list filter="[<data>jsonindexes[]] :map[<data>jsonextract<currentTiddler>,[data]]" variable="item">
|
||||||
|
<$macrocall $name="zotero-save-item" item=<<item>>/>
|
||||||
|
</$list>
|
||||||
|
\end zotero-save-items
|
||||||
|
|
||||||
|
\procedure zotero-get-items(start:"0",limit:"25")
|
||||||
|
|
||||||
|
\procedure completion()
|
||||||
|
\import [[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]
|
||||||
|
<$action-log msg="In completion"/>
|
||||||
|
<$action-log/>
|
||||||
|
<!-- Success -->
|
||||||
|
<$list filter="[<status>compare:number:gteq[200]compare:number:lteq[299]]" variable="ignore">
|
||||||
|
<!-- Import these items -->
|
||||||
|
<$macrocall $name="zotero-save-items" data=<<data>>/>
|
||||||
|
<!-- Check if there are any more items to download -->
|
||||||
|
<$list filter="[<headers>jsonget[total-results]subtract<start>subtract<limit>compare:number:gt[0]]" variable="ignore">
|
||||||
|
<$macrocall $name="zotero-get-items" start={{{ [<start>add<limit>] }}} limit=<<limit>>/>
|
||||||
|
</$list>
|
||||||
|
</$list>
|
||||||
|
\end completion
|
||||||
|
|
||||||
|
\procedure progress()
|
||||||
|
\import [[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]
|
||||||
|
<$action-log message="In progress-actions"/>
|
||||||
|
\end progress
|
||||||
|
|
||||||
|
\procedure request-url()
|
||||||
|
\rules only transcludeinline transcludeblock filteredtranscludeinline filteredtranscludeblock
|
||||||
|
https://api.zotero.org/groups/{{$:/config/zotero-group}}/items/
|
||||||
|
\end request-url
|
||||||
|
|
||||||
|
<$wikify name="url" text=<<request-url>>>
|
||||||
|
<$action-sendmessage
|
||||||
|
$message="tm-http-request"
|
||||||
|
url=<<url>>
|
||||||
|
method="GET"
|
||||||
|
query-format="json"
|
||||||
|
query-sort="title"
|
||||||
|
query-start=<<start>>
|
||||||
|
query-limit=<<limit>>
|
||||||
|
header-accept="application/json"
|
||||||
|
bind-status="$:/temp/zotero/status"
|
||||||
|
bind-progress="$:/temp/zotero/progress"
|
||||||
|
oncompletion=<<completion>>
|
||||||
|
onprogress=<<progress>>
|
||||||
|
var-start=<<start>>
|
||||||
|
var-limit=<<limit>>
|
||||||
|
/>
|
||||||
|
</$wikify>
|
||||||
|
\end
|
||||||
|
|
||||||
|
\procedure zotero-actions()
|
||||||
|
<$macrocall $name="zotero-get-items" start="0" limit="50"/>
|
||||||
|
\end
|
||||||
|
|
||||||
|
|
||||||
|
<<select-zotero-group>>
|
||||||
|
|
||||||
|
<$button actions=<<zotero-actions>>>
|
||||||
|
Start import from Zotero group
|
||||||
|
</$button>
|
||||||
|
|
||||||
|
<$list filter="[tag[$:/tags/ZoteroImport]limit[1]]" variable="ignore">
|
||||||
|
|
||||||
|
!! Imported Tiddlers
|
||||||
|
|
||||||
|
<$button>
|
||||||
|
<$action-deletetiddler $filter="[tag[$:/tags/ZoteroImport]]"/>
|
||||||
|
Delete these tiddlers
|
||||||
|
</$button>
|
||||||
|
|
||||||
|
Export: <$macrocall $name="exportButton" exportFilter="[tag[$:/tags/ZoteroImport]]" lingoBase="$:/language/Buttons/ExportTiddlers/"/>
|
||||||
|
|
||||||
|
</$list>
|
||||||
|
|
||||||
|
<ol>
|
||||||
|
<$list filter="[tag[$:/tags/ZoteroImport]]">
|
||||||
|
<li>
|
||||||
|
<$link>
|
||||||
|
<$view field="title"/>
|
||||||
|
</$link>
|
||||||
|
</li>
|
||||||
|
</$list>
|
||||||
|
</ol>
|
@ -0,0 +1,49 @@
|
|||||||
|
caption: tm-http-request
|
||||||
|
created: 20230429161453032
|
||||||
|
modified: 20230429161453032
|
||||||
|
tags: Messages
|
||||||
|
title: WidgetMessage: tm-http-request
|
||||||
|
type: text/vnd.tiddlywiki
|
||||||
|
|
||||||
|
The ''tm-http-request'' message is used to make an HTTP request to a server.
|
||||||
|
|
||||||
|
It uses the following properties on the `event` object:
|
||||||
|
|
||||||
|
|!Name |!Description |
|
||||||
|
|param |Not used |
|
||||||
|
|paramObject |Hashmap of parameters (see below) |
|
||||||
|
|
||||||
|
The following parameters are used:
|
||||||
|
|
||||||
|
|!Name |!Description |
|
||||||
|
|method |HTTP method (eg "GET", "POST") |
|
||||||
|
|body |String data to be sent with the request |
|
||||||
|
|query-* |Query string parameters with string values |
|
||||||
|
|header-* |Headers with string values |
|
||||||
|
|password-header-* |Headers with values taken from the password store |
|
||||||
|
|password-query-* |Query string parameters with values taken from the password store |
|
||||||
|
|var-* |Variables to be passed to the completion and progress handlers (without the "var-" prefix) |
|
||||||
|
|bind-status |Title of tiddler to which the status of the request ("pending", "complete", "error") should be bound |
|
||||||
|
|bind-progress |Title of tiddler to which the progress of the request (0 to 100) should be bound |
|
||||||
|
|oncompletion |Action strings to be executed when the request completes |
|
||||||
|
|onprogress |Action strings to be executed when progress is reported |
|
||||||
|
|
||||||
|
The following variables are passed to the completion handler:
|
||||||
|
|
||||||
|
|!Name |!Description |
|
||||||
|
|status |HTTP result status code (see [[MDN|https://developer.mozilla.org/en-US/docs/Web/HTTP/Status]]) |
|
||||||
|
|statusText |HTTP result status text |
|
||||||
|
|error |Error string |
|
||||||
|
|data |Returned data |
|
||||||
|
|headers |Response headers as a JSON object |
|
||||||
|
|
||||||
|
The following variables are passed to the progress handler:
|
||||||
|
|
||||||
|
|!Name |!Description |
|
||||||
|
|lengthComputable |Whether the progress loaded and total figures are valid - "yes" or "no" |
|
||||||
|
|loaded |Number of bytes loaded so far |
|
||||||
|
|total |Total number bytes to be loaded |
|
||||||
|
|
||||||
|
!! Examples
|
||||||
|
|
||||||
|
* [[Zotero's|https://www.zotero.org/]] API for retrieving reference items: [[WidgetMessage: tm-http-request Example - Zotero]]
|
@ -0,0 +1,2 @@
|
|||||||
|
title: $:/config/zotero-group
|
||||||
|
text: 4813312
|
Loading…
Reference in New Issue
Block a user