Skip to content

Commit b53844e

Browse files
committed
Merge pull request #45 from hbeeken/rename-swarm
[wip] Refactoring credentials into foursquare-credentials
2 parents dc605c1 + b1530c1 commit b53844e

File tree

10 files changed

+724
-663
lines changed

10 files changed

+724
-663
lines changed

Diff for: foursquare/foursquare.html

+155
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
<!--
2+
Copyright 2014 IBM Corp.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
-->
16+
17+
<script type="text/x-red" data-template-name="foursquare-credentials">
18+
<div id="node-config-foursquare-app-keys">
19+
<div class="form-row">
20+
<p style="margin-top: 10px;"><b>1.</b> Create your own app at <a href="https://foursquare.com/developers/apps" target="_blank" style="text-decoration:underline;">foursquare.com</a></p>
21+
</div>
22+
<div class="form-tips" id="node-config-foursquare-tooltip">
23+
</div>
24+
<div class="form-row">
25+
<p style="margin-top: 10px;"><b>2.</b> Copy the app details here:</p>
26+
</div>
27+
<div class="form-row">
28+
<label style="margin-left: 10px; margin-right: -10px;" for="node-config-input-client_id"><i class="fa fa-user"></i> Client ID</label>
29+
<input type="password" id="node-config-input-client_id">
30+
</div>
31+
<div class="form-row">
32+
<label style="margin-left: 10px; margin-right: -10px;" for="node-config-input-client_secret"><i class="fa fa-key"></i> Client Secret</label>
33+
<input type="password" id="node-config-input-client_secret">
34+
</div>
35+
<div class="form-row">
36+
<label>&nbsp;</label>
37+
<a class="btn" id="node-config-start-auth" href="#" target="_blank">Authenticate with Foursquare</a>
38+
</div>
39+
</div>
40+
<div id="node-config-foursquare-user">
41+
<div class="form-row">
42+
<label><i class="fa fa-user"></i> Foursquare User</label><span id="node-config-foursquare-displayname" class="input-xlarge uneditable-input"></span>
43+
</div>
44+
<input type="hidden" id="node-config-input-displayname">
45+
</div>
46+
</script>
47+
48+
<script type="text/javascript">
49+
(function() {
50+
RED.nodes.registerType('foursquare-credentials',{
51+
category: 'config',
52+
defaults: {
53+
displayname: {value:""}
54+
},
55+
credentials: {
56+
displayname: {type:"text", required: true},
57+
clientid: {type:"password",required:true},
58+
clientsecret: {type: "password",required:true},
59+
accesstoken: {type: "password", required:true}
60+
},
61+
label: function() {
62+
return this.displayname;
63+
},
64+
exportable: false,
65+
oneditprepare: function() {
66+
var id = this.id;
67+
68+
var pathname = document.location.pathname;
69+
if (pathname.slice(-1) != "/") {
70+
pathname += "/";
71+
}
72+
var callback = location.protocol + "//" +
73+
location.hostname + ":" + location.port +
74+
pathname + "foursquare-credentials";
75+
$("#node-config-foursquare-tooltip").html("<p>Please configure the authorized <b>Redirect URIs</b> of your app to include the following url:</p>\n<code>"+callback+"</code>");
76+
77+
function updateFoursquareAuthButton() {
78+
var v1 = $("#node-config-input-client_id").val();
79+
var v2 = $("#node-config-input-client_secret").val();
80+
$("#node-config-start-auth").toggleClass("disabled",(v1.length === 0 || v2.length === 0));
81+
}
82+
$("#node-config-input-client_id").on('change keydown paste input',updateFoursquareAuthButton);
83+
$("#node-config-input-client_secret").on('change keydown paste input',updateFoursquareAuthButton);
84+
85+
function updateFoursquareScreenName(sn) {
86+
$("#node-config-foursquare-app-keys").hide();
87+
$("#node-config-foursquare-user").show();
88+
$("#node-config-input-displayname").val(sn);
89+
$("#node-config-foursquare-displayname").html(sn);
90+
}
91+
92+
function pollFoursquareCredentials(e) {
93+
$.getJSON('credentials/foursquare-credentials/'+id,function(data) {
94+
if (data.displayname) {
95+
$("#node-config-dialog-ok").button("enable");
96+
updateFoursquareScreenName(data.displayname);
97+
delete window.foursquareConfigNodeIntervalId;
98+
} else {
99+
window.foursquareConfigNodeIntervalId = window.setTimeout(pollFoursquareCredentials,2000);
100+
}
101+
});
102+
}
103+
104+
updateFoursquareAuthButton();
105+
106+
if (this.displayname) {
107+
updateFoursquareScreenName(this.displayname);
108+
} else {
109+
$("#node-config-foursquare-app-keys").show();
110+
$("#node-config-foursquare-user").hide();
111+
$("#node-config-dialog-ok").button("disable");
112+
}
113+
114+
$("#node-config-start-auth").mousedown(function(e) {
115+
var client_id = $("#node-config-input-client_id").val();
116+
var client_secret = $("#node-config-input-client_secret").val();
117+
var pathname = document.location.pathname;
118+
if (pathname.slice(-1) != "/") {
119+
pathname += "/";
120+
}
121+
var callback = encodeURIComponent(location.protocol+"//"+location.hostname+":"+location.port+pathname+"foursquare-credentials/auth/callback");
122+
var url = 'foursquare-credentials/auth?id='+id+'&callback='+callback+'&clientid='+client_id+"&clientsecret="+client_secret;
123+
$(this).attr("href",url);
124+
window.foursquareConfigNodeIntervalId = window.setTimeout(pollFoursquareCredentials,2000);
125+
});
126+
$("#node-config-start-auth").click(function(e) {
127+
var key = $("#node-config-input-client_id").val();
128+
var secret = $("#node-config-input-client_secret").val();
129+
if (key === "" || secret === "") {
130+
e.preventDefault();
131+
}
132+
});
133+
134+
},
135+
136+
oneditsave: function() {
137+
if (window.foursquareConfigNodeIntervalId) {
138+
window.clearTimeout(window.foursquareConfigNodeIntervalId);
139+
delete window.foursquareConfigNodeIntervalId;
140+
}
141+
},
142+
oneditcancel: function(adding) {
143+
if (window.foursquareConfigNodeIntervalId) {
144+
window.clearTimeout(window.foursquareConfigNodeIntervalId);
145+
delete window.foursquareConfigNodeIntervalId;
146+
}
147+
}
148+
149+
});
150+
})();
151+
</script>
152+
153+
154+
155+

Diff for: swarm/swarm.js renamed to foursquare/foursquare.js

+4-110
Original file line numberDiff line numberDiff line change
@@ -32,126 +32,20 @@ module.exports = function(RED) {
3232
);
3333
}
3434

35-
36-
function SwarmNode(n) {
35+
function FoursquareNode(n) {
3736
RED.nodes.createNode(this,n);
3837
}
3938

40-
RED.nodes.registerType("swarm-credentials", SwarmNode, {
39+
RED.nodes.registerType("foursquare-credentials", FoursquareNode, {
4140
credentials: {
4241
displayname: {type: "text"},
4342
clientid: {type: "password"},
4443
clientsecret: {type: "password"},
4544
accesstoken: {type: "password"}
4645
}
4746
});
48-
49-
/**
50-
* Swarm input node - will return the most recent check-in since
51-
* the node has been initialized. The node will only populate msg.payload
52-
* with the JSON of the check-in if a new check-in has been made within
53-
* the polling interval.
54-
*/
55-
function SwarmInNode(n) {
56-
RED.nodes.createNode(this, n);
57-
var credentials = RED.nodes.getCredentials(n.swarm);
58-
var node = this;
59-
var credentialsOk = checkCredentials(node, credentials);
60-
if (credentialsOk) {
61-
var repeat = 900000; // 15 mins
62-
var now = Math.floor(((new Date()).getTime())/1000); // time now in seconds since epoch
63-
var afterTimestamp = now;
64-
var lastcheckin = null;
65-
66-
var interval = setInterval(function() {
67-
node.emit("input", {});
68-
}, repeat );
69-
70-
this.on("input", function(msg) {
71-
getCheckinsAfterTimestamp(node, "self", afterTimestamp, credentials, msg, function(msg) {
72-
var latestcheckin = JSON.stringify(msg);
73-
if (latestcheckin != lastcheckin) {
74-
lastcheckin = latestcheckin;
75-
afterTimestamp = msg.payload.createdAt;
76-
node.send(msg);
77-
}
78-
});
79-
});
80-
81-
this.on("close", function() {
82-
if (interval != null) {
83-
clearInterval(interval);
84-
}
85-
});
86-
87-
}
88-
}
89-
90-
RED.nodes.registerType("swarm in", SwarmInNode);
91-
92-
/**
93-
* Swarm query node - will return the most recent check-in since
94-
* the node has been initialized. If a check-in exists the node will always return
95-
* the most recent even if no new check-ins have happened since the previous query.
96-
* The node only populates msg.payload when a check-in is found.
97-
*/
98-
function SwarmQueryNode(n) {
99-
RED.nodes.createNode(this, n);
100-
var node = this;
101-
this.request = n.request || "get-most-recent-checkin";
102-
var credentials = RED.nodes.getCredentials(n.swarm);
103-
var credentialsOk = checkCredentials(node, credentials);
104-
if (credentialsOk) {
105-
var now = Math.floor(((new Date()).getTime())/1000); // time now in seconds since epoch (rounded down)
106-
var afterTimestamp = now;
107-
108-
this.on("input", function(msg) {
109-
if (node.request === "get-most-recent-checkin") {
110-
getCheckinsAfterTimestamp(node, "self", afterTimestamp, credentials, msg, function(msg) {
111-
afterTimestamp = msg.payload.createdAt - 2;
112-
node.send(msg);
113-
});
114-
}
115-
});
116-
}
117-
}
118-
119-
RED.nodes.registerType("swarm", SwarmQueryNode);
120-
121-
function checkCredentials(node, credentials) {
122-
if (credentials && credentials.clientid && credentials.clientsecret && credentials.accesstoken) {
123-
return true;
124-
} else {
125-
node.error("problem with credentials being set: " + credentials + ", ");
126-
node.status({fill:"red",shape:"ring",text:"failed"});
127-
return false;
128-
}
129-
}
130-
131-
function getCheckinsAfterTimestamp(node, userid, afterTimestamp, credentials, msg, callback) {
132-
var apiUrl = "https://api.foursquare.com/v2/users/" + userid + "/checkins?oauth_token=" + credentials.accesstoken + "&v=20141016&afterTimestamp=" + afterTimestamp+"&sort=newestfirst";
133-
request.get(apiUrl,function(err, httpResponse, body) {
134-
if (err) {
135-
node.error(err.toString());
136-
node.status({fill:"red",shape:"ring",text:"failed"});
137-
} else {
138-
var result = JSON.parse(body);
139-
if (result.meta.code != 200) {
140-
node.error("Error code: " + result.meta.code + ", errorDetail: " + result.meta.errorDetail);
141-
node.status({fill:"red",shape:"ring",text:"failed"});
142-
} else {
143-
if (result.response.checkins.items.length !== 0) {
144-
var latest = result.response.checkins.items[0];
145-
msg.payload = {};
146-
msg.payload = latest;
147-
callback(msg);
148-
}
149-
}
150-
}
151-
});
152-
}
15347

154-
RED.httpAdmin.get('/swarm-credentials/auth', function(req, res){
48+
RED.httpAdmin.get('/foursquare-credentials/auth', function(req, res){
15549
if (!req.query.clientid || !req.query.clientsecret || !req.query.id || !req.query.callback) {
15650
return res.status(400).send('ERROR: request does not contain the required parameters');
15751
}
@@ -175,7 +69,7 @@ module.exports = function(RED) {
17569
res.redirect(url);
17670
});
17771

178-
RED.httpAdmin.get('/swarm-credentials/auth/callback', function(req, res){
72+
RED.httpAdmin.get('/foursquare-credentials/auth/callback', function(req, res){
17973
if (req.query.error) {
18074
return res.send("ERROR: " + req.query.error + ": " + req.query.error_description);
18175
}
File renamed without changes.

0 commit comments

Comments
 (0)