@@ -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