mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2024-12-24 17:10:29 +00:00
Add basic support for traveltime.com isochrone API
This commit is contained in:
parent
15f266a01f
commit
d2607489b6
@ -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,99 @@ 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 || {};
|
||||
this.wiki = options.wiki || $tw.wiki;
|
||||
}
|
||||
|
||||
HttpClient.prototype.handleHttpRequest = function(event) {
|
||||
console.log("Making an HTTP request",event)
|
||||
var self = this,
|
||||
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-",
|
||||
PASSWORD_HEADER_PARAMETER_PREFIX = "password-header-",
|
||||
CONTEXT_VARIABLE_PARAMETER_PREFIX = "var-",
|
||||
requestHeaders = {},
|
||||
contextVariables = {},
|
||||
setBinding = function(title,text) {
|
||||
if(title) {
|
||||
self.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 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_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;
|
||||
}
|
||||
});
|
||||
$tw.utils.httpRequest({
|
||||
url: url,
|
||||
type: method,
|
||||
headers: requestHeaders,
|
||||
data: paramObject.body,
|
||||
callback: function(err,data,xhr) {
|
||||
var headers = {};
|
||||
$tw.utils.each(xhr.getAllResponseHeaders().split("\r\n"),function(line) {
|
||||
var parts = line.split(":");
|
||||
if(parts.length === 2) {
|
||||
headers[parts[0].toLowerCase()] = parts[1].trim();
|
||||
}
|
||||
});
|
||||
setBinding(bindStatus,xhr.status === 200 ? "complete" : "error");
|
||||
setBinding(bindProgress,"100");
|
||||
var results = {
|
||||
status: xhr.status.toString(),
|
||||
statusText: xhr.statusText,
|
||||
error: (err || "").toString(),
|
||||
data: (data || "").toString(),
|
||||
headers: JSON.stringify(headers)
|
||||
};
|
||||
$tw.rootWidget.invokeActionString(completionActions,undefined,undefined,$tw.utils.extend({},contextVariables,results));
|
||||
// console.log("Back!",err,data,xhr);
|
||||
},
|
||||
progress: function(lengthComputable,loaded,total) {
|
||||
if(lengthComputable) {
|
||||
setBinding(bindProgress,"" + Math.floor((loaded/total) * 100))
|
||||
}
|
||||
$tw.rootWidget.invokeActionString(progressActions,undefined,undefined,{
|
||||
lengthComputable: lengthComputable ? "yes" : "no",
|
||||
loaded: loaded,
|
||||
total: total
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
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 +171,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 +192,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) {
|
||||
|
@ -0,0 +1,43 @@
|
||||
caption: tm-http-request
|
||||
created: 20220908161746341
|
||||
modified: 20220908161746341
|
||||
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 |
|
||||
|header-* |Headers with string values|
|
||||
|password-header-* |Headers 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 |
|
@ -1,5 +1,6 @@
|
||||
title: $:/plugins/geospatial/demo/features/us-states
|
||||
type: application/json
|
||||
tags: $:/tags/GeoLayer
|
||||
|
||||
{"type":"FeatureCollection","features":[
|
||||
{"type":"Feature","id":"01","properties":{"name":"Alabama","density":94.65},"geometry":{"type":"Polygon","coordinates":[[[-87.359296,35.00118],[-85.606675,34.984749],[-85.431413,34.124869],[-85.184951,32.859696],[-85.069935,32.580372],[-84.960397,32.421541],[-85.004212,32.322956],[-84.889196,32.262709],[-85.058981,32.13674],[-85.053504,32.01077],[-85.141136,31.840985],[-85.042551,31.539753],[-85.113751,31.27686],[-85.004212,31.003013],[-85.497137,30.997536],[-87.600282,30.997536],[-87.633143,30.86609],[-87.408589,30.674397],[-87.446927,30.510088],[-87.37025,30.427934],[-87.518128,30.280057],[-87.655051,30.247195],[-87.90699,30.411504],[-87.934375,30.657966],[-88.011052,30.685351],[-88.10416,30.499135],[-88.137022,30.318396],[-88.394438,30.367688],[-88.471115,31.895754],[-88.241084,33.796253],[-88.098683,34.891641],[-88.202745,34.995703],[-87.359296,35.00118]]]}},
|
||||
|
11
plugins/tiddlywiki/geospatial/demo/maps.tid
Normal file
11
plugins/tiddlywiki/geospatial/demo/maps.tid
Normal file
@ -0,0 +1,11 @@
|
||||
title: $:/plugins/tiddlywiki/geospatial/demo/maps
|
||||
caption: Maps
|
||||
tags: $:/tags/GeospatialDemo
|
||||
|
||||
! Map with Layers and Markers
|
||||
|
||||
<$geomap
|
||||
markers="[all[tiddlers+shadows]tag[$:/tags/GeoMarker]]"
|
||||
layers="[all[tiddlers+shadows]tag[$:/tags/GeoLayer]]"
|
||||
/>
|
||||
|
92
plugins/tiddlywiki/geospatial/demo/traveltime.tid
Normal file
92
plugins/tiddlywiki/geospatial/demo/traveltime.tid
Normal file
@ -0,0 +1,92 @@
|
||||
title: $:/plugins/tiddlywiki/geospatial/demo/traveltime
|
||||
caption: Traveltime
|
||||
tags: $:/tags/GeospatialDemo
|
||||
|
||||
\define completion-actions()
|
||||
<$action-log/>
|
||||
<$action-setfield $tiddler="$:/temp/_StatusCode" text=<<status>>/>
|
||||
<$action-setfield $tiddler="$:/temp/_StatusText" text=<<statusText>>/>
|
||||
<$action-setfield $tiddler="$:/temp/_Error" text=<<error>>/>
|
||||
<$action-setfield $tiddler="$:/temp/_Result" text=<<data>>/>
|
||||
<$action-setfield $tiddler="$:/temp/_Headers" text=<<headers>>/>
|
||||
<$list filter="[<status>match[200]]" variable="ignore">
|
||||
<$action-setfield $tiddler="$:/temp/_IsochroneLayer" text={{{ [<data>] }}} tags="$:/tags/GeoLayer"/>
|
||||
</$list>
|
||||
\end
|
||||
|
||||
\define progress-actions()
|
||||
<$action-log message="In progress-actions"/>
|
||||
<$action-log/>
|
||||
\end
|
||||
|
||||
\define payload-source()
|
||||
\rules only transcludeinline transcludeblock filteredtranscludeinline filteredtranscludeblock
|
||||
{
|
||||
"departure_searches": [
|
||||
{
|
||||
"id": "My first isochrone",
|
||||
"coords": {
|
||||
"lat": 51.507609,
|
||||
"lng": -0.128315
|
||||
},
|
||||
"departure_time": "2021-09-27T08:00:00Z",
|
||||
"travel_time": 3600,
|
||||
"transportation": {
|
||||
"type": "driving"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
\end
|
||||
|
||||
\define get-traveltime-actions()
|
||||
<$wikify name="payload" text=<<payload-source>>>
|
||||
<$action-log $message="Making payload"/>
|
||||
<$action-log/>
|
||||
<$action-sendmessage
|
||||
$message="tm-http-request"
|
||||
url="https://api.traveltimeapp.com/v4/time-map"
|
||||
method="POST"
|
||||
header-accept="application/geo+json"
|
||||
header-Content-Type="application/json"
|
||||
password-header-X-Api-Key="traveltime-secret-key"
|
||||
password-header-X-Application-Id="traveltime-application-id"
|
||||
body=<<payload>>
|
||||
var-context="Context string"
|
||||
bind-status="$:/temp/plugins/tiddlywiki/geospatial/demo/traveltime/status"
|
||||
bind-progress="$:/temp/plugins/tiddlywiki/geospatial/demo/traveltime/progress"
|
||||
oncompletion=<<completion-actions>>
|
||||
onprogress=<<progress-actions>>
|
||||
/>
|
||||
</$wikify>
|
||||
\end
|
||||
|
||||
|
||||
|
||||
<$button actions=<<get-traveltime-actions>>>
|
||||
Call ~TravelTime
|
||||
</$button>
|
||||
|
||||
Status:
|
||||
<pre><code><$text text={{$:/temp/plugins/tiddlywiki/geospatial/demo/traveltime/status}}/></code></pre>
|
||||
|
||||
Progress:
|
||||
<pre><code><$text text={{$:/temp/plugins/tiddlywiki/geospatial/demo/traveltime/progress}}/></code></pre>
|
||||
|
||||
Response
|
||||
|
||||
~StatusCode:
|
||||
<pre><code><$text text={{$:/temp/_StatusCode}}/></code></pre>
|
||||
|
||||
~StatusText:
|
||||
<pre><code><$text text={{$:/temp/_StatusText}}/></code></pre>
|
||||
|
||||
Error:
|
||||
<pre><code><$text text={{$:/temp/_Error}}/></code></pre>
|
||||
|
||||
Headers:
|
||||
<pre><code><$text text={{$:/temp/_Headers}}/></code></pre>
|
||||
|
||||
Result:
|
||||
<pre><code><$text text={{$:/temp/_Result}}/></code></pre>
|
||||
|
@ -2,5 +2,5 @@
|
||||
"title": "$:/plugins/tiddlywiki/geospatial",
|
||||
"name": "Geospatial Utilities",
|
||||
"description": "Geospatial utilities",
|
||||
"list": "readme license"
|
||||
"list": "readme settings license"
|
||||
}
|
||||
|
@ -1,11 +1,5 @@
|
||||
title: $:/plugins/tiddlywiki/geospatial/readme
|
||||
|
||||
! Examples
|
||||
! Demos
|
||||
|
||||
!! Simple Map
|
||||
|
||||
<$geomap/>
|
||||
|
||||
!! Map with Markers
|
||||
|
||||
<$geomap markers="[all[tiddlers+shadows]tag[$:/tags/GeoMarker]]"/>
|
||||
<<tabs tabsList:"[all[tiddlers+shadows]tag[$:/tags/GeospatialDemo]]" default:"$:/plugins/tiddlywiki/geospatial/demo/traveltime">>
|
||||
|
15
plugins/tiddlywiki/geospatial/settings.tid
Normal file
15
plugins/tiddlywiki/geospatial/settings.tid
Normal file
@ -0,0 +1,15 @@
|
||||
title: $:/plugins/tiddlywiki/geospatial/settings
|
||||
tags: $:/tags/ControlPanel
|
||||
caption: Geospatial Plugin
|
||||
|
||||
<div class="tc-control-panel">
|
||||
|
||||
! Geospatial Plugin Settings
|
||||
|
||||
Register for a free account at https://traveltime.com/ and copy and paste the secrets below:
|
||||
|
||||
~TravelTime Application ID: <$password name="traveltime-application-id"/>
|
||||
|
||||
~TravelTime Secret Key: <$password name="traveltime-secret-key"/>
|
||||
|
||||
</div>
|
@ -56,6 +56,8 @@ GeomapWidget.prototype.renderMap = function(domNode) {
|
||||
maxZoom: 19,
|
||||
attribution: '© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
|
||||
}).addTo(map);
|
||||
// Disable Leaflet attribution
|
||||
map.attributionControl.setPrefix("");
|
||||
// Create default icon
|
||||
const iconProportions = 365/560,
|
||||
iconHeight = 50;
|
||||
@ -67,12 +69,18 @@ GeomapWidget.prototype.renderMap = function(domNode) {
|
||||
});
|
||||
// Add scale
|
||||
L.control.scale().addTo(map);
|
||||
// Add US states overlay
|
||||
const layer = L.geoJSON($tw.utils.parseJSONSafe(self.wiki.getTiddlerText("$:/plugins/geospatial/demo/features/us-states"),[])).addTo(map);
|
||||
// Create markers
|
||||
// Add overlays
|
||||
if(this.geomapLayerFilter) {
|
||||
$tw.utils.each(this.wiki.filterTiddlers(this.geomapLayerFilter),function(title) {
|
||||
var tiddler = self.wiki.getTiddler(title);
|
||||
if(tiddler) {
|
||||
var layer = L.geoJSON($tw.utils.parseJSONSafe(tiddler.fields.text || "[]",[])).addTo(map);
|
||||
}
|
||||
});
|
||||
}
|
||||
// Add markers
|
||||
if(this.geomapMarkerFilter) {
|
||||
var titles = this.wiki.filterTiddlers(this.geomapMarkerFilter);
|
||||
$tw.utils.each(titles,function(title) {
|
||||
$tw.utils.each(this.wiki.filterTiddlers(this.geomapMarkerFilter),function(title) {
|
||||
var tiddler = self.wiki.getTiddler(title);
|
||||
if(tiddler) {
|
||||
var lat = $tw.utils.parseNumber(tiddler.fields.lat || "0"),
|
||||
@ -89,6 +97,7 @@ GeomapWidget.prototype.renderMap = function(domNode) {
|
||||
Compute the internal state of the widget
|
||||
*/
|
||||
GeomapWidget.prototype.execute = function() {
|
||||
this.geomapLayerFilter = this.getAttribute("layers");
|
||||
this.geomapMarkerFilter = this.getAttribute("markers");
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user