Skip to content

Commit 8705bfd

Browse files
committed
Merge pull request #39 from hindessm/more-dropbox-nodes
More dropbox nodes
2 parents abdcdad + 86182a3 commit 8705bfd

File tree

2 files changed

+237
-46
lines changed

2 files changed

+237
-46
lines changed

dropbox/dropbox.html

Lines changed: 88 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,93 @@
6565
})();
6666
</script>
6767

68+
<script type="text/x-red" data-template-name="dropbox in">
69+
<div class="form-row">
70+
<label for="node-input-dropbox"><i class="fa fa-user"></i> Dropbox</label>
71+
<input type="text" id="node-input-dropbox">
72+
</div>
73+
<div class="form-row node-input-filepattern">
74+
<label for="node-input-filepattern"><i class="fa fa-file"></i> Filename Pattern</label>
75+
<input type="text" id="node-input-filepattern" placeholder="Filepattern">
76+
</div>
77+
<div class="form-row">
78+
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
79+
<input type="text" id="node-input-name" placeholder="Name">
80+
</div>
81+
</script>
82+
83+
<script type="text/x-red" data-help-name="dropbox in">
84+
<p>Dropbox watch node. Watches for file events on Dropbox. By
85+
default all file events are reported, but the filename pattern can
86+
be supplied to limit the events to files which have full filenames
87+
that match the glob pattern. The event messages consist of the
88+
full filename in <b>msg.payload</b> property, the filename
89+
in <b>msg.file</b>, the event type in <b>msg.event</b> and
90+
the <a href="https://github.com/dropbox/dropbox-js">dropbox.js</a>
91+
API <a href="http://coffeedoc.info/github/dropbox/dropbox-js/master/classes/Dropbox/Http/PulledChange.html">PulledChange</a>
92+
object in <b>msg.data</b>.</p>
93+
</script>
94+
95+
<script type="text/javascript">
96+
RED.nodes.registerType('dropbox in',{
97+
category: 'storage-input',
98+
color:"#C0DEED",
99+
defaults: {
100+
dropbox: {type:"dropbox-config",required:true},
101+
filepattern: {value:""},
102+
name: {value:""}
103+
},
104+
inputs: 0,
105+
outputs: 1,
106+
icon: "dropbox.png",
107+
label: function() {
108+
return this.name||this.filepattern||'Dropbox';
109+
}
110+
});
111+
</script>
112+
113+
<script type="text/x-red" data-template-name="dropbox">
114+
<div class="form-row">
115+
<label for="node-input-dropbox"><i class="fa fa-user"></i> Dropbox</label>
116+
<input type="text" id="node-input-dropbox">
117+
</div>
118+
<div class="form-row node-input-filename">
119+
<label for="node-input-filename"><i class="fa fa-file"></i> Filename</label>
120+
<input type="text" id="node-input-filename" placeholder="Filename">
121+
</div>
122+
<div class="form-row">
123+
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
124+
<input type="text" id="node-input-name" placeholder="Name">
125+
</div>
126+
</script>
127+
128+
<script type="text/x-red" data-help-name="dropbox">
129+
<p>Dropbox input node. Downloads content from Dropbox. The
130+
filename on Dropbox is taken from the node <b>filename</b>
131+
property or the <b>msg.filename</b> property. The downloaded
132+
content is sent as <b>msg.payload</b> property. If the download
133+
fails <b>msg.error</b> will contain an error object.</p>
134+
</script>
135+
136+
<script type="text/javascript">
137+
RED.nodes.registerType('dropbox',{
138+
category: 'storage-input',
139+
color:"#C0DEED",
140+
defaults: {
141+
dropbox: {type:"dropbox-config",required:true},
142+
filename: {value:""},
143+
name: {value:""}
144+
},
145+
inputs: 1,
146+
outputs: 1,
147+
icon: "dropbox.png",
148+
align: "right",
149+
label: function() {
150+
return this.name||this.filename||'Dropbox';
151+
}
152+
});
153+
</script>
154+
68155
<script type="text/x-red" data-template-name="dropbox out">
69156
<div class="form-row">
70157
<label for="node-input-dropbox"><i class="fa fa-user"></i> Dropbox</label>
@@ -96,7 +183,7 @@
96183
dropbox: {type:"dropbox-config",required:true},
97184
filename: {value:""},
98185
localFilename: {value:""},
99-
name: {value:"Dropbox"}
186+
name: {value:""}
100187
},
101188
inputs:1,
102189
outputs:0,

dropbox/dropbox.js

Lines changed: 149 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -30,58 +30,151 @@ module.exports = function(RED) {
3030
}
3131
});
3232

33+
function DropboxInNode(n) {
34+
RED.nodes.createNode(this,n);
35+
this.filepattern = n.filepattern || "";
36+
this.dropboxConfig = RED.nodes.getNode(n.dropbox);
37+
var credentials = this.dropboxConfig ? this.dropboxConfig.credentials : {};
38+
if (!credentials.appkey || !credentials.appsecret ||
39+
!credentials.accesstoken) {
40+
this.warn("Missing dropbox credentials");
41+
return;
42+
}
43+
44+
var node = this;
45+
var dropbox = new Dropbox.Client({
46+
//uid: credentials.uid,
47+
key: credentials.appkey,
48+
secret: credentials.appsecret,
49+
token: credentials.accesstoken,
50+
});
51+
node.status({fill:"blue",shape:"dot",text:"initializing"});
52+
dropbox.pullChanges(function(err, data) {
53+
if (err) {
54+
node.error("initialization failed " + err.toString());
55+
node.status({fill:"red",shape:"ring",text:"failed"});
56+
return;
57+
}
58+
node.status({});
59+
node.state = data.cursor();
60+
node.on("input", function(msg) {
61+
node.status({fill:"blue",shape:"dot",text:"checking for changes"});
62+
dropbox.pullChanges(node.state, function(err, data) {
63+
if (err) {
64+
node.warn("failed to fetch changes" + err.toString());
65+
node.status({}); // clear status since poll retries anyway
66+
return;
67+
}
68+
node.state = data.cursor();
69+
node.status({});
70+
var changes = data.changes;
71+
for (var i = 0; i < changes.length; i++) {
72+
var change = changes[i];
73+
msg.payload = change.path;
74+
msg.file = change.path.substring(change.path.lastIndexOf('/') + 1);
75+
msg.event = change.wasRemoved ? 'delete' : 'add';
76+
msg.data = change;
77+
node.send(msg);
78+
}
79+
});
80+
});
81+
var interval = setInterval(function() {
82+
node.emit("input", {});
83+
}, 900000); // 15 minutes
84+
node.on("close", function() {
85+
if (interval !== null) {
86+
clearInterval(interval);
87+
}
88+
});
89+
});
90+
}
91+
RED.nodes.registerType("dropbox in",DropboxInNode);
92+
93+
function DropboxQueryNode(n) {
94+
RED.nodes.createNode(this,n);
95+
this.filename = n.filename || "";
96+
this.dropboxConfig = RED.nodes.getNode(n.dropbox);
97+
var credentials = this.dropboxConfig ? this.dropboxConfig.credentials : {};
98+
if (!credentials.appkey || !credentials.appsecret ||
99+
!credentials.accesstoken) {
100+
this.warn("Missing dropbox credentials");
101+
return;
102+
}
103+
104+
var node = this;
105+
var dropbox = new Dropbox.Client({
106+
//uid: credentials.uid,
107+
key: credentials.appkey,
108+
secret: credentials.appsecret,
109+
token: credentials.accesstoken,
110+
});
111+
node.on("input", function(msg) {
112+
var filename = this.filename || msg.filename;
113+
if (filename === "") {
114+
node.warn("No filename specified");
115+
return;
116+
}
117+
msg.filename = filename;
118+
node.status({fill:"blue",shape:"dot",text:"downloading"});
119+
dropbox.readFile(filename, function(err, data) {
120+
if (err) {
121+
node.warn("download failed " + err.toString());
122+
delete msg.payload;
123+
msg.error = err;
124+
} else {
125+
msg.payload = data;
126+
delete msg.error;
127+
}
128+
node.status({});
129+
node.send(msg);
130+
});
131+
});
132+
}
133+
RED.nodes.registerType("dropbox",DropboxQueryNode);
134+
33135
function DropboxOutNode(n) {
34136
RED.nodes.createNode(this,n);
35137
this.filename = n.filename || "";
36138
this.localFilename = n.localFilename || "";
37139
this.dropboxConfig = RED.nodes.getNode(n.dropbox);
38140
var credentials = this.dropboxConfig ? this.dropboxConfig.credentials : {};
141+
if (!credentials.appkey || !credentials.appsecret ||
142+
!credentials.accesstoken) {
143+
this.warn("Missing dropbox credentials");
144+
return;
145+
}
39146
var node = this;
40-
if (credentials.appkey && credentials.appsecret &&
41-
credentials.accesstoken) {
42-
var dropbox = new Dropbox.Client({
43-
//uid: credentials.uid,
44-
key: credentials.appkey,
45-
secret: credentials.appsecret,
46-
token: credentials.accesstoken,
47-
});
48-
node.status({fill:"blue",shape:"dot",text:"checking credentials"});
49-
dropbox.getAccountInfo(function (err) {
50-
if (err) {
51-
node.error("Error verifying credentials: " + err);
52-
node.status({fill:"red",shape:"ring",text:"access denied"});
147+
var dropbox = new Dropbox.Client({
148+
//uid: credentials.uid,
149+
key: credentials.appkey,
150+
secret: credentials.appsecret,
151+
token: credentials.accesstoken,
152+
});
153+
node.status({fill:"blue",shape:"dot",text:"checking credentials"});
154+
dropbox.getAccountInfo(function (err) {
155+
if (err) {
156+
node.error("Error verifying credentials: " + err);
157+
node.status({fill:"red",shape:"ring",text:"access denied"});
158+
return;
159+
}
160+
node.status({});
161+
node.on("input", function(msg) {
162+
var filename = this.filename || msg.filename;
163+
if (filename === "") {
164+
node.warn("No filename specified");
53165
return;
54166
}
55-
node.status({});
56-
node.on("input", function(msg) {
57-
var filename = this.filename || msg.filename;
58-
if (filename === "") {
59-
node.warn("No filename specified");
60-
return;
61-
}
62-
var localFilename = this.localFilename || msg.localFilename;
63-
if (localFilename) {
64-
// TODO: use chunked upload for files larger than 150M
65-
node.status({fill:"blue",shape:"dot",text:"uploading"});
66-
fs.readFile(localFilename, function read(err, data) {
67-
if (err) {
68-
node.error(err.toString());
69-
node.status({fill:"red",shape:"ring",text:"failed"});
70-
return;
71-
}
167+
var localFilename = this.localFilename || msg.localFilename;
168+
if (localFilename) {
169+
// TODO: use chunked upload for files larger than 150M
170+
node.status({fill:"blue",shape:"dot",text:"uploading"});
171+
fs.readFile(localFilename, function read(err, data) {
172+
if (err) {
173+
node.error(err.toString());
174+
node.status({fill:"red",shape:"ring",text:"failed"});
175+
return;
176+
}
72177

73-
dropbox.writeFile(filename, data, function(err) {
74-
if (err) {
75-
node.error(err.toString());
76-
node.status({fill:"red",shape:"ring",text:"failed"});
77-
return;
78-
}
79-
node.status({});
80-
});
81-
});
82-
} else if (typeof msg.payload !== "undefined") {
83-
var data = RED.util.ensureBuffer(msg.payload);
84-
node.status({fill:"blue",shape:"dot",text:"uploading"});
85178
dropbox.writeFile(filename, data, function(err) {
86179
if (err) {
87180
node.error(err.toString());
@@ -90,10 +183,21 @@ module.exports = function(RED) {
90183
}
91184
node.status({});
92185
});
93-
}
94-
});
186+
});
187+
} else if (typeof msg.payload !== "undefined") {
188+
var data = RED.util.ensureBuffer(msg.payload);
189+
node.status({fill:"blue",shape:"dot",text:"uploading"});
190+
dropbox.writeFile(filename, data, function(err) {
191+
if (err) {
192+
node.error(err.toString());
193+
node.status({fill:"red",shape:"ring",text:"failed"});
194+
return;
195+
}
196+
node.status({});
197+
});
198+
}
95199
});
96-
}
200+
});
97201
}
98202
RED.nodes.registerType("dropbox out",DropboxOutNode);
99203
};

0 commit comments

Comments
 (0)