mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2024-07-06 20:14:22 +00:00
Initial Commit
This commit is contained in:
parent
1cac177211
commit
585c7339de
|
@ -20,6 +20,11 @@ exports.before = ["story"];
|
|||
exports.synchronous = true;
|
||||
|
||||
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
|
||||
$tw.modal = new $tw.utils.Modal($tw.wiki);
|
||||
$tw.rootWidget.addEventListener("tm-modal",function(event) {
|
||||
|
|
|
@ -3,7 +3,7 @@ title: $:/core/modules/utils/dom/http.js
|
|||
type: application/javascript
|
||||
module-type: utils
|
||||
|
||||
Browser HTTP support
|
||||
HTTP support
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
@ -13,11 +13,127 @@ Browser HTTP support
|
|||
"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
|
||||
headers: hashmap of headers to send
|
||||
type: GET, PUT, POST etc
|
||||
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
|
||||
*/
|
||||
exports.httpRequest = function(options) {
|
||||
|
@ -83,8 +199,16 @@ exports.httpRequest = function(options) {
|
|||
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
|
||||
request.open(type,url,true);
|
||||
// Headers
|
||||
if(headers) {
|
||||
$tw.utils.each(headers,function(header,headerTitle,object) {
|
||||
request.setRequestHeader(headerTitle,header);
|
||||
|
@ -96,6 +220,7 @@ exports.httpRequest = function(options) {
|
|||
if(!hasHeader("X-Requested-With") && !isSimpleRequest(type,headers)) {
|
||||
request.setRequestHeader("X-Requested-With","TiddlyWiki");
|
||||
}
|
||||
// Send data
|
||||
try {
|
||||
request.send(data);
|
||||
} catch(e) {
|
||||
|
@ -104,4 +229,19 @@ exports.httpRequest = function(options) {
|
|||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
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
|
||||
*/
|
||||
|
|
|
@ -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