From d1569975bb18f4359fac18aa98f55b69c248a3ad Mon Sep 17 00:00:00 2001 From: "Chinthakayala, Sheshashailavas (sc2914)" Date: Mon, 28 Aug 2017 05:25:46 -0900 Subject: [PATCH] [CCSDK-28] populated the seed code for dgbuilder updated the code to point to the new package name for sli Change-Id: I3b5a1d05dc5193664fd4a667afdcd0b2354010a4 Issue-ID:{CCSDK-28} Signed-off-by: Chinthakayala, Sheshashailavas (sc2914) Signed-off-by: Chinthakayala, Sheshashailavas (sc2914) --- dgbuilder/.gitignore | 12 + dgbuilder/CONTRIBUTING.md | 82 + dgbuilder/Gruntfile.js | 91 + dgbuilder/INSTALL.md | 57 + dgbuilder/LICENSE | 177 ++ dgbuilder/build_pom_for_yang_compile | 86 + dgbuilder/core_nodes/analysis/72-sentiment.html | 49 + dgbuilder/core_nodes/analysis/72-sentiment.js | 33 + dgbuilder/core_nodes/core/20-inject.html | 437 +++++ dgbuilder/core_nodes/core/20-inject.js | 97 + dgbuilder/core_nodes/core/58-debug.html | 248 +++ dgbuilder/core_nodes/core/58-debug.js | 114 ++ dgbuilder/core_nodes/core/75-exec.html | 68 + dgbuilder/core_nodes/core/75-exec.js | 84 + dgbuilder/core_nodes/core/80-function.html | 110 ++ dgbuilder/core_nodes/core/80-function.js | 79 + dgbuilder/core_nodes/core/80-template.html | 102 + dgbuilder/core_nodes/core/80-template.js | 61 + dgbuilder/core_nodes/core/89-delay.html | 167 ++ dgbuilder/core_nodes/core/89-delay.js | 171 ++ dgbuilder/core_nodes/core/89-trigger.html | 130 ++ dgbuilder/core_nodes/core/89-trigger.js | 91 + dgbuilder/core_nodes/core/90-comment.html | 86 + dgbuilder/core_nodes/core/90-comment.js | 23 + dgbuilder/core_nodes/core/98-unknown.html | 49 + dgbuilder/core_nodes/core/98-unknown.js | 23 + dgbuilder/core_nodes/deprecated/61-imap.html | 56 + dgbuilder/core_nodes/deprecated/61-imap.js | 139 ++ dgbuilder/core_nodes/deprecated/73-parsexml.html | 53 + dgbuilder/core_nodes/deprecated/73-parsexml.js | 47 + dgbuilder/core_nodes/deprecated/74-js2xml.html | 51 + dgbuilder/core_nodes/deprecated/74-js2xml.js | 39 + dgbuilder/core_nodes/deprecated/90-httpget.html | 61 + dgbuilder/core_nodes/deprecated/90-httpget.js | 53 + dgbuilder/core_nodes/hardware/35-arduino.html | 171 ++ dgbuilder/core_nodes/hardware/35-arduino.js | 160 ++ dgbuilder/core_nodes/hardware/36-rpi-gpio.html | 182 ++ dgbuilder/core_nodes/hardware/36-rpi-gpio.js | 185 ++ dgbuilder/core_nodes/io/10-mqtt.html | 157 ++ dgbuilder/core_nodes/io/10-mqtt.js | 119 ++ dgbuilder/core_nodes/io/21-httpin.html | 254 +++ dgbuilder/core_nodes/io/21-httpin.js | 241 +++ dgbuilder/core_nodes/io/22-websocket.html | 163 ++ dgbuilder/core_nodes/io/22-websocket.js | 185 ++ dgbuilder/core_nodes/io/23-watch.html | 57 + dgbuilder/core_nodes/io/23-watch.js | 51 + dgbuilder/core_nodes/io/25-serial.html | 265 +++ dgbuilder/core_nodes/io/25-serial.js | 310 +++ dgbuilder/core_nodes/io/31-tcpin.html | 299 +++ dgbuilder/core_nodes/io/31-tcpin.js | 472 +++++ dgbuilder/core_nodes/io/32-udp.html | 212 ++ dgbuilder/core_nodes/io/32-udp.js | 171 ++ dgbuilder/core_nodes/io/lib/mqtt.js | 254 +++ dgbuilder/core_nodes/io/lib/mqttConnectionPool.js | 128 ++ dgbuilder/core_nodes/logic/10-switch.html | 198 ++ dgbuilder/core_nodes/logic/10-switch.js | 78 + dgbuilder/core_nodes/logic/15-change.html | 139 ++ dgbuilder/core_nodes/logic/15-change.js | 74 + dgbuilder/core_nodes/logic/16-range.html | 81 + dgbuilder/core_nodes/logic/16-range.js | 48 + dgbuilder/core_nodes/parsers/70-CSV.html | 123 ++ dgbuilder/core_nodes/parsers/70-CSV.js | 157 ++ dgbuilder/core_nodes/parsers/70-HTML.html | 73 + dgbuilder/core_nodes/parsers/70-HTML.js | 60 + dgbuilder/core_nodes/parsers/70-JSON.html | 47 + dgbuilder/core_nodes/parsers/70-JSON.js | 46 + dgbuilder/core_nodes/parsers/70-XML.html | 48 + dgbuilder/core_nodes/parsers/70-XML.js | 46 + dgbuilder/core_nodes/social/27-twitter.html | 223 +++ dgbuilder/core_nodes/social/27-twitter.js | 347 ++++ dgbuilder/core_nodes/social/32-feedparse.html | 57 + dgbuilder/core_nodes/social/32-feedparse.js | 71 + dgbuilder/core_nodes/social/61-email.html | 189 ++ dgbuilder/core_nodes/social/61-email.js | 246 +++ dgbuilder/core_nodes/social/91-irc.html | 206 ++ dgbuilder/core_nodes/social/91-irc.js | 237 +++ dgbuilder/core_nodes/storage/28-tail.html | 58 + dgbuilder/core_nodes/storage/28-tail.js | 69 + dgbuilder/core_nodes/storage/50-file.html | 110 ++ dgbuilder/core_nodes/storage/50-file.js | 93 + dgbuilder/core_nodes/storage/65-redisout.html | 105 + dgbuilder/core_nodes/storage/65-redisout.js | 107 + dgbuilder/core_nodes/storage/66-mongodb.html | 231 +++ dgbuilder/core_nodes/storage/66-mongodb.js | 233 +++ dgbuilder/createReleaseDir.sh | 129 ++ dgbuilder/flowShareUsers.js | 16 + dgbuilder/generatedJS/.gitignore | 2 + dgbuilder/git_scripts/gitcheckout | 17 + dgbuilder/git_scripts/gitckout | 15 + dgbuilder/git_scripts/gitcurbranch | 13 + dgbuilder/git_scripts/gitlog | 18 + dgbuilder/git_scripts/gitpull | 7 + dgbuilder/git_scripts/gitstatus | 7 + dgbuilder/nodes/99-sample.html.demo | 79 + dgbuilder/nodes/99-sample.js.demo | 64 + dgbuilder/nodes/dge/dgelogic/block.html | 223 +++ dgbuilder/nodes/dge/dgelogic/block.js | 31 + dgbuilder/nodes/dge/dgelogic/breakNode.html | 161 ++ dgbuilder/nodes/dge/dgelogic/breakNode.js | 31 + dgbuilder/nodes/dge/dgelogic/call.html | 183 ++ dgbuilder/nodes/dge/dgelogic/call.js | 31 + dgbuilder/nodes/dge/dgelogic/configure.html | 227 +++ dgbuilder/nodes/dge/dgelogic/configure.js | 31 + dgbuilder/nodes/dge/dgelogic/delete.html | 187 ++ dgbuilder/nodes/dge/dgelogic/delete.js | 31 + dgbuilder/nodes/dge/dgelogic/execute.html | 197 ++ dgbuilder/nodes/dge/dgelogic/execute.js | 31 + dgbuilder/nodes/dge/dgelogic/exists.html | 187 ++ dgbuilder/nodes/dge/dgelogic/exists.js | 31 + dgbuilder/nodes/dge/dgelogic/forNode.html | 172 ++ dgbuilder/nodes/dge/dgelogic/forNode.js | 31 + dgbuilder/nodes/dge/dgelogic/get-resource.html | 192 ++ dgbuilder/nodes/dge/dgelogic/get-resource.js | 31 + dgbuilder/nodes/dge/dgelogic/is-available.html | 186 ++ dgbuilder/nodes/dge/dgelogic/is-available.js | 31 + dgbuilder/nodes/dge/dgelogic/notify.html | 195 ++ dgbuilder/nodes/dge/dgelogic/notify.js | 31 + dgbuilder/nodes/dge/dgelogic/record.html | 185 ++ dgbuilder/nodes/dge/dgelogic/record.js | 31 + dgbuilder/nodes/dge/dgelogic/release.html | 192 ++ dgbuilder/nodes/dge/dgelogic/release.js | 31 + dgbuilder/nodes/dge/dgelogic/reserve.html | 189 ++ dgbuilder/nodes/dge/dgelogic/reserve.js | 31 + dgbuilder/nodes/dge/dgelogic/save.html | 189 ++ dgbuilder/nodes/dge/dgelogic/save.js | 31 + dgbuilder/nodes/dge/dgelogic/set.html | 162 ++ dgbuilder/nodes/dge/dgelogic/set.js | 31 + dgbuilder/nodes/dge/dgelogic/switchNode.html | 232 +++ dgbuilder/nodes/dge/dgelogic/switchNode.js | 31 + dgbuilder/nodes/dge/dgelogic/update.html | 195 ++ dgbuilder/nodes/dge/dgelogic/update.js | 31 + dgbuilder/nodes/dge/dgemain/GenericXML.html | 140 ++ dgbuilder/nodes/dge/dgemain/GenericXML.js | 31 + dgbuilder/nodes/dge/dgemain/comment.html | 97 + dgbuilder/nodes/dge/dgemain/comment.js | 23 + dgbuilder/nodes/dge/dgemain/dgstart.html | 1322 +++++++++++++ dgbuilder/nodes/dge/dgemain/dgstart.js | 594 ++++++ dgbuilder/nodes/dge/dgemain/method.html | 141 ++ dgbuilder/nodes/dge/dgemain/method.js | 31 + dgbuilder/nodes/dge/dgemain/serviceLogic.html | 125 ++ dgbuilder/nodes/dge/dgemain/serviceLogic.js | 31 + dgbuilder/nodes/dge/dgeoutcome/already-active.html | 144 ++ dgbuilder/nodes/dge/dgeoutcome/already-active.js | 31 + dgbuilder/nodes/dge/dgeoutcome/failure.html | 142 ++ dgbuilder/nodes/dge/dgeoutcome/failure.js | 31 + dgbuilder/nodes/dge/dgeoutcome/not-found.html | 142 ++ dgbuilder/nodes/dge/dgeoutcome/not-found.js | 31 + dgbuilder/nodes/dge/dgeoutcome/other.html | 143 ++ dgbuilder/nodes/dge/dgeoutcome/other.js | 31 + dgbuilder/nodes/dge/dgeoutcome/outcome.html | 143 ++ dgbuilder/nodes/dge/dgeoutcome/outcome.js | 31 + dgbuilder/nodes/dge/dgeoutcome/outcomeFalse.html | 143 ++ dgbuilder/nodes/dge/dgeoutcome/outcomeFalse.js | 31 + dgbuilder/nodes/dge/dgeoutcome/outcomeTrue.html | 142 ++ dgbuilder/nodes/dge/dgeoutcome/outcomeTrue.js | 31 + dgbuilder/nodes/dge/dgeoutcome/success.html | 141 ++ dgbuilder/nodes/dge/dgeoutcome/success.js | 31 + dgbuilder/nodes/dge/dgereturn/returnFailure.html | 170 ++ dgbuilder/nodes/dge/dgereturn/returnFailure.js | 31 + dgbuilder/nodes/dge/dgereturn/returnSuccess.html | 174 ++ dgbuilder/nodes/dge/dgereturn/returnSuccess.js | 32 + dgbuilder/package.json | 104 + dgbuilder/pom.xml | 139 ++ dgbuilder/public/bootstrap/css/bootstrap.min.css | 9 + .../bootstrap/img/glyphicons-halflings-white.png | Bin 0 -> 8777 bytes .../public/bootstrap/img/glyphicons-halflings.png | Bin 0 -> 12799 bytes dgbuilder/public/bootstrap/js/bootstrap.min.js | 6 + dgbuilder/public/d3.v3.min.js | 4 + dgbuilder/public/favicon.ico | Bin 0 -> 1150 bytes .../public/font-awesome/css/font-awesome.min.css | 4 + .../public/font-awesome/fonts/FontAwesome.otf | Bin 0 -> 85908 bytes .../font-awesome/fonts/fontawesome-webfont.eot | Bin 0 -> 56006 bytes .../font-awesome/fonts/fontawesome-webfont.svg | 520 +++++ .../font-awesome/fonts/fontawesome-webfont.ttf | Bin 0 -> 112160 bytes .../font-awesome/fonts/fontawesome-webfont.woff | Bin 0 -> 65452 bytes dgbuilder/public/grip.png | Bin 0 -> 223 bytes dgbuilder/public/icons/alert.png | Bin 0 -> 308 bytes dgbuilder/public/icons/arduino.png | Bin 0 -> 603 bytes dgbuilder/public/icons/arrow-in.png | Bin 0 -> 393 bytes dgbuilder/public/icons/bridge-dash.png | Bin 0 -> 609 bytes dgbuilder/public/icons/bridge.png | Bin 0 -> 575 bytes dgbuilder/public/icons/comment.png | Bin 0 -> 601 bytes dgbuilder/public/icons/db.png | Bin 0 -> 459 bytes dgbuilder/public/icons/debug.png | Bin 0 -> 218 bytes dgbuilder/public/icons/envelope.png | Bin 0 -> 324 bytes dgbuilder/public/icons/feed.png | Bin 0 -> 378 bytes dgbuilder/public/icons/file.png | Bin 0 -> 255 bytes dgbuilder/public/icons/function.png | Bin 0 -> 457 bytes dgbuilder/public/icons/hash.png | Bin 0 -> 502 bytes dgbuilder/public/icons/inject.png | Bin 0 -> 449 bytes dgbuilder/public/icons/leveldb.png | Bin 0 -> 1676 bytes dgbuilder/public/icons/light.png | Bin 0 -> 639 bytes dgbuilder/public/icons/mongodb.png | Bin 0 -> 414 bytes dgbuilder/public/icons/node-changed.png | Bin 0 -> 386 bytes dgbuilder/public/icons/node-error.png | Bin 0 -> 386 bytes dgbuilder/public/icons/range.png | Bin 0 -> 360 bytes dgbuilder/public/icons/redis.png | Bin 0 -> 736 bytes dgbuilder/public/icons/rpi.png | Bin 0 -> 482 bytes dgbuilder/public/icons/serial.png | Bin 0 -> 273 bytes dgbuilder/public/icons/swap.png | Bin 0 -> 592 bytes dgbuilder/public/icons/switch.png | Bin 0 -> 509 bytes dgbuilder/public/icons/template.png | Bin 0 -> 488 bytes dgbuilder/public/icons/timer.png | Bin 0 -> 628 bytes dgbuilder/public/icons/trigger.png | Bin 0 -> 258 bytes dgbuilder/public/icons/twitter.png | Bin 0 -> 404 bytes dgbuilder/public/icons/watch.png | Bin 0 -> 591 bytes dgbuilder/public/icons/white-globe.png | Bin 0 -> 707 bytes dgbuilder/public/images/dgstart.png | Bin 0 -> 2514 bytes dgbuilder/public/images/page-loading.gif | Bin 0 -> 3992 bytes dgbuilder/public/index.html | 332 ++++ dgbuilder/public/index.html.orig | 247 +++ .../css/smoothness/images/animated-overlay.gif | Bin 0 -> 1738 bytes .../images/ui-bg_flat_0_aaaaaa_40x100.png | Bin 0 -> 212 bytes .../images/ui-bg_flat_75_ffffff_40x100.png | Bin 0 -> 208 bytes .../images/ui-bg_glass_55_fbf9ee_1x400.png | Bin 0 -> 335 bytes .../images/ui-bg_glass_65_ffffff_1x400.png | Bin 0 -> 207 bytes .../images/ui-bg_glass_75_dadada_1x400.png | Bin 0 -> 262 bytes .../images/ui-bg_glass_75_e6e6e6_1x400.png | Bin 0 -> 262 bytes .../images/ui-bg_glass_95_fef1ec_1x400.png | Bin 0 -> 332 bytes .../ui-bg_highlight-soft_75_cccccc_1x100.png | Bin 0 -> 280 bytes .../smoothness/images/ui-icons_222222_256x240.png | Bin 0 -> 6922 bytes .../smoothness/images/ui-icons_2e83ff_256x240.png | Bin 0 -> 4549 bytes .../smoothness/images/ui-icons_454545_256x240.png | Bin 0 -> 6992 bytes .../smoothness/images/ui-icons_888888_256x240.png | Bin 0 -> 6999 bytes .../smoothness/images/ui-icons_cd0a0a_256x240.png | Bin 0 -> 4549 bytes .../css/smoothness/jquery-ui-1.10.3.custom.min.css | 5 + dgbuilder/public/jquery/js/jquery-1.11.1.min.js | 4 + .../jquery/js/jquery-ui-1.10.3.custom.min.js | 7 + .../public/jquery/js/jquery.ui.touch-punch.min.js | 11 + dgbuilder/public/node-red.png | Bin 0 -> 1019 bytes dgbuilder/public/orion/built-editor.css | 526 +++++ dgbuilder/public/orion/built-editor.min.js | 1081 +++++++++++ dgbuilder/public/pw_maze_white.png | Bin 0 -> 600 bytes dgbuilder/public/red/comms.js | 93 + dgbuilder/public/red/history.js | 99 + dgbuilder/public/red/main.js | 1620 +++++++++++++++ dgbuilder/public/red/main.js.orig | 323 +++ dgbuilder/public/red/nodes.js | 553 ++++++ dgbuilder/public/red/ui/editor.js | 665 +++++++ dgbuilder/public/red/ui/keyboard.js | 68 + dgbuilder/public/red/ui/library.js | 370 ++++ dgbuilder/public/red/ui/menu.js | 122 ++ dgbuilder/public/red/ui/notifications.js | 59 + dgbuilder/public/red/ui/palette.js | 230 +++ dgbuilder/public/red/ui/sidebar.js | 154 ++ dgbuilder/public/red/ui/state.js | 26 + dgbuilder/public/red/ui/tab-config.js | 84 + dgbuilder/public/red/ui/tab-info.js | 90 + dgbuilder/public/red/ui/tabs.js | 127 ++ dgbuilder/public/red/ui/touch/radialMenu.js | 184 ++ dgbuilder/public/red/ui/view.js | 2053 ++++++++++++++++++++ dgbuilder/public/red/ui/view.js.orig | 1639 ++++++++++++++++ dgbuilder/public/red/validators.js | 19 + dgbuilder/public/spin.svg | 41 + dgbuilder/public/style.css | 980 ++++++++++ dgbuilder/public/style.css.orig | 966 +++++++++ dgbuilder/public/util/css/validateNodeXml.css | 86 + dgbuilder/public/util/js/dgeToXml.js | 1328 +++++++++++++ dgbuilder/public/util/js/dgeToXml.js.imp | 147 ++ dgbuilder/public/util/js/jsonTool.js | 67 + dgbuilder/public/util/js/migrateFlow.js | 184 ++ dgbuilder/public/util/js/sliValues.js | 763 ++++++++ dgbuilder/public/util/js/validateNodeXml.js | 325 ++++ .../public/util/js/vkbeautify.0.99.00.beta.js | 358 ++++ dgbuilder/red.js | 224 +++ dgbuilder/red/cli/lib/config.js | 53 + dgbuilder/red/cli/lib/request.js | 51 + dgbuilder/red/cli/nr-cli.js | 151 ++ dgbuilder/red/comms.js | 132 ++ dgbuilder/red/events.js | 19 + dgbuilder/red/library.js | 117 ++ dgbuilder/red/log.js | 39 + dgbuilder/red/nodes/Node.js | 147 ++ dgbuilder/red/nodes/credentials.js | 208 ++ dgbuilder/red/nodes/flows.js | 220 +++ dgbuilder/red/nodes/index.js | 134 ++ dgbuilder/red/nodes/registry.js | 693 +++++++ dgbuilder/red/red.js | 68 + dgbuilder/red/server.js | 1318 +++++++++++++ dgbuilder/red/settings.js | 84 + dgbuilder/red/sla.js | 249 +++ dgbuilder/red/storage/index.js | 107 + dgbuilder/red/storage/localfilesystem.js | 309 +++ dgbuilder/red/ui.js | 77 + dgbuilder/red/util.js | 43 + dgbuilder/releases/sdnc1.0/.config.json | 228 +++ dgbuilder/releases/sdnc1.0/codecloud/.gitignore | 0 .../releases/sdnc1.0/conf/svclogic.properties | 5 + dgbuilder/releases/sdnc1.0/customSettings.js | 38 + dgbuilder/releases/sdnc1.0/flows/shared/.gitignore | 0 .../sdnc1.0/flows/shared/backups/.gitignore | 0 dgbuilder/releases/sdnc1.0/html/.gitignore | 0 dgbuilder/releases/sdnc1.0/lib/flows/.gitignore | 0 dgbuilder/releases/sdnc1.0/logs/.gitignore | 0 dgbuilder/releases/sdnc1.0/logs/process_pid | 1 + dgbuilder/releases/sdnc1.0/xml/.gitignore | 0 dgbuilder/show_status.sh | 54 + dgbuilder/src/assembly/assemble_zip.xml | 101 + dgbuilder/start.sh | 74 + dgbuilder/stop.sh | 52 + dgbuilder/svclogic/copy_xml.sh | 4 + dgbuilder/svclogic/dg.xml | 2 + dgbuilder/svclogic/lib/.gitignore | 0 dgbuilder/svclogic/load_dg | 1 + dgbuilder/svclogic/svclogic.properties | 5 + dgbuilder/svclogic/svclogic.sh | 14 + dgbuilder/test/_spec.js | 93 + dgbuilder/test/nodes/core/core/20-inject_spec.js | 118 ++ dgbuilder/test/nodes/core/core/58-debug_spec.js | 298 +++ dgbuilder/test/nodes/core/core/80-function_spec.js | 149 ++ dgbuilder/test/nodes/core/core/80-template_spec.js | 46 + dgbuilder/test/nodes/core/core/89-delay_spec.js | 420 ++++ dgbuilder/test/nodes/core/core/90-comment_spec.js | 36 + dgbuilder/test/nodes/core/logic/10-switch_spec.js | 367 ++++ dgbuilder/test/nodes/core/logic/15-change_spec.js | 194 ++ dgbuilder/test/nodes/core/logic/16-range_spec.js | 131 ++ dgbuilder/test/nodes/core/parsers/70-HTML_spec.js | 211 ++ dgbuilder/test/nodes/core/parsers/70-JSON_spec.js | 104 + dgbuilder/test/nodes/core/parsers/70-XML_spec.js | 107 + dgbuilder/test/nodes/core/storage/28-tail_spec.js | 165 ++ dgbuilder/test/nodes/helper.js | 128 ++ dgbuilder/test/red/cli/lib/config_spec.js | 53 + dgbuilder/test/red/cli/lib/request_spec.js | 46 + dgbuilder/test/red/cli/nr-cli_spec.js | 15 + dgbuilder/test/red/comms_spec.js | 189 ++ dgbuilder/test/red/events_spec.js | 22 + dgbuilder/test/red/library_spec.js | 237 +++ dgbuilder/test/red/log_spec.js | 22 + dgbuilder/test/red/nodes/Node_spec.js | 297 +++ dgbuilder/test/red/nodes/credentials_spec.js | 497 +++++ dgbuilder/test/red/nodes/flows_spec.js | 134 ++ dgbuilder/test/red/nodes/index_spec.js | 255 +++ dgbuilder/test/red/nodes/registry_spec.js | 808 ++++++++ .../resources/DuplicateTestNode/TestNode1.html | 3 + .../nodes/resources/DuplicateTestNode/TestNode1.js | 5 + .../resources/MultipleNodes1/MultipleNodes1.html | 6 + .../resources/MultipleNodes1/MultipleNodes1.js | 7 + .../NestedDirectoryNode/NestedNode/NestedNode.html | 4 + .../NestedDirectoryNode/NestedNode/NestedNode.js | 5 + .../NestedDirectoryNode/NestedNode/icons/file.txt | 3 + .../NestedNode/lib/ShouldNotLoad.html | 4 + .../NestedNode/lib/ShouldNotLoad.js | 5 + .../NestedNode/test/ShouldNotLoad.html | 4 + .../NestedNode/test/ShouldNotLoad.js | 5 + .../red/nodes/resources/TestNode1/TestNode1.html | 5 + .../red/nodes/resources/TestNode1/TestNode1.js | 5 + .../red/nodes/resources/TestNode2/TestNode2.html | 4 + .../red/nodes/resources/TestNode2/TestNode2.js | 10 + .../red/nodes/resources/TestNode3/TestNode3.html | 3 + .../red/nodes/resources/TestNode3/TestNode3.js | 8 + dgbuilder/test/red/red_spec.js | 22 + dgbuilder/test/red/server_spec.js | 22 + dgbuilder/test/red/settings_spec.js | 114 ++ dgbuilder/test/red/storage/index_spec.js | 128 ++ dgbuilder/test/red/storage/localfilesystem_spec.js | 367 ++++ dgbuilder/test/red/ui_spec.js | 177 ++ dgbuilder/test/red/util_spec.js | 70 + dgbuilder/test/resources/70-HTML-test-file.html | 25 + dgbuilder/tools/FormatXml.java | 49 + dgbuilder/tools/PrintYangToProp.java | 1424 ++++++++++++++ dgbuilder/tools/dot_to_json.js | 138 ++ dgbuilder/tools/formatXml.py | 11 + dgbuilder/tools/format_json.sh | 6 + dgbuilder/tools/format_xml.sh | 16 + dgbuilder/tools/generate_props_from_yang.sh | 96 + dgbuilder/tools/getModuleName.sh | 2 + dgbuilder/tools/getRpcsClassFromYang.sh | 85 + dgbuilder/tools/jsonTool.js | 119 ++ dgbuilder/tools/json_to_html | 139 ++ dgbuilder/tools/json_to_html_table | 144 ++ dgbuilder/tools/json_to_prop | 116 ++ dgbuilder/tools/output_js/.gitignore | 2 + dgbuilder/tools/pom.xml_base | 79 + dgbuilder/tools/printYangProps.sh | 8 + dgbuilder/tools/printYangToProp.jar | Bin 0 -> 9010 bytes dgbuilder/tools/rs | 2 + dgbuilder/tools/setClasspath | 13 + dgbuilder/yangFiles/.gitignore | 2 + pom.xml | 1 + 379 files changed, 50220 insertions(+) create mode 100644 dgbuilder/.gitignore create mode 100644 dgbuilder/CONTRIBUTING.md create mode 100644 dgbuilder/Gruntfile.js create mode 100644 dgbuilder/INSTALL.md create mode 100644 dgbuilder/LICENSE create mode 100755 dgbuilder/build_pom_for_yang_compile create mode 100644 dgbuilder/core_nodes/analysis/72-sentiment.html create mode 100644 dgbuilder/core_nodes/analysis/72-sentiment.js create mode 100644 dgbuilder/core_nodes/core/20-inject.html create mode 100644 dgbuilder/core_nodes/core/20-inject.js create mode 100644 dgbuilder/core_nodes/core/58-debug.html create mode 100644 dgbuilder/core_nodes/core/58-debug.js create mode 100644 dgbuilder/core_nodes/core/75-exec.html create mode 100644 dgbuilder/core_nodes/core/75-exec.js create mode 100644 dgbuilder/core_nodes/core/80-function.html create mode 100644 dgbuilder/core_nodes/core/80-function.js create mode 100644 dgbuilder/core_nodes/core/80-template.html create mode 100644 dgbuilder/core_nodes/core/80-template.js create mode 100644 dgbuilder/core_nodes/core/89-delay.html create mode 100644 dgbuilder/core_nodes/core/89-delay.js create mode 100644 dgbuilder/core_nodes/core/89-trigger.html create mode 100644 dgbuilder/core_nodes/core/89-trigger.js create mode 100644 dgbuilder/core_nodes/core/90-comment.html create mode 100644 dgbuilder/core_nodes/core/90-comment.js create mode 100644 dgbuilder/core_nodes/core/98-unknown.html create mode 100644 dgbuilder/core_nodes/core/98-unknown.js create mode 100644 dgbuilder/core_nodes/deprecated/61-imap.html create mode 100644 dgbuilder/core_nodes/deprecated/61-imap.js create mode 100644 dgbuilder/core_nodes/deprecated/73-parsexml.html create mode 100644 dgbuilder/core_nodes/deprecated/73-parsexml.js create mode 100644 dgbuilder/core_nodes/deprecated/74-js2xml.html create mode 100644 dgbuilder/core_nodes/deprecated/74-js2xml.js create mode 100644 dgbuilder/core_nodes/deprecated/90-httpget.html create mode 100644 dgbuilder/core_nodes/deprecated/90-httpget.js create mode 100644 dgbuilder/core_nodes/hardware/35-arduino.html create mode 100644 dgbuilder/core_nodes/hardware/35-arduino.js create mode 100644 dgbuilder/core_nodes/hardware/36-rpi-gpio.html create mode 100644 dgbuilder/core_nodes/hardware/36-rpi-gpio.js create mode 100644 dgbuilder/core_nodes/io/10-mqtt.html create mode 100644 dgbuilder/core_nodes/io/10-mqtt.js create mode 100644 dgbuilder/core_nodes/io/21-httpin.html create mode 100644 dgbuilder/core_nodes/io/21-httpin.js create mode 100644 dgbuilder/core_nodes/io/22-websocket.html create mode 100644 dgbuilder/core_nodes/io/22-websocket.js create mode 100644 dgbuilder/core_nodes/io/23-watch.html create mode 100644 dgbuilder/core_nodes/io/23-watch.js create mode 100644 dgbuilder/core_nodes/io/25-serial.html create mode 100644 dgbuilder/core_nodes/io/25-serial.js create mode 100644 dgbuilder/core_nodes/io/31-tcpin.html create mode 100644 dgbuilder/core_nodes/io/31-tcpin.js create mode 100644 dgbuilder/core_nodes/io/32-udp.html create mode 100644 dgbuilder/core_nodes/io/32-udp.js create mode 100644 dgbuilder/core_nodes/io/lib/mqtt.js create mode 100644 dgbuilder/core_nodes/io/lib/mqttConnectionPool.js create mode 100644 dgbuilder/core_nodes/logic/10-switch.html create mode 100644 dgbuilder/core_nodes/logic/10-switch.js create mode 100644 dgbuilder/core_nodes/logic/15-change.html create mode 100644 dgbuilder/core_nodes/logic/15-change.js create mode 100644 dgbuilder/core_nodes/logic/16-range.html create mode 100644 dgbuilder/core_nodes/logic/16-range.js create mode 100644 dgbuilder/core_nodes/parsers/70-CSV.html create mode 100644 dgbuilder/core_nodes/parsers/70-CSV.js create mode 100644 dgbuilder/core_nodes/parsers/70-HTML.html create mode 100644 dgbuilder/core_nodes/parsers/70-HTML.js create mode 100644 dgbuilder/core_nodes/parsers/70-JSON.html create mode 100644 dgbuilder/core_nodes/parsers/70-JSON.js create mode 100644 dgbuilder/core_nodes/parsers/70-XML.html create mode 100644 dgbuilder/core_nodes/parsers/70-XML.js create mode 100644 dgbuilder/core_nodes/social/27-twitter.html create mode 100644 dgbuilder/core_nodes/social/27-twitter.js create mode 100644 dgbuilder/core_nodes/social/32-feedparse.html create mode 100644 dgbuilder/core_nodes/social/32-feedparse.js create mode 100644 dgbuilder/core_nodes/social/61-email.html create mode 100644 dgbuilder/core_nodes/social/61-email.js create mode 100644 dgbuilder/core_nodes/social/91-irc.html create mode 100644 dgbuilder/core_nodes/social/91-irc.js create mode 100644 dgbuilder/core_nodes/storage/28-tail.html create mode 100644 dgbuilder/core_nodes/storage/28-tail.js create mode 100644 dgbuilder/core_nodes/storage/50-file.html create mode 100644 dgbuilder/core_nodes/storage/50-file.js create mode 100644 dgbuilder/core_nodes/storage/65-redisout.html create mode 100644 dgbuilder/core_nodes/storage/65-redisout.js create mode 100644 dgbuilder/core_nodes/storage/66-mongodb.html create mode 100644 dgbuilder/core_nodes/storage/66-mongodb.js create mode 100755 dgbuilder/createReleaseDir.sh create mode 100644 dgbuilder/flowShareUsers.js create mode 100644 dgbuilder/generatedJS/.gitignore create mode 100755 dgbuilder/git_scripts/gitcheckout create mode 100755 dgbuilder/git_scripts/gitckout create mode 100755 dgbuilder/git_scripts/gitcurbranch create mode 100755 dgbuilder/git_scripts/gitlog create mode 100755 dgbuilder/git_scripts/gitpull create mode 100755 dgbuilder/git_scripts/gitstatus create mode 100644 dgbuilder/nodes/99-sample.html.demo create mode 100644 dgbuilder/nodes/99-sample.js.demo create mode 100644 dgbuilder/nodes/dge/dgelogic/block.html create mode 100644 dgbuilder/nodes/dge/dgelogic/block.js create mode 100644 dgbuilder/nodes/dge/dgelogic/breakNode.html create mode 100644 dgbuilder/nodes/dge/dgelogic/breakNode.js create mode 100644 dgbuilder/nodes/dge/dgelogic/call.html create mode 100644 dgbuilder/nodes/dge/dgelogic/call.js create mode 100644 dgbuilder/nodes/dge/dgelogic/configure.html create mode 100644 dgbuilder/nodes/dge/dgelogic/configure.js create mode 100644 dgbuilder/nodes/dge/dgelogic/delete.html create mode 100644 dgbuilder/nodes/dge/dgelogic/delete.js create mode 100644 dgbuilder/nodes/dge/dgelogic/execute.html create mode 100644 dgbuilder/nodes/dge/dgelogic/execute.js create mode 100644 dgbuilder/nodes/dge/dgelogic/exists.html create mode 100644 dgbuilder/nodes/dge/dgelogic/exists.js create mode 100644 dgbuilder/nodes/dge/dgelogic/forNode.html create mode 100644 dgbuilder/nodes/dge/dgelogic/forNode.js create mode 100644 dgbuilder/nodes/dge/dgelogic/get-resource.html create mode 100644 dgbuilder/nodes/dge/dgelogic/get-resource.js create mode 100644 dgbuilder/nodes/dge/dgelogic/is-available.html create mode 100644 dgbuilder/nodes/dge/dgelogic/is-available.js create mode 100644 dgbuilder/nodes/dge/dgelogic/notify.html create mode 100644 dgbuilder/nodes/dge/dgelogic/notify.js create mode 100644 dgbuilder/nodes/dge/dgelogic/record.html create mode 100644 dgbuilder/nodes/dge/dgelogic/record.js create mode 100644 dgbuilder/nodes/dge/dgelogic/release.html create mode 100644 dgbuilder/nodes/dge/dgelogic/release.js create mode 100644 dgbuilder/nodes/dge/dgelogic/reserve.html create mode 100644 dgbuilder/nodes/dge/dgelogic/reserve.js create mode 100644 dgbuilder/nodes/dge/dgelogic/save.html create mode 100644 dgbuilder/nodes/dge/dgelogic/save.js create mode 100644 dgbuilder/nodes/dge/dgelogic/set.html create mode 100644 dgbuilder/nodes/dge/dgelogic/set.js create mode 100644 dgbuilder/nodes/dge/dgelogic/switchNode.html create mode 100644 dgbuilder/nodes/dge/dgelogic/switchNode.js create mode 100644 dgbuilder/nodes/dge/dgelogic/update.html create mode 100644 dgbuilder/nodes/dge/dgelogic/update.js create mode 100644 dgbuilder/nodes/dge/dgemain/GenericXML.html create mode 100644 dgbuilder/nodes/dge/dgemain/GenericXML.js create mode 100644 dgbuilder/nodes/dge/dgemain/comment.html create mode 100644 dgbuilder/nodes/dge/dgemain/comment.js create mode 100644 dgbuilder/nodes/dge/dgemain/dgstart.html create mode 100644 dgbuilder/nodes/dge/dgemain/dgstart.js create mode 100644 dgbuilder/nodes/dge/dgemain/method.html create mode 100644 dgbuilder/nodes/dge/dgemain/method.js create mode 100644 dgbuilder/nodes/dge/dgemain/serviceLogic.html create mode 100644 dgbuilder/nodes/dge/dgemain/serviceLogic.js create mode 100644 dgbuilder/nodes/dge/dgeoutcome/already-active.html create mode 100644 dgbuilder/nodes/dge/dgeoutcome/already-active.js create mode 100644 dgbuilder/nodes/dge/dgeoutcome/failure.html create mode 100644 dgbuilder/nodes/dge/dgeoutcome/failure.js create mode 100644 dgbuilder/nodes/dge/dgeoutcome/not-found.html create mode 100644 dgbuilder/nodes/dge/dgeoutcome/not-found.js create mode 100644 dgbuilder/nodes/dge/dgeoutcome/other.html create mode 100644 dgbuilder/nodes/dge/dgeoutcome/other.js create mode 100644 dgbuilder/nodes/dge/dgeoutcome/outcome.html create mode 100644 dgbuilder/nodes/dge/dgeoutcome/outcome.js create mode 100644 dgbuilder/nodes/dge/dgeoutcome/outcomeFalse.html create mode 100644 dgbuilder/nodes/dge/dgeoutcome/outcomeFalse.js create mode 100644 dgbuilder/nodes/dge/dgeoutcome/outcomeTrue.html create mode 100644 dgbuilder/nodes/dge/dgeoutcome/outcomeTrue.js create mode 100644 dgbuilder/nodes/dge/dgeoutcome/success.html create mode 100644 dgbuilder/nodes/dge/dgeoutcome/success.js create mode 100644 dgbuilder/nodes/dge/dgereturn/returnFailure.html create mode 100644 dgbuilder/nodes/dge/dgereturn/returnFailure.js create mode 100644 dgbuilder/nodes/dge/dgereturn/returnSuccess.html create mode 100644 dgbuilder/nodes/dge/dgereturn/returnSuccess.js create mode 100644 dgbuilder/package.json create mode 100644 dgbuilder/pom.xml create mode 100644 dgbuilder/public/bootstrap/css/bootstrap.min.css create mode 100644 dgbuilder/public/bootstrap/img/glyphicons-halflings-white.png create mode 100644 dgbuilder/public/bootstrap/img/glyphicons-halflings.png create mode 100644 dgbuilder/public/bootstrap/js/bootstrap.min.js create mode 100644 dgbuilder/public/d3.v3.min.js create mode 100644 dgbuilder/public/favicon.ico create mode 100644 dgbuilder/public/font-awesome/css/font-awesome.min.css create mode 100644 dgbuilder/public/font-awesome/fonts/FontAwesome.otf create mode 100755 dgbuilder/public/font-awesome/fonts/fontawesome-webfont.eot create mode 100755 dgbuilder/public/font-awesome/fonts/fontawesome-webfont.svg create mode 100755 dgbuilder/public/font-awesome/fonts/fontawesome-webfont.ttf create mode 100755 dgbuilder/public/font-awesome/fonts/fontawesome-webfont.woff create mode 100644 dgbuilder/public/grip.png create mode 100644 dgbuilder/public/icons/alert.png create mode 100644 dgbuilder/public/icons/arduino.png create mode 100644 dgbuilder/public/icons/arrow-in.png create mode 100644 dgbuilder/public/icons/bridge-dash.png create mode 100644 dgbuilder/public/icons/bridge.png create mode 100644 dgbuilder/public/icons/comment.png create mode 100644 dgbuilder/public/icons/db.png create mode 100644 dgbuilder/public/icons/debug.png create mode 100644 dgbuilder/public/icons/envelope.png create mode 100644 dgbuilder/public/icons/feed.png create mode 100644 dgbuilder/public/icons/file.png create mode 100644 dgbuilder/public/icons/function.png create mode 100644 dgbuilder/public/icons/hash.png create mode 100644 dgbuilder/public/icons/inject.png create mode 100644 dgbuilder/public/icons/leveldb.png create mode 100644 dgbuilder/public/icons/light.png create mode 100644 dgbuilder/public/icons/mongodb.png create mode 100644 dgbuilder/public/icons/node-changed.png create mode 100644 dgbuilder/public/icons/node-error.png create mode 100644 dgbuilder/public/icons/range.png create mode 100644 dgbuilder/public/icons/redis.png create mode 100644 dgbuilder/public/icons/rpi.png create mode 100644 dgbuilder/public/icons/serial.png create mode 100644 dgbuilder/public/icons/swap.png create mode 100644 dgbuilder/public/icons/switch.png create mode 100644 dgbuilder/public/icons/template.png create mode 100644 dgbuilder/public/icons/timer.png create mode 100644 dgbuilder/public/icons/trigger.png create mode 100644 dgbuilder/public/icons/twitter.png create mode 100644 dgbuilder/public/icons/watch.png create mode 100644 dgbuilder/public/icons/white-globe.png create mode 100644 dgbuilder/public/images/dgstart.png create mode 100644 dgbuilder/public/images/page-loading.gif create mode 100644 dgbuilder/public/index.html create mode 100644 dgbuilder/public/index.html.orig create mode 100644 dgbuilder/public/jquery/css/smoothness/images/animated-overlay.gif create mode 100644 dgbuilder/public/jquery/css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png create mode 100644 dgbuilder/public/jquery/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png create mode 100644 dgbuilder/public/jquery/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png create mode 100644 dgbuilder/public/jquery/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png create mode 100644 dgbuilder/public/jquery/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png create mode 100644 dgbuilder/public/jquery/css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png create mode 100644 dgbuilder/public/jquery/css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png create mode 100644 dgbuilder/public/jquery/css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png create mode 100644 dgbuilder/public/jquery/css/smoothness/images/ui-icons_222222_256x240.png create mode 100644 dgbuilder/public/jquery/css/smoothness/images/ui-icons_2e83ff_256x240.png create mode 100644 dgbuilder/public/jquery/css/smoothness/images/ui-icons_454545_256x240.png create mode 100644 dgbuilder/public/jquery/css/smoothness/images/ui-icons_888888_256x240.png create mode 100644 dgbuilder/public/jquery/css/smoothness/images/ui-icons_cd0a0a_256x240.png create mode 100644 dgbuilder/public/jquery/css/smoothness/jquery-ui-1.10.3.custom.min.css create mode 100644 dgbuilder/public/jquery/js/jquery-1.11.1.min.js create mode 100644 dgbuilder/public/jquery/js/jquery-ui-1.10.3.custom.min.js create mode 100644 dgbuilder/public/jquery/js/jquery.ui.touch-punch.min.js create mode 100644 dgbuilder/public/node-red.png create mode 100644 dgbuilder/public/orion/built-editor.css create mode 100644 dgbuilder/public/orion/built-editor.min.js create mode 100644 dgbuilder/public/pw_maze_white.png create mode 100644 dgbuilder/public/red/comms.js create mode 100644 dgbuilder/public/red/history.js create mode 100644 dgbuilder/public/red/main.js create mode 100644 dgbuilder/public/red/main.js.orig create mode 100644 dgbuilder/public/red/nodes.js create mode 100644 dgbuilder/public/red/ui/editor.js create mode 100644 dgbuilder/public/red/ui/keyboard.js create mode 100644 dgbuilder/public/red/ui/library.js create mode 100644 dgbuilder/public/red/ui/menu.js create mode 100644 dgbuilder/public/red/ui/notifications.js create mode 100644 dgbuilder/public/red/ui/palette.js create mode 100644 dgbuilder/public/red/ui/sidebar.js create mode 100644 dgbuilder/public/red/ui/state.js create mode 100644 dgbuilder/public/red/ui/tab-config.js create mode 100644 dgbuilder/public/red/ui/tab-info.js create mode 100644 dgbuilder/public/red/ui/tabs.js create mode 100644 dgbuilder/public/red/ui/touch/radialMenu.js create mode 100644 dgbuilder/public/red/ui/view.js create mode 100644 dgbuilder/public/red/ui/view.js.orig create mode 100644 dgbuilder/public/red/validators.js create mode 100644 dgbuilder/public/spin.svg create mode 100644 dgbuilder/public/style.css create mode 100644 dgbuilder/public/style.css.orig create mode 100644 dgbuilder/public/util/css/validateNodeXml.css create mode 100644 dgbuilder/public/util/js/dgeToXml.js create mode 100644 dgbuilder/public/util/js/dgeToXml.js.imp create mode 100644 dgbuilder/public/util/js/jsonTool.js create mode 100644 dgbuilder/public/util/js/migrateFlow.js create mode 100644 dgbuilder/public/util/js/sliValues.js create mode 100644 dgbuilder/public/util/js/validateNodeXml.js create mode 100644 dgbuilder/public/util/js/vkbeautify.0.99.00.beta.js create mode 100644 dgbuilder/red.js create mode 100644 dgbuilder/red/cli/lib/config.js create mode 100644 dgbuilder/red/cli/lib/request.js create mode 100755 dgbuilder/red/cli/nr-cli.js create mode 100644 dgbuilder/red/comms.js create mode 100644 dgbuilder/red/events.js create mode 100644 dgbuilder/red/library.js create mode 100644 dgbuilder/red/log.js create mode 100644 dgbuilder/red/nodes/Node.js create mode 100644 dgbuilder/red/nodes/credentials.js create mode 100644 dgbuilder/red/nodes/flows.js create mode 100644 dgbuilder/red/nodes/index.js create mode 100644 dgbuilder/red/nodes/registry.js create mode 100644 dgbuilder/red/red.js create mode 100644 dgbuilder/red/server.js create mode 100644 dgbuilder/red/settings.js create mode 100644 dgbuilder/red/sla.js create mode 100644 dgbuilder/red/storage/index.js create mode 100644 dgbuilder/red/storage/localfilesystem.js create mode 100644 dgbuilder/red/ui.js create mode 100644 dgbuilder/red/util.js create mode 100644 dgbuilder/releases/sdnc1.0/.config.json create mode 100644 dgbuilder/releases/sdnc1.0/codecloud/.gitignore create mode 100644 dgbuilder/releases/sdnc1.0/conf/svclogic.properties create mode 100644 dgbuilder/releases/sdnc1.0/customSettings.js create mode 100644 dgbuilder/releases/sdnc1.0/flows/shared/.gitignore create mode 100644 dgbuilder/releases/sdnc1.0/flows/shared/backups/.gitignore create mode 100644 dgbuilder/releases/sdnc1.0/html/.gitignore create mode 100644 dgbuilder/releases/sdnc1.0/lib/flows/.gitignore create mode 100644 dgbuilder/releases/sdnc1.0/logs/.gitignore create mode 100644 dgbuilder/releases/sdnc1.0/logs/process_pid create mode 100644 dgbuilder/releases/sdnc1.0/xml/.gitignore create mode 100755 dgbuilder/show_status.sh create mode 100644 dgbuilder/src/assembly/assemble_zip.xml create mode 100755 dgbuilder/start.sh create mode 100755 dgbuilder/stop.sh create mode 100755 dgbuilder/svclogic/copy_xml.sh create mode 100644 dgbuilder/svclogic/dg.xml create mode 100644 dgbuilder/svclogic/lib/.gitignore create mode 100755 dgbuilder/svclogic/load_dg create mode 100644 dgbuilder/svclogic/svclogic.properties create mode 100755 dgbuilder/svclogic/svclogic.sh create mode 100644 dgbuilder/test/_spec.js create mode 100644 dgbuilder/test/nodes/core/core/20-inject_spec.js create mode 100644 dgbuilder/test/nodes/core/core/58-debug_spec.js create mode 100644 dgbuilder/test/nodes/core/core/80-function_spec.js create mode 100644 dgbuilder/test/nodes/core/core/80-template_spec.js create mode 100644 dgbuilder/test/nodes/core/core/89-delay_spec.js create mode 100644 dgbuilder/test/nodes/core/core/90-comment_spec.js create mode 100644 dgbuilder/test/nodes/core/logic/10-switch_spec.js create mode 100644 dgbuilder/test/nodes/core/logic/15-change_spec.js create mode 100644 dgbuilder/test/nodes/core/logic/16-range_spec.js create mode 100644 dgbuilder/test/nodes/core/parsers/70-HTML_spec.js create mode 100644 dgbuilder/test/nodes/core/parsers/70-JSON_spec.js create mode 100644 dgbuilder/test/nodes/core/parsers/70-XML_spec.js create mode 100644 dgbuilder/test/nodes/core/storage/28-tail_spec.js create mode 100644 dgbuilder/test/nodes/helper.js create mode 100644 dgbuilder/test/red/cli/lib/config_spec.js create mode 100644 dgbuilder/test/red/cli/lib/request_spec.js create mode 100644 dgbuilder/test/red/cli/nr-cli_spec.js create mode 100644 dgbuilder/test/red/comms_spec.js create mode 100644 dgbuilder/test/red/events_spec.js create mode 100644 dgbuilder/test/red/library_spec.js create mode 100644 dgbuilder/test/red/log_spec.js create mode 100644 dgbuilder/test/red/nodes/Node_spec.js create mode 100644 dgbuilder/test/red/nodes/credentials_spec.js create mode 100644 dgbuilder/test/red/nodes/flows_spec.js create mode 100644 dgbuilder/test/red/nodes/index_spec.js create mode 100644 dgbuilder/test/red/nodes/registry_spec.js create mode 100644 dgbuilder/test/red/nodes/resources/DuplicateTestNode/TestNode1.html create mode 100644 dgbuilder/test/red/nodes/resources/DuplicateTestNode/TestNode1.js create mode 100644 dgbuilder/test/red/nodes/resources/MultipleNodes1/MultipleNodes1.html create mode 100644 dgbuilder/test/red/nodes/resources/MultipleNodes1/MultipleNodes1.js create mode 100644 dgbuilder/test/red/nodes/resources/NestedDirectoryNode/NestedNode/NestedNode.html create mode 100644 dgbuilder/test/red/nodes/resources/NestedDirectoryNode/NestedNode/NestedNode.js create mode 100644 dgbuilder/test/red/nodes/resources/NestedDirectoryNode/NestedNode/icons/file.txt create mode 100644 dgbuilder/test/red/nodes/resources/NestedDirectoryNode/NestedNode/lib/ShouldNotLoad.html create mode 100644 dgbuilder/test/red/nodes/resources/NestedDirectoryNode/NestedNode/lib/ShouldNotLoad.js create mode 100644 dgbuilder/test/red/nodes/resources/NestedDirectoryNode/NestedNode/test/ShouldNotLoad.html create mode 100644 dgbuilder/test/red/nodes/resources/NestedDirectoryNode/NestedNode/test/ShouldNotLoad.js create mode 100644 dgbuilder/test/red/nodes/resources/TestNode1/TestNode1.html create mode 100644 dgbuilder/test/red/nodes/resources/TestNode1/TestNode1.js create mode 100644 dgbuilder/test/red/nodes/resources/TestNode2/TestNode2.html create mode 100644 dgbuilder/test/red/nodes/resources/TestNode2/TestNode2.js create mode 100644 dgbuilder/test/red/nodes/resources/TestNode3/TestNode3.html create mode 100644 dgbuilder/test/red/nodes/resources/TestNode3/TestNode3.js create mode 100644 dgbuilder/test/red/red_spec.js create mode 100644 dgbuilder/test/red/server_spec.js create mode 100644 dgbuilder/test/red/settings_spec.js create mode 100644 dgbuilder/test/red/storage/index_spec.js create mode 100644 dgbuilder/test/red/storage/localfilesystem_spec.js create mode 100644 dgbuilder/test/red/ui_spec.js create mode 100644 dgbuilder/test/red/util_spec.js create mode 100644 dgbuilder/test/resources/70-HTML-test-file.html create mode 100644 dgbuilder/tools/FormatXml.java create mode 100644 dgbuilder/tools/PrintYangToProp.java create mode 100644 dgbuilder/tools/dot_to_json.js create mode 100644 dgbuilder/tools/formatXml.py create mode 100755 dgbuilder/tools/format_json.sh create mode 100755 dgbuilder/tools/format_xml.sh create mode 100755 dgbuilder/tools/generate_props_from_yang.sh create mode 100755 dgbuilder/tools/getModuleName.sh create mode 100755 dgbuilder/tools/getRpcsClassFromYang.sh create mode 100644 dgbuilder/tools/jsonTool.js create mode 100644 dgbuilder/tools/json_to_html create mode 100755 dgbuilder/tools/json_to_html_table create mode 100755 dgbuilder/tools/json_to_prop create mode 100644 dgbuilder/tools/output_js/.gitignore create mode 100644 dgbuilder/tools/pom.xml_base create mode 100755 dgbuilder/tools/printYangProps.sh create mode 100644 dgbuilder/tools/printYangToProp.jar create mode 100755 dgbuilder/tools/rs create mode 100755 dgbuilder/tools/setClasspath create mode 100644 dgbuilder/yangFiles/.gitignore diff --git a/dgbuilder/.gitignore b/dgbuilder/.gitignore new file mode 100644 index 00000000..1b8a6ba9 --- /dev/null +++ b/dgbuilder/.gitignore @@ -0,0 +1,12 @@ +org.eclipse.core.resources.prefs +.classpath +.project +.settings +.idea +.externalToolBuilders +maven-eclipse.xml +*.class +target/ +MANIFEST.MF +.DS_STORE +.metadata diff --git a/dgbuilder/CONTRIBUTING.md b/dgbuilder/CONTRIBUTING.md new file mode 100644 index 00000000..52fe8911 --- /dev/null +++ b/dgbuilder/CONTRIBUTING.md @@ -0,0 +1,82 @@ +# Contributing to Node-RED + +We welcome contributions, but request you follow these guidelines. + +## Raising issues + +Please raise any bug reports on the project's +[issue tracker](https://github.com/node-red/node-red/issues?state=open). Be sure to +search the list to see if your issue has already been raised. + +A good bug report is one that make it easy for us to understand what you were +trying to do and what went wrong. + +Provide as much context as possible so we can try to recreate the issue. +If possible, include the relevant part of your flow. To do this, select the +relevant nodes, press Ctrl-E and copy the flow data from the Export dialog. + +At a minimum, please include: + + - Version of Node-RED - either release number if you downloaded a zip, or the first few lines of `git log` if you are cloning the repository directly. + - Version of node.js - what does `node -v` say? + + +## New features + +For feature requests, please raise them on the [mailing list](https://groups.google.com/forum/#!forum/node-red). + +## Pull-Requests + +### Changes to existing code +if you want to raise a pull-request with a new feature, or a refactoring +of existing code, it may well get rejected if you haven't discussed it on +the [mailing list](https://groups.google.com/forum/#!forum/node-red) first. + +### New nodes + +The plugin nature of Node-RED means anyone can create a new node to extend +its capabilities. + +We want to avoid duplication as that can lead to confusion. Many of our existing +nodes offer a starting point of functionality. If they are missing features, +we would rather extend them than add separate 'advanced' versions. But the key +to that approach is getting the UX right to not lose the simplicity. + +To contribute a new node, please raise a pull-request against the +`node-red-nodes` repository. + +Eventually, the nodes will be npm-installable, but we're not there yet. We'll +also have some sort of registry of nodes to help with discoverability. + +### Coding standards + +Please ensure you follow the coding standards used through-out the existing +code base. Some basic rules include: + + - all files must have the Apache license in the header. + - indent with 4-spaces, no tabs. No arguments. + - opening brace on same line as `if`/`for`/`function`/etc, closing brace on its + own line. + +### Contributor License Aggreement + +In order for us to accept pull-requests, the contributor must first complete +a Contributor License Agreement (CLA). This clarifies the intellectual +property license granted with any contribution. It is for your protection as a +Contributor as well as the protection of IBM and its customers; it does not +change your rights to use your own Contributions for any other purpose. + +You can download the CLAs here: + + - [individual](http://nodered.org/cla/node-red-cla-individual.pdf) + - [corporate](http://nodered.org/cla/node-red-cla-corporate.pdf) + +If you are an IBMer, please contact us directly as the contribution process is +slightly different. + + + + + + + diff --git a/dgbuilder/Gruntfile.js b/dgbuilder/Gruntfile.js new file mode 100644 index 00000000..62a553f7 --- /dev/null +++ b/dgbuilder/Gruntfile.js @@ -0,0 +1,91 @@ +/** + * Copyright 2013, 2014 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(grunt) { + + // Project configuration. + grunt.initConfig({ + pkg: grunt.file.readJSON('package.json'), + simplemocha: { + options: { + globals: ['expect'], + timeout: 3000, + ignoreLeaks: false, + ui: 'bdd', + reporter: 'spec' + }, + all: { src: ['test/**/*_spec.js'] }, + core: { src: ["test/_spec.js","test/red/**/*_spec.js"]}, + nodes: { src: ["test/nodes/**/*_spec.js"]} + }, + jshint: { + options: { + // http://www.jshint.com/docs/options/ + "asi": true, // allow missing semicolons + "curly": true, // require braces + "eqnull": true, // ignore ==null + "forin": true, // require property filtering in "for in" loops + "immed": true, // require immediate functions to be wrapped in ( ) + "nonbsp": true, // warn on unexpected whitespace breaking chars + //"strict": true, // commented out for now as it causes 100s of warnings, but want to get there eventually + "loopfunc": true, // allow functions to be defined in loops + "sub": true // don't warn that foo['bar'] should be written as foo.bar + }, + all: [ + 'Gruntfile.js', + 'red.js', + 'red/**/*.js', + 'nodes/**/*.js', + 'public/red/**/*.js' + ], + + core: { + files: { + src: [ + 'Gruntfile.js', + 'red.js', + 'red/**/*.js' + ] + } + }, + nodes: { + files: { + src: [ 'nodes/**/*.js' ] + } + }, + editor: { + files: { + src: [ 'public/red/**/*.js' ] + } + }, + tests: { + files: { + src: ['test/**/*.js'] + }, + options: { + "expr": true + } + } + + } + }); + + grunt.loadNpmTasks('grunt-simple-mocha'); + grunt.loadNpmTasks('grunt-contrib-jshint'); + + grunt.registerTask('default', ['jshint:core','jshint:tests','jshint:editor','simplemocha:core','simplemocha:nodes']); + +}; diff --git a/dgbuilder/INSTALL.md b/dgbuilder/INSTALL.md new file mode 100644 index 00000000..90922e6f --- /dev/null +++ b/dgbuilder/INSTALL.md @@ -0,0 +1,57 @@ +Node-RED Install +================ + +## Install node.js + +You can get the latest version from . + +Or, you may want to use a version from your operating system's package manager: + + +## Get Node-RED + +Clone the repository from GitHub: + + $ git clone git@github.com:node-red/node-red.git + +## Install the pre-requisite modules + +From the top-level directory of Node-RED, run: + + $ npm install + +This will install the core pre-requisite modules. + +## Run Node-RED + +From the top-level directory, run: + + $ node red.js + +You can then access Node-RED at . + +Online documentation is available at . + +## Installing individual node dependencies + +When Node-RED starts, it attempts to load the nodes from the `nodes/` directory. +Each will have its own set of dependencies that will need to be installed before +the node is available in the palette. + +To help identify the dependencies, Node-RED logs any modules it fails to find +for a particular node. You don't have to install these unless you want or need +that node to appear. + +Alternatively, a node's `.js` file can be examined to identify the modules it +explicitly requires. For example, the Twitter node is defined in +`nodes/social/27-twitter.js` and contains: + + var RED = require("../../red/red"); + var ntwitter = require('ntwitter'); + var OAuth= require('oauth').OAuth; + +Of these, `ntwitter` and `oauth` are neither built-in modules nor ones provided +by Node-RED itself. They can subsequently be installed by running: + + $ npm install ntwitter oauth + diff --git a/dgbuilder/LICENSE b/dgbuilder/LICENSE new file mode 100644 index 00000000..f433b1a5 --- /dev/null +++ b/dgbuilder/LICENSE @@ -0,0 +1,177 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/dgbuilder/build_pom_for_yang_compile b/dgbuilder/build_pom_for_yang_compile new file mode 100755 index 00000000..c9aa38ac --- /dev/null +++ b/dgbuilder/build_pom_for_yang_compile @@ -0,0 +1,86 @@ +echo "Version of dgbuilder pom is : $4" +echo "Building pom.xml_base for compiling yang" + +model_pom_content=$(cat < + + 4.0.0 + + org.onap.ccsdk.distribution + distribution-root + ${1} + + yangApp-model + bundle + 1.0.0-SNAPSHOT + + + + + org.apache.felix + maven-bundle-plugin + true + + + * + + + + + org.opendaylight.yangtools + yang-maven-plugin + \${odl.yangtools.yang.maven.plugin.version} + + + org.opendaylight.mdsal + maven-sal-api-gen-plugin + \${odl.sal.api.gen.plugin.version} + jar + + + + + + generate-sources + + + \${yang.file.directory} + + + org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl + \${salGeneratorPath} + + + true + + + + + + + + + org.opendaylight.mdsal + yang-binding + \${odl.mdsal.yang.binding.version} + + + org.opendaylight.yangtools + yang-common + \${odl.yangtools.version} + + + org.opendaylight.mdsal.model + ietf-inet-types + \${odl.ietf-inet-types.version} + + + org.opendaylight.mdsal.model + ietf-yang-types + \${odl.ietf-yang-types.version} + + + +EOF +) +echo "$model_pom_content" >tools/pom.xml_base diff --git a/dgbuilder/core_nodes/analysis/72-sentiment.html b/dgbuilder/core_nodes/analysis/72-sentiment.html new file mode 100644 index 00000000..c33b873b --- /dev/null +++ b/dgbuilder/core_nodes/analysis/72-sentiment.html @@ -0,0 +1,49 @@ + + + + + + + diff --git a/dgbuilder/core_nodes/analysis/72-sentiment.js b/dgbuilder/core_nodes/analysis/72-sentiment.js new file mode 100644 index 00000000..747e079c --- /dev/null +++ b/dgbuilder/core_nodes/analysis/72-sentiment.js @@ -0,0 +1,33 @@ +/** + * Copyright 2013 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + var sentiment = require('sentiment'); + + function SentimentNode(n) { + RED.nodes.createNode(this,n); + var node = this; + + this.on("input", function(msg) { + sentiment(msg.payload, msg.overrides || null, function (err, result) { + msg.sentiment = result; + node.send(msg); + }); + }); + } + RED.nodes.registerType("sentiment",SentimentNode); +} diff --git a/dgbuilder/core_nodes/core/20-inject.html b/dgbuilder/core_nodes/core/20-inject.html new file mode 100644 index 00000000..38aa6efe --- /dev/null +++ b/dgbuilder/core_nodes/core/20-inject.html @@ -0,0 +1,437 @@ + + + + + + + diff --git a/dgbuilder/core_nodes/core/20-inject.js b/dgbuilder/core_nodes/core/20-inject.js new file mode 100644 index 00000000..dff0fb65 --- /dev/null +++ b/dgbuilder/core_nodes/core/20-inject.js @@ -0,0 +1,97 @@ +/** + * Copyright 2013, 2014 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + var cron = require("cron"); + + function InjectNode(n) { + RED.nodes.createNode(this,n); + this.topic = n.topic; + this.payload = n.payload; + this.payloadType = n.payloadType; + this.repeat = n.repeat; + this.crontab = n.crontab; + this.once = n.once; + var node = this; + this.interval_id = null; + this.cronjob = null; + + if (this.repeat && !isNaN(this.repeat) && this.repeat > 0) { + this.repeat = this.repeat * 1000; + this.log("repeat = "+this.repeat); + this.interval_id = setInterval( function() { + node.emit("input",{}); + }, this.repeat ); + } else if (this.crontab) { + if (cron) { + this.log("crontab = "+this.crontab); + this.cronjob = new cron.CronJob(this.crontab, + function() { + node.emit("input",{}); + }, + null,true); + } else { + this.error("'cron' module not found"); + } + } + + if (this.once) { + setTimeout( function(){ node.emit("input",{}); }, 100); + } + + this.on("input",function(msg) { + var msg = {topic:this.topic}; + if ( (this.payloadType == null && this.payload == "") || this.payloadType == "date") { + msg.payload = Date.now(); + } else if (this.payloadType == null || this.payloadType == "string") { + msg.payload = this.payload; + } else { + msg.payload = ""; + } + this.send(msg); + msg = null; + }); + } + + RED.nodes.registerType("inject",InjectNode); + + InjectNode.prototype.close = function() { + if (this.interval_id != null) { + clearInterval(this.interval_id); + this.log("inject: repeat stopped"); + } else if (this.cronjob != null) { + this.cronjob.stop(); + this.log("inject: cronjob stopped"); + delete this.cronjob; + } + } + + RED.httpAdmin.post("/inject/:id", function(req,res) { + var node = RED.nodes.getNode(req.params.id); + if (node != null) { + try { + node.receive(); + res.send(200); + } catch(err) { + res.send(500); + node.error("Inject failed:"+err); + console.log(err.stack); + } + } else { + res.send(404); + } + }); +} diff --git a/dgbuilder/core_nodes/core/58-debug.html b/dgbuilder/core_nodes/core/58-debug.html new file mode 100644 index 00000000..04aa5078 --- /dev/null +++ b/dgbuilder/core_nodes/core/58-debug.html @@ -0,0 +1,248 @@ + + + + + + + + + diff --git a/dgbuilder/core_nodes/core/58-debug.js b/dgbuilder/core_nodes/core/58-debug.js new file mode 100644 index 00000000..7436bf2c --- /dev/null +++ b/dgbuilder/core_nodes/core/58-debug.js @@ -0,0 +1,114 @@ +/** + * Copyright 2013 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + var util = require("util"); + var events = require("events"); + var debuglength = RED.settings.debugMaxLength||1000; + var useColors = false; + // util.inspect.styles.boolean = "red"; + + function DebugNode(n) { + RED.nodes.createNode(this,n); + this.name = n.name; + this.complete = n.complete; + this.console = n.console; + this.active = (n.active == null)||n.active; + var node = this; + + this.on("input",function(msg) { + if (this.complete == "true") { // debug complete msg object + if (this.console == "true") { + node.log("\n"+util.inspect(msg, {colors:useColors, depth:10})); + } + if (this.active) { + sendDebug({id:this.id,name:this.name,topic:msg.topic,msg:msg,_path:msg._path}); + } + } else { // debug just the msg.payload + if (this.console == "true") { + if (typeof msg.payload === "string") { + node.log((msg.payload.indexOf("\n") != -1 ? "\n" : "") + msg.payload); + } + else if (typeof msg.payload === "object") { node.log("\n"+util.inspect(msg.payload, {colors:useColors, depth:10})); } + else { node.log(util.inspect(msg.payload, {colors:useColors})); } + } + if (this.active) { + sendDebug({id:this.id,name:this.name,topic:msg.topic,msg:msg.payload,_path:msg._path}); + } + } + }); + } + + RED.nodes.registerType("debug",DebugNode); + + function sendDebug(msg) { + if (msg.msg instanceof Error) { + msg.msg = msg.msg.toString(); + } else if (msg.msg instanceof Buffer) { + msg.msg = "(Buffer) "+msg.msg.toString('hex'); + } else if (typeof msg.msg === 'object') { + var seen = []; + var ty = "(Object) "; + if (util.isArray(msg.msg)) { ty = "(Array) "; } + msg.msg = ty + JSON.stringify(msg.msg, function(key, value) { + if (typeof value === 'object' && value !== null) { + if (seen.indexOf(value) !== -1) { return "[circular]"; } + seen.push(value); + } + return value; + }," "); + seen = null; + } else if (typeof msg.msg === "boolean") { + msg.msg = "(boolean) "+msg.msg.toString(); + } else if (msg.msg === 0) { + msg.msg = "0"; + } else if (msg.msg == null) { + msg.msg = "(undefined)"; + } + + if (msg.msg.length > debuglength) { + msg.msg = msg.msg.substr(0,debuglength) +" ...."; + } + + RED.comms.publish("debug",msg); + } + + DebugNode.logHandler = new events.EventEmitter(); + DebugNode.logHandler.on("log",function(msg) { + if (msg.level == "warn" || msg.level == "error") { + sendDebug(msg); + } + }); + RED.log.addHandler(DebugNode.logHandler); + + RED.httpAdmin.post("/debug/:id/:state", function(req,res) { + var node = RED.nodes.getNode(req.params.id); + var state = req.params.state; + if (node != null) { + if (state === "enable") { + node.active = true; + res.send(200); + } else if (state === "disable") { + node.active = false; + res.send(201); + } else { + res.send(404); + } + } else { + res.send(404); + } + }); +} diff --git a/dgbuilder/core_nodes/core/75-exec.html b/dgbuilder/core_nodes/core/75-exec.html new file mode 100644 index 00000000..567a34c1 --- /dev/null +++ b/dgbuilder/core_nodes/core/75-exec.html @@ -0,0 +1,68 @@ + + + + + + + diff --git a/dgbuilder/core_nodes/core/75-exec.js b/dgbuilder/core_nodes/core/75-exec.js new file mode 100644 index 00000000..a07b1401 --- /dev/null +++ b/dgbuilder/core_nodes/core/75-exec.js @@ -0,0 +1,84 @@ +/** + * Copyright 2013 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + var spawn = require('child_process').spawn; + var exec = require('child_process').exec; + + function ExecNode(n) { + RED.nodes.createNode(this,n); + this.cmd = n.command.trim(); + this.append = n.append.trim() || ""; + this.useSpawn = n.useSpawn; + + var node = this; + this.on("input", function(msg) { + node.status({fill:"blue",shape:"dot"}); + if (this.useSpawn === true) { + // make the extra args into an array + // then prepend with the msg.payload + if (typeof(msg.payload !== "string")) { msg.payload = msg.payload.toString(); } + var arg = []; + if (node.append.length > 0) { arg = node.append.split(","); } + if (msg.payload.trim() !== "") { arg.unshift(msg.payload); } + node.log(node.cmd+" ["+arg+"]"); + if (node.cmd.indexOf(" ") == -1) { + var ex = spawn(node.cmd,arg); + ex.stdout.on('data', function (data) { + //console.log('[exec] stdout: ' + data); + msg.payload = data.toString(); + node.send([msg,null,null]); + }); + ex.stderr.on('data', function (data) { + //console.log('[exec] stderr: ' + data); + msg.payload = data.toString(); + node.send([null,msg,null]); + }); + ex.on('close', function (code) { + //console.log('[exec] result: ' + code); + msg.payload = code; + node.status({}); + node.send([null,null,msg]); + }); + ex.on('error', function (code) { + node.warn(code); + }); + } + else { node.error("Spawn command must be just the command - no spaces or extra parameters"); } + } + else { + var cl = node.cmd+" "+msg.payload+" "+node.append; + node.log(cl); + var child = exec(cl, function (error, stdout, stderr) { + msg.payload = stdout; + var msg2 = {payload:stderr}; + var msg3 = null; + //console.log('[exec] stdout: ' + stdout); + //console.log('[exec] stderr: ' + stderr); + if (error !== null) { + msg3 = {payload:error}; + //console.log('[exec] error: ' + error); + } + node.status({}); + node.send([msg,msg2,msg3]); + }); + } + }); + } + + RED.nodes.registerType("exec",ExecNode); +} diff --git a/dgbuilder/core_nodes/core/80-function.html b/dgbuilder/core_nodes/core/80-function.html new file mode 100644 index 00000000..442c391d --- /dev/null +++ b/dgbuilder/core_nodes/core/80-function.html @@ -0,0 +1,110 @@ + + + + + + + diff --git a/dgbuilder/core_nodes/core/80-function.js b/dgbuilder/core_nodes/core/80-function.js new file mode 100644 index 00000000..e1413a7a --- /dev/null +++ b/dgbuilder/core_nodes/core/80-function.js @@ -0,0 +1,79 @@ +/** + * Copyright 2013 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + var util = require("util"); + var vm = require("vm"); + + function FunctionNode(n) { + RED.nodes.createNode(this,n); + this.name = n.name; + this.func = n.func; + var functionText = "var results = null; results = (function(msg){"+this.func+"\n})(msg);"; + this.topic = n.topic; + var sandbox = { + console:console, + util:util, + Buffer:Buffer, + context: { + global:RED.settings.functionGlobalContext || {} + } + }; + var context = vm.createContext(sandbox); + try { + this.script = vm.createScript(functionText); + this.on("input", function(msg) { + try { + var start = process.hrtime(); + context.msg = msg; + this.script.runInContext(context); + var results = context.results; + if (results == null) { + results = []; + } else if (results.length == null) { + results = [results]; + } + if (msg._topic) { + for (var m in results) { + if (results[m]) { + if (util.isArray(results[m])) { + for (var n=0; n < results[m].length; n++) { + results[m][n]._topic = msg._topic; + } + } else { + results[m]._topic = msg._topic; + } + } + } + } + this.send(results); + var duration = process.hrtime(start); + if (process.env.NODE_RED_FUNCTION_TIME) { + this.status({fill:"yellow",shape:"dot",text:""+Math.floor((duration[0]* 1e9 + duration[1])/10000)/100}); + } + } catch(err) { + this.error(err.toString()); + } + }); + } catch(err) { + this.error(err); + } + } + + RED.nodes.registerType("function",FunctionNode); + RED.library.register("functions"); +} diff --git a/dgbuilder/core_nodes/core/80-template.html b/dgbuilder/core_nodes/core/80-template.html new file mode 100644 index 00000000..dc014d37 --- /dev/null +++ b/dgbuilder/core_nodes/core/80-template.html @@ -0,0 +1,102 @@ + + + + + + + diff --git a/dgbuilder/core_nodes/core/80-template.js b/dgbuilder/core_nodes/core/80-template.js new file mode 100644 index 00000000..7c84142d --- /dev/null +++ b/dgbuilder/core_nodes/core/80-template.js @@ -0,0 +1,61 @@ +/** + * Copyright 2013 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + var mustache = require("mustache"); + + function TemplateNode(n) { + RED.nodes.createNode(this,n); + this.name = n.name; + this.field = n.field || "payload"; + this.template = n.template; + var node = this; + + var b = node.field.split("."); + var i = 0; + var m = null; + var rec = function(obj) { + i += 1; + if ((i < b.length) && (typeof obj[b[i-1]] === "object")) { + rec(obj[b[i-1]]); // not there yet - carry on digging + } + else { + if (i === b.length) { // we've finished so assign the value + obj[b[i-1]] = mustache.render(node.template,m); + node.send(m); + } + else { + obj[b[i-1]] = {}; // needs to be a new object so create it + rec(obj[b[i-1]]); // and carry on digging + } + } + } + + node.on("input", function(msg) { + try { + m = msg; + i = 0; + rec(msg); + } catch(err) { + node.error(err.message); + } + }); + } + + RED.nodes.registerType("template",TemplateNode); + RED.library.register("templates"); +} diff --git a/dgbuilder/core_nodes/core/89-delay.html b/dgbuilder/core_nodes/core/89-delay.html new file mode 100644 index 00000000..dcb0a5b9 --- /dev/null +++ b/dgbuilder/core_nodes/core/89-delay.html @@ -0,0 +1,167 @@ + + + + + + + + + + diff --git a/dgbuilder/core_nodes/core/89-delay.js b/dgbuilder/core_nodes/core/89-delay.js new file mode 100644 index 00000000..3c4e1c01 --- /dev/null +++ b/dgbuilder/core_nodes/core/89-delay.js @@ -0,0 +1,171 @@ +/** + * Copyright 2013, 2014 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +//Simple node to introduce a pause into a flow +module.exports = function(RED) { + "use strict"; + + var MILLIS_TO_NANOS = 1000000; + var SECONDS_TO_NANOS = 1000000000; + + function random(n) { + var wait = n.randomFirst + (n.diff * Math.random()); + if (n.buffer.length > 0) { + n.send(n.buffer.pop()); + n.randomID = setTimeout(function() {random(n);},wait); + } else { + n.randomID = -1; + } + } + + function DelayNode(n) { + RED.nodes.createNode(this,n); + + this.pauseType = n.pauseType; + this.timeoutUnits = n.timeoutUnits; + this.randomUnits = n.randomUnits; + this.rateUnits = n.rateUnits; + + if (n.timeoutUnits === "milliseconds") { + this.timeout = n.timeout; + } else if (n.timeoutUnits === "seconds") { + this.timeout = n.timeout * 1000; + } else if (n.timeoutUnits === "minutes") { + this.timeout = n.timeout * (60 * 1000); + } else if (n.timeoutUnits === "hours") { + this.timeout = n.timeout * (60 * 60 * 1000); + } else if (n.timeoutUnits === "days") { + this.timeout = n.timeout * (24 * 60 * 60 * 1000); + } + + if (n.rateUnits === "second") { + this.rate = 1000/n.rate; + } else if (n.rateUnits === "minute") { + this.rate = (60 * 1000)/n.rate; + } else if (n.rateUnits === "hour") { + this.rate = (60 * 60 * 1000)/n.rate; + } else if (n.rateUnits === "day") { + this.rate = (24 * 60 * 60 * 1000)/n.rate; + } + + if (n.randomUnits === "milliseconds") { + this.randomFirst = n.randomFirst; + this.randomLast = n.randomLast; + } else if (n.randomUnits === "seconds") { + this.randomFirst = n.randomFirst * 1000; + this.randomLast = n.randomLast * 1000; + } else if (n.randomUnits === "minutes") { + this.randomFirst = n.randomFirst * (60 * 1000); + this.randomLast = n.randomLast * (60 * 1000); + } else if (n.randomUnits === "hours") { + this.randomFirst = n.randomFirst * (60 * 60 * 1000); + this.randomLast = n.randomLast * (60 * 60 * 1000); + } else if (n.randomUnits === "days") { + this.randomFirst = n.randomFirst * (24 * 60 * 60 * 1000); + this.randomLast = n.randomLast * (24 * 60 * 60 * 1000); + } + + this.diff = this.randomLast - this.randomFirst; + this.name = n.name; + this.idList = []; + this.buffer = []; + this.intervalID = -1; + this.randomID = -1; + this.lastSent; + this.drop = n.drop; + var node = this; + + if (this.pauseType === "delay") { + this.on("input", function(msg) { + var id; + id = setTimeout(function(){ + node.idList.splice(node.idList.indexOf(id),1); + node.send(msg); + }, node.timeout); + this.idList.push(id); + }); + + this.on("close", function() { + for (var i=0; i 0) { + node.status({text:node.buffer.length}); + } + if (node.buffer.length > 1000) { + node.warn(this.name + " buffer exceeded 1000 messages"); + } + } else { + node.send(msg); + node.intervalID = setInterval(function() { + if (node.buffer.length === 0) { + clearInterval(node.intervalID); + node.intervalID = -1; + node.status({text:""}); + } + + if (node.buffer.length > 0) { + node.send(node.buffer.shift()); + node.status({text:node.buffer.length}); + } + },node.rate); + } + } else { + var timeSinceLast; + if (node.lastSent) { + timeSinceLast = process.hrtime(node.lastSent); + } + if (!node.lastSent) { // ensuring that we always send the first message + node.lastSent = process.hrtime(); + node.send(msg); + } else if ( ( (timeSinceLast[0] * SECONDS_TO_NANOS) + timeSinceLast[1] ) > (node.rate * MILLIS_TO_NANOS) ) { + node.lastSent = process.hrtime(); + node.send(msg); + } + } + }); + + this.on("close", function() { + clearInterval(this.intervalID); + this.buffer = []; + }); + + } else if (this.pauseType === "random") { + this.on("input",function(msg){ + node.buffer.push(msg); + if (node.randomID === -1) { + var wait = node.randomFirst + (node.diff * Math.random()); + node.randomID = setTimeout(function() {random(node);},wait); + } + }); + + this.on("close", function (){ + if (this.randomID !== -1) { + clearTimeout(this.randomID); + } + }); + } + } + RED.nodes.registerType("delay",DelayNode); +} diff --git a/dgbuilder/core_nodes/core/89-trigger.html b/dgbuilder/core_nodes/core/89-trigger.html new file mode 100644 index 00000000..f3ec530d --- /dev/null +++ b/dgbuilder/core_nodes/core/89-trigger.html @@ -0,0 +1,130 @@ + + + + + + + + diff --git a/dgbuilder/core_nodes/core/89-trigger.js b/dgbuilder/core_nodes/core/89-trigger.js new file mode 100644 index 00000000..d86a2130 --- /dev/null +++ b/dgbuilder/core_nodes/core/89-trigger.js @@ -0,0 +1,91 @@ +/** + * Copyright 2014 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + var mustache = require("mustache"); + function TriggerNode(n) { + RED.nodes.createNode(this,n); + this.op1 = n.op1 || "1"; + this.op2 = n.op2 || "0"; + this.op1type = n.op1type || "val"; + this.op2type = n.op2type || "val"; + this.extend = n.extend || false; + this.units = n.units || "ms"; + this.duration = n.duration || 250; + if (this.duration <= 0) { this.duration = 0; } + else { + if (this.units == "s") { this.duration = this.duration * 1000; } + if (this.units == "min") { this.duration = this.duration * 1000 * 60; } + if (this.units == "hr") { this.duration = this.duration * 1000 *60 * 60; } + } + this.op1Templated = this.op1.indexOf("{{") != -1; + this.op2Templated = this.op2.indexOf("{{") != -1; + if (!isNaN(this.op1)) { this.op1 = Number(this.op1); } + if (!isNaN(this.op2)) { this.op2 = Number(this.op2); } + if (this.op1 == "true") { this.op1 = true; } + if (this.op2 == "true") { this.op1 = true; } + if (this.op1 == "false") { this.op2 = false; } + if (this.op2 == "false") { this.op2 = false; } + if (this.op1 == "null") { this.op1 = null; } + if (this.op2 == "null") { this.op1 = null; } + try { this.op1 = JSON.parse(this.op1); } + catch(e) { this.op1 = this.op1; } + try { this.op2 = JSON.parse(this.op2); } + catch(e) { this.op2 = this.op2; } + + var node = this; + var tout = null; + var m2; + this.on("input", function(msg) { + if (msg.hasOwnProperty("reset")) { + clearTimeout(tout); + tout = null; + } + else { + if (!tout) { + if (node.op2type === "pay") { m2 = msg.payload; } + else if (node.op2Templated) { m2 = mustache.render(node.op2,msg); } + else { m2 = node.op2; } + if (node.op1type === "pay") { } + else if (node.op1Templated) { msg.payload = mustache.render(node.op1,msg); } + else { msg.payload = node.op1; } + if (node.op1type !== "nul") { node.send(msg); } + if (node.duration === 0) { tout = "infinite"; } + else { + tout = setTimeout(function() { + msg.payload = m2; + if (node.op2type !== "nul") { node.send(msg); } + tout = null; + },node.duration); + } + } + else if ((node.extend == "true") && (node.duration > 0)) { + clearTimeout(tout); + tout = setTimeout(function() { + msg.payload = m2; + if (node.op2type !== "nul") { node.send(msg); } + tout = null; + },node.duration); + } + } + }); + this.on("close", function() { + if (tout) { clearTimeout(tout); } + }); + } + RED.nodes.registerType("trigger",TriggerNode); +} diff --git a/dgbuilder/core_nodes/core/90-comment.html b/dgbuilder/core_nodes/core/90-comment.html new file mode 100644 index 00000000..3638fdaa --- /dev/null +++ b/dgbuilder/core_nodes/core/90-comment.html @@ -0,0 +1,86 @@ + + + + + + + diff --git a/dgbuilder/core_nodes/core/90-comment.js b/dgbuilder/core_nodes/core/90-comment.js new file mode 100644 index 00000000..ef5f0800 --- /dev/null +++ b/dgbuilder/core_nodes/core/90-comment.js @@ -0,0 +1,23 @@ +/** + * Copyright 2013 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + function CommentNode(n) { + RED.nodes.createNode(this,n); + } + RED.nodes.registerType("comment",CommentNode); +} diff --git a/dgbuilder/core_nodes/core/98-unknown.html b/dgbuilder/core_nodes/core/98-unknown.html new file mode 100644 index 00000000..19a4ad59 --- /dev/null +++ b/dgbuilder/core_nodes/core/98-unknown.html @@ -0,0 +1,49 @@ + + + + + + + diff --git a/dgbuilder/core_nodes/core/98-unknown.js b/dgbuilder/core_nodes/core/98-unknown.js new file mode 100644 index 00000000..ed4716b8 --- /dev/null +++ b/dgbuilder/core_nodes/core/98-unknown.js @@ -0,0 +1,23 @@ +/** + * Copyright 2013 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + function UnknownNode(n) { + RED.nodes.createNode(this,n); + } + RED.nodes.registerType("unknown",UnknownNode); +} diff --git a/dgbuilder/core_nodes/deprecated/61-imap.html b/dgbuilder/core_nodes/deprecated/61-imap.html new file mode 100644 index 00000000..9702cd64 --- /dev/null +++ b/dgbuilder/core_nodes/deprecated/61-imap.html @@ -0,0 +1,56 @@ + + + + + + + diff --git a/dgbuilder/core_nodes/deprecated/61-imap.js b/dgbuilder/core_nodes/deprecated/61-imap.js new file mode 100644 index 00000000..aa2b4beb --- /dev/null +++ b/dgbuilder/core_nodes/deprecated/61-imap.js @@ -0,0 +1,139 @@ +/** + * Copyright 2013 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var RED = require(process.env.NODE_RED_HOME+"/red/red"); +var Imap = require('imap'); +var util = require('util'); + +try { + var emailkey = RED.settings.email || require(process.env.NODE_RED_HOME+"/../emailkeys.js"); +} catch (err) { + //util.log("[61-imap.js] Info : No Email credentials found."); +} + +if (emailkey) { + var imap = new Imap({ + user: emailkey.user, + password: emailkey.pass, + host: emailkey.server||"imap.gmail.com", + port: emailkey.port||"993", + tls: true, + tlsOptions: { rejectUnauthorized: false } + }); + + function openInbox(cb) { + imap.openBox('INBOX', true, cb); + } +} + +function ImapNode(n) { + RED.nodes.createNode(this,n); + this.warn("This node has been deprecated and will be deleted in a future release. Please update your flow to use the 'e-mail in' node."); + this.name = n.name; + this.repeat = n.repeat * 1000 || 300000; + var node = this; + this.interval_id = null; + var oldmail = {}; + + if (!isNaN(this.repeat) && this.repeat > 0) { + node.log("repeat = "+this.repeat); + this.interval_id = setInterval( function() { + node.emit("input",{}); + }, this.repeat ); + } + + this.on("input", function(msg) { + if (imap) { + imap.once('ready', function() { + var pay = {}; + openInbox(function(err, box) { + if (box.messages.total > 0) { + var f = imap.seq.fetch(box.messages.total + ':*', { bodies: ['HEADER.FIELDS (FROM SUBJECT DATE)','TEXT'] }); + f.on('message', function(msg, seqno) { + node.log('message: #'+ seqno); + var prefix = '(#' + seqno + ') '; + msg.on('body', function(stream, info) { + var buffer = ''; + stream.on('data', function(chunk) { + buffer += chunk.toString('utf8'); + }); + stream.on('end', function() { + if (info.which !== 'TEXT') { + pay.from = Imap.parseHeader(buffer).from[0]; + pay.topic = Imap.parseHeader(buffer).subject[0]; + pay.date = Imap.parseHeader(buffer).date[0]; + } else { + var parts = buffer.split("Content-Type"); + for (var p in parts) { + if (parts[p].indexOf("text/plain") >= 0) { + pay.payload = parts[p].split("\n").slice(1,-2).join("\n").trim(); + } + if (parts[p].indexOf("text/html") >= 0) { + pay.html = parts[p].split("\n").slice(1,-2).join("\n").trim(); + } + } + //pay.body = buffer; + } + }); + }); + msg.on('end', function() { + //node.log('Finished: '+prefix); + }); + }); + f.on('error', function(err) { + node.warn('fetch error: ' + err); + }); + f.on('end', function() { + if (JSON.stringify(pay) !== oldmail) { + node.send(pay); + oldmail = JSON.stringify(pay); + node.log('sent new message: '+pay.topic); + } + else { node.log('duplicate not sent: '+pay.topic); } + imap.end(); + }); + } + else { + // node.log("you have achieved inbox zero"); + imap.end(); + } + }); + }); + imap.connect(); + } + else { node.warn("No Email credentials found. See info panel."); } + }); + + if (imap) { + imap.on('error', function(err) { + util.log(err); + }); + } + + this.on("error", function(err) { + node.log("error: ",err); + }); + + this.on("close", function() { + if (this.interval_id != null) { + clearInterval(this.interval_id); + } + if (imap) { imap.destroy(); } + }); + + node.emit("input",{}); +} +RED.nodes.registerType("imap",ImapNode); diff --git a/dgbuilder/core_nodes/deprecated/73-parsexml.html b/dgbuilder/core_nodes/deprecated/73-parsexml.html new file mode 100644 index 00000000..b6fc16fe --- /dev/null +++ b/dgbuilder/core_nodes/deprecated/73-parsexml.html @@ -0,0 +1,53 @@ + + + + + + + diff --git a/dgbuilder/core_nodes/deprecated/73-parsexml.js b/dgbuilder/core_nodes/deprecated/73-parsexml.js new file mode 100644 index 00000000..92850cb6 --- /dev/null +++ b/dgbuilder/core_nodes/deprecated/73-parsexml.js @@ -0,0 +1,47 @@ +/** + * Copyright 2013 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + var util = require("util"); + var parseString = require('xml2js').parseString; + var useColors = true; + //util.inspect.styles.boolean = "red"; + + function Xml2jsNode(n) { + RED.nodes.createNode(this,n); + this.warn("This node has been deprecated and will be deleted in a future release. Please update your flow to use the 'xml' node."); + this.useEyes = n.useEyes||false; + var node = this; + this.on("input", function(msg) { + try { + parseString(msg.payload, {strict:true,async:true}, function (err, result) { + //parseString(msg.payload, {strict:false,async:true}, function (err, result) { + if (err) { node.error(err); } + else { + msg.payload = result; + node.send(msg); + if (node.useEyes == true) { + node.log("\n"+util.inspect(msg, {colors:useColors, depth:10})); + } + } + }); + } + catch(e) { util.log("[73-parsexml.js] "+e); } + }); + } + RED.nodes.registerType("xml2js",Xml2jsNode); +} diff --git a/dgbuilder/core_nodes/deprecated/74-js2xml.html b/dgbuilder/core_nodes/deprecated/74-js2xml.html new file mode 100644 index 00000000..f614579b --- /dev/null +++ b/dgbuilder/core_nodes/deprecated/74-js2xml.html @@ -0,0 +1,51 @@ + + + + + + + diff --git a/dgbuilder/core_nodes/deprecated/74-js2xml.js b/dgbuilder/core_nodes/deprecated/74-js2xml.js new file mode 100644 index 00000000..164bafad --- /dev/null +++ b/dgbuilder/core_nodes/deprecated/74-js2xml.js @@ -0,0 +1,39 @@ +/** + * Copyright 2013 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + var js2xmlparser = require("js2xmlparser"); + + function Js2XmlNode(n) { + RED.nodes.createNode(this,n); + this.warn("This node has been deprecated and will be deleted in a future release. Please update your flow to use the 'xml' node."); + this.root = n.root; + var node = this; + + this.on("input", function(msg) { + try { + var root = node.root || typeof msg.payload; + if (typeof msg.payload !== "object") { msg.payload = '"'+msg.payload+'"'; } + console.log(root, typeof msg.payload,msg.payload); + msg.payload = js2xmlparser(root, msg.payload); + node.send(msg); + } + catch(e) { console.log(e); } + }); + } + RED.nodes.registerType("json2xml",Js2XmlNode); +} diff --git a/dgbuilder/core_nodes/deprecated/90-httpget.html b/dgbuilder/core_nodes/deprecated/90-httpget.html new file mode 100644 index 00000000..b1f2e080 --- /dev/null +++ b/dgbuilder/core_nodes/deprecated/90-httpget.html @@ -0,0 +1,61 @@ + + + + + + + diff --git a/dgbuilder/core_nodes/deprecated/90-httpget.js b/dgbuilder/core_nodes/deprecated/90-httpget.js new file mode 100644 index 00000000..63e16b93 --- /dev/null +++ b/dgbuilder/core_nodes/deprecated/90-httpget.js @@ -0,0 +1,53 @@ +/** + * Copyright 2013 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var RED = require(process.env.NODE_RED_HOME+"/red/red"); + +function HttpGet(n) { + RED.nodes.createNode(this,n); + this.warn("This node has been deprecated and will be deleted in a future release. Please update your flow to use the 'http request' node."); + this.baseurl = n.baseurl || ""; + this.append = n.append || ""; + var node = this; + if (this.baseurl.substring(0,5) === "https") { var http = require("https"); } + else { var http = require("http"); } + this.on("input", function(msg) { + msg._payload = msg.payload; + //util.log("[httpget] "+this.baseurl+msg.payload+this.append); + http.get(this.baseurl+msg.payload+this.append, function(res) { + node.log("Http response: " + res.statusCode); + msg.rc = res.statusCode; + msg.payload = ""; + if ((msg.rc != 200) && (msg.rc != 404)) { + node.send(msg); + } + res.setEncoding('utf8'); + res.on('data', function(chunk) { + msg.payload += chunk; + }); + res.on('end', function() { + node.send(msg); + }); + }).on('error', function(e) { + //node.error(e); + msg.rc = 503; + msg.payload = e; + node.send(msg); + }); + }); +} + +RED.nodes.registerType("httpget",HttpGet); diff --git a/dgbuilder/core_nodes/hardware/35-arduino.html b/dgbuilder/core_nodes/hardware/35-arduino.html new file mode 100644 index 00000000..17f02892 --- /dev/null +++ b/dgbuilder/core_nodes/hardware/35-arduino.html @@ -0,0 +1,171 @@ + + + + + + + + + + + + + + + + + diff --git a/dgbuilder/core_nodes/hardware/35-arduino.js b/dgbuilder/core_nodes/hardware/35-arduino.js new file mode 100644 index 00000000..795e9907 --- /dev/null +++ b/dgbuilder/core_nodes/hardware/35-arduino.js @@ -0,0 +1,160 @@ +/** + * Copyright 2013,2014 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + var util = require("util"); + var ArduinoFirmata = require('arduino-firmata'); + var fs = require('fs'); + var plat = require('os').platform(); + var portlist = ArduinoFirmata.list(function (err, ports) { + portlist = ports; + }); + + // The Board Definition - this opens (and closes) the connection + function ArduinoNode(n) { + RED.nodes.createNode(this,n); + this.device = n.device || null; + this.repeat = n.repeat||25; + //node.log("opening connection "+this.device); + var node = this; + node.board = new ArduinoFirmata(); + if (portlist.indexOf(node.device) === -1) { + node.warn("Device "+node.device+" not found"); + } + else { + node.board.connect(node.device); + } + + node.board.on('boardReady', function(){ + node.log("version "+node.board.boardVersion); + }); + + node.on('close', function() { + if (node.board) { + try { + node.board.close(function() { + node.log("port closed"); + }); + } catch(e) { } + } + }); + } + RED.nodes.registerType("arduino-board",ArduinoNode); + + + // The Input Node + function DuinoNodeIn(n) { + RED.nodes.createNode(this,n); + this.buttonState = -1; + this.pin = n.pin; + this.state = n.state; + this.arduino = n.arduino; + this.serverConfig = RED.nodes.getNode(this.arduino); + if (typeof this.serverConfig === "object") { + this.board = this.serverConfig.board; + //this.repeat = this.serverConfig.repeat; + var node = this; + node.status({fill:"red",shape:"ring",text:"connecting"}); + + node.board.on('connect', function() { + node.status({fill:"green",shape:"dot",text:"connected"}); + //console.log("i",node.state,node.pin); + if (node.state == "ANALOG") { + node.board.on('analogChange', function(e) { + if (e.pin == node.pin) { + var msg = {payload:e.value, topic:"A"+e.pin}; + node.send(msg); + } + }); + + } + else { + node.board.pinMode(node.pin, ArduinoFirmata.INPUT); + node.board.on('digitalChange', function(e) { + if (e.pin == node.pin) { + var msg = {payload:e.value, topic:e.pin}; + node.send(msg); + } + }); + } + }); + } + else { + util.log("[Firmata-arduino] port not configured"); + } + } + RED.nodes.registerType("arduino in",DuinoNodeIn); + + + // The Output Node + function DuinoNodeOut(n) { + RED.nodes.createNode(this,n); + this.buttonState = -1; + this.pin = n.pin; + this.state = n.state; + this.arduino = n.arduino; + this.serverConfig = RED.nodes.getNode(this.arduino); + if (typeof this.serverConfig === "object") { + this.board = this.serverConfig.board; + var node = this; + node.status({fill:"red",shape:"ring",text:"connecting"}); + + node.board.on('connect', function() { + node.status({fill:"green",shape:"dot",text:"connected"}); + //console.log("o",node.state,node.pin); + node.board.pinMode(node.pin, node.state); + node.on("input", function(msg) { + if (node.state == "OUTPUT") { + if ((msg.payload == true)||(msg.payload == 1)||(msg.payload.toString().toLowerCase() == "on")) { + node.board.digitalWrite(node.pin, true); + } + if ((msg.payload == false)||(msg.payload == 0)||(msg.payload.toString().toLowerCase() == "off")) { + node.board.digitalWrite(node.pin, false); + } + } + if (node.state == "PWM") { + msg.payload = msg.payload * 1; + if ((msg.payload >= 0) && (msg.payload <= 255)) { + //console.log(msg.payload, node.pin); + node.board.servoWrite(node.pin, msg.payload); + } + } + if (node.state == "SERVO") { + msg.payload = msg.payload * 1; + if ((msg.payload >= 0) && (msg.payload <= 180)) { + //console.log(msg.payload, node.pin); + node.board.servoWrite(node.pin, msg.payload); + } + } + }); + }); + } + else { + util.log("[Firmata-arduino] port not configured"); + } + } + RED.nodes.registerType("arduino out",DuinoNodeOut); + + RED.httpAdmin.get("/arduinoports",function(req,res) { + ArduinoFirmata.list(function (err, ports) { + //console.log(JSON.stringify(ports)); + res.writeHead(200, {'Content-Type': 'text/plain'}); + res.write(JSON.stringify(ports)); + res.end(); + }); + }); +} diff --git a/dgbuilder/core_nodes/hardware/36-rpi-gpio.html b/dgbuilder/core_nodes/hardware/36-rpi-gpio.html new file mode 100644 index 00000000..9e705c2c --- /dev/null +++ b/dgbuilder/core_nodes/hardware/36-rpi-gpio.html @@ -0,0 +1,182 @@ + + + + + + + + + + + + + + diff --git a/dgbuilder/core_nodes/hardware/36-rpi-gpio.js b/dgbuilder/core_nodes/hardware/36-rpi-gpio.js new file mode 100644 index 00000000..93cbc4e0 --- /dev/null +++ b/dgbuilder/core_nodes/hardware/36-rpi-gpio.js @@ -0,0 +1,185 @@ +/** + * Copyright 2013 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + var util = require("util"); + var exec = require('child_process').exec; + var fs = require('fs'); + + var gpioCommand = '/usr/local/bin/gpio'; + + if (!fs.existsSync("/dev/ttyAMA0")) { // unlikely if not on a Pi + throw "Info : Ignoring Raspberry Pi specific node."; + } + + if (!fs.existsSync(gpioCommand)) { // gpio command not installed + throw "Info : Can't find Raspberry Pi wiringPi gpio command."; + } + + // Map physical P1 pins to Gordon's Wiring-Pi Pins (as they should be V1/V2 tolerant) + var pintable = { + // Physical : WiringPi + "11":"0", + "12":"1", + "13":"2", + "15":"3", + "16":"4", + "18":"5", + "22":"6", + "7":"7", + "3":"8", + "5":"9", + "24":"10", + "26":"11", + "19":"12", + "21":"13", + "23":"14", + "8":"15", + "10":"16", + "27":"30", + "28":"31", + "29":"21", + "31":"22", + "32":"26", + "33":"23", + "35":"24", + "36":"27", + "37":"25", + "38":"28", + "40":"29" + } + var tablepin = { + // WiringPi : Physical + "0":"11", + "1":"12", + "2":"13", + "3":"15", + "4":"16", + "5":"18", + "6":"22", + "7":"7", + "8":"3", + "9":"5", + "10":"24", + "11":"26", + "12":"19", + "13":"21", + "14":"23", + "15":"8", + "16":"10", + "30":"27", + "31":"28", + "21":"29", + "22":"31", + "26":"32", + "23":"33", + "24":"35", + "27":"36", + "25":"37", + "28":"38", + "29":"40" + } + + function GPIOInNode(n) { + RED.nodes.createNode(this,n); + this.buttonState = -1; + this.pin = pintable[n.pin]; + this.intype = n.intype; + var node = this; + + if (node.pin !== undefined) { + exec(gpioCommand+" mode "+node.pin+" "+node.intype, function(err,stdout,stderr) { + if (err) { node.error(err); } + else { + node._interval = setInterval( function() { + exec(gpioCommand+" read "+node.pin, function(err,stdout,stderr) { + if (err) { node.error(err); } + else { + if (node.buttonState !== Number(stdout)) { + var previousState = node.buttonState; + node.buttonState = Number(stdout); + if (previousState !== -1) { + var msg = {topic:"pi/"+tablepin[node.pin], payload:node.buttonState}; + node.send(msg); + } + } + } + }); + }, 250); + } + }); + } + else { + node.error("Invalid GPIO pin: "+node.pin); + } + + node.on("close", function() { + clearInterval(node._interval); + }); + } + + function GPIOOutNode(n) { + RED.nodes.createNode(this,n); + this.pin = pintable[n.pin]; + var node = this; + + if (node.pin !== undefined) { + process.nextTick(function() { + exec(gpioCommand+" mode "+node.pin+" out", function(err,stdout,stderr) { + if (err) { node.error(err); } + else { + node.on("input", function(msg) { + if (msg.payload === "true") { msg.payload = true; } + if (msg.payload === "false") { msg.payload = false; } + var out = Number(msg.payload); + if ((out === 0)|(out === 1)) { + exec(gpioCommand+" write "+node.pin+" "+out, function(err,stdout,stderr) { + if (err) { node.error(err); } + }); + } + else { node.warn("Invalid input - not 0 or 1"); } + }); + } + }); + }); + } + else { + node.error("Invalid GPIO pin: "+node.pin); + } + + node.on("close", function() { + exec(gpioCommand+" mode "+node.pin+" in"); + }); + } + + var pitype = { type:"" }; + exec(gpioCommand+" -v | grep Type", function(err,stdout,stderr) { + if (err) { + util.log('[36-rpi-gpio.js] Error: "'+gpioCommand+' -v" command failed for some reason.'); + } + else { + pitype = { type:(stdout.split(","))[0].split(": ")[1], rev:(stdout.split(","))[1].split(": ")[1] }; + } + }); + + RED.nodes.registerType("rpi-gpio in",GPIOInNode); + RED.nodes.registerType("rpi-gpio out",GPIOOutNode); + + RED.httpAdmin.get('/rpi-gpio/:id',function(req,res) { + res.send( JSON.stringify(pitype) ); + }); +} diff --git a/dgbuilder/core_nodes/io/10-mqtt.html b/dgbuilder/core_nodes/io/10-mqtt.html new file mode 100644 index 00000000..2ff5eb29 --- /dev/null +++ b/dgbuilder/core_nodes/io/10-mqtt.html @@ -0,0 +1,157 @@ + + + + + + + + + + + + + + + + + diff --git a/dgbuilder/core_nodes/io/10-mqtt.js b/dgbuilder/core_nodes/io/10-mqtt.js new file mode 100644 index 00000000..c8bc4901 --- /dev/null +++ b/dgbuilder/core_nodes/io/10-mqtt.js @@ -0,0 +1,119 @@ +/** + * Copyright 2013,2014 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + var connectionPool = require("./lib/mqttConnectionPool"); + + function MQTTBrokerNode(n) { + RED.nodes.createNode(this,n); + this.broker = n.broker; + this.port = n.port; + this.clientid = n.clientid; + if (this.credentials) { + this.username = this.credentials.user; + this.password = this.credentials.password; + } + } + RED.nodes.registerType("mqtt-broker",MQTTBrokerNode,{ + credentials: { + user: {type:"text"}, + password: {type: "password"} + } + }); + + function MQTTInNode(n) { + RED.nodes.createNode(this,n); + this.topic = n.topic; + this.broker = n.broker; + this.brokerConfig = RED.nodes.getNode(this.broker); + if (this.brokerConfig) { + this.status({fill:"red",shape:"ring",text:"disconnected"}); + this.client = connectionPool.get(this.brokerConfig.broker,this.brokerConfig.port,this.brokerConfig.clientid,this.brokerConfig.username,this.brokerConfig.password); + var node = this; + this.client.subscribe(this.topic,2,function(topic,payload,qos,retain) { + var msg = {topic:topic,payload:payload,qos:qos,retain:retain}; + if ((node.brokerConfig.broker == "localhost")||(node.brokerConfig.broker == "127.0.0.1")) { + msg._topic = topic; + } + node.send(msg); + }); + this.client.on("connectionlost",function() { + node.status({fill:"red",shape:"ring",text:"disconnected"}); + }); + this.client.on("connect",function() { + node.status({fill:"green",shape:"dot",text:"connected"}); + }); + this.client.connect(); + } else { + this.error("missing broker configuration"); + } + this.on('close', function() { + if (this.client) { + this.client.disconnect(); + } + }); + } + RED.nodes.registerType("mqtt in",MQTTInNode); + + function MQTTOutNode(n) { + RED.nodes.createNode(this,n); + this.topic = n.topic; + this.qos = n.qos || null; + this.retain = n.retain; + this.broker = n.broker; + this.brokerConfig = RED.nodes.getNode(this.broker); + + if (this.brokerConfig) { + this.status({fill:"red",shape:"ring",text:"disconnected"},true); + this.client = connectionPool.get(this.brokerConfig.broker,this.brokerConfig.port,this.brokerConfig.clientid,this.brokerConfig.username,this.brokerConfig.password); + var node = this; + this.on("input",function(msg) { + if (msg.qos) { + msg.qos = parseInt(msg.qos); + if ((msg.qos !== 0) && (msg.qos !== 1) && (msg.qos !== 2)) { + msg.qos = null; + } + } + msg.qos = Number(node.qos || msg.qos || 0); + msg.retain = node.retain || msg.retain || false; + msg.retain = ((msg.retain === true) || (msg.retain === "true")) || false; + if (node.topic) { + msg.topic = node.topic; + } + if ((msg.hasOwnProperty("topic")) && (typeof msg.topic === "string") && (msg.topic !== "")) { // topic must exist + this.client.publish(msg); // send the message + } + else { node.warn("Invalid topic specified"); } + }); + this.client.on("connectionlost",function() { + node.status({fill:"red",shape:"ring",text:"disconnected"}); + }); + this.client.on("connect",function() { + node.status({fill:"green",shape:"dot",text:"connected"}); + }); + this.client.connect(); + } else { + this.error("missing broker configuration"); + } + this.on('close', function() { + if (this.client) { + this.client.disconnect(); + } + }); + } + RED.nodes.registerType("mqtt out",MQTTOutNode); +} diff --git a/dgbuilder/core_nodes/io/21-httpin.html b/dgbuilder/core_nodes/io/21-httpin.html new file mode 100644 index 00000000..059b8596 --- /dev/null +++ b/dgbuilder/core_nodes/io/21-httpin.html @@ -0,0 +1,254 @@ + + + + + + + + + + + + + + + diff --git a/dgbuilder/core_nodes/io/21-httpin.js b/dgbuilder/core_nodes/io/21-httpin.js new file mode 100644 index 00000000..877ccc09 --- /dev/null +++ b/dgbuilder/core_nodes/io/21-httpin.js @@ -0,0 +1,241 @@ +/** + * Copyright 2013,2014 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + var http = require("follow-redirects").http; + var https = require("follow-redirects").https; + var urllib = require("url"); + var express = require("express"); + var getBody = require('raw-body'); + var mustache = require("mustache"); + var querystring = require("querystring"); + + var cors = require('cors'); + var jsonParser = express.json(); + var urlencParser = express.urlencoded(); + + function rawBodyParser(req, res, next) { + if (req._body) { return next(); } + req.body = ""; + req._body = true; + getBody(req, { + limit: '1mb', + length: req.headers['content-length'], + encoding: 'utf8' + }, function (err, buf) { + if (err) { return next(err); } + req.body = buf; + next(); + }); + } + + + function HTTPIn(n) { + RED.nodes.createNode(this,n); + if (RED.settings.httpNodeRoot !== false) { + + this.url = n.url; + this.method = n.method; + + var node = this; + + this.errorHandler = function(err,req,res,next) { + node.warn(err); + res.send(500); + }; + + this.callback = function(req,res) { + if (node.method == "post") { + node.send({req:req,res:res,payload:req.body}); + } else if (node.method == "get") { + node.send({req:req,res:res,payload:req.query}); + } else { + node.send({req:req,res:res}); + } + } + + var corsHandler = function(req,res,next) { next(); } + + if (RED.settings.httpNodeCors) { + corsHandler = cors(RED.settings.httpNodeCors); + RED.httpNode.options(this.url,corsHandler); + } + + if (this.method == "get") { + RED.httpNode.get(this.url,corsHandler,this.callback,this.errorHandler); + } else if (this.method == "post") { + RED.httpNode.post(this.url,corsHandler,jsonParser,urlencParser,rawBodyParser,this.callback,this.errorHandler); + } else if (this.method == "put") { + RED.httpNode.put(this.url,corsHandler,jsonParser,urlencParser,rawBodyParser,this.callback,this.errorHandler); + } else if (this.method == "delete") { + RED.httpNode.delete(this.url,corsHandler,this.callback,this.errorHandler); + } + + this.on("close",function() { + var routes = RED.httpNode.routes[this.method]; + for (var i = 0; i + + + + + + + + + + + + + + + + + + + + + diff --git a/dgbuilder/core_nodes/io/22-websocket.js b/dgbuilder/core_nodes/io/22-websocket.js new file mode 100644 index 00000000..72eda502 --- /dev/null +++ b/dgbuilder/core_nodes/io/22-websocket.js @@ -0,0 +1,185 @@ +/** + * Copyright 2013 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + var ws = require("ws"), + inspect = require("sys").inspect; + + // A node red node that sets up a local websocket server + function WebSocketListenerNode(n) { + // Create a RED node + RED.nodes.createNode(this,n); + + var node = this; + + // Store local copies of the node configuration (as defined in the .html) + node.path = n.path; + node.wholemsg = (n.wholemsg === "true"); + + node._inputNodes = []; // collection of nodes that want to receive events + + var path = RED.settings.httpNodeRoot || "/"; + path = path + (path.slice(-1) == "/" ? "":"/") + (node.path.charAt(0) == "/" ? node.path.substring(1) : node.path); + + // Workaround https://github.com/einaros/ws/pull/253 + // Listen for 'newListener' events from RED.server + node._serverListeners = {}; + + var storeListener = function(/*String*/event,/*function*/listener){ + if(event == "error" || event == "upgrade" || event == "listening"){ + node._serverListeners[event] = listener; + } + } + + node._clients = {}; + + RED.server.addListener('newListener',storeListener); + + // Create a WebSocket Server + node.server = new ws.Server({server:RED.server,path:path}); + + // Workaround https://github.com/einaros/ws/pull/253 + // Stop listening for new listener events + RED.server.removeListener('newListener',storeListener); + + node.server.on('connection', function(socket){ + var id = (1+Math.random()*4294967295).toString(16); + node._clients[id] = socket; + socket.on('close',function() { + delete node._clients[id]; + }); + socket.on('message',function(data,flags){ + node.handleEvent(id,socket,'message',data,flags); + }); + socket.on('error', function(err) { + node.warn("An error occured on the ws connection: "+inspect(err)); + }); + }); + + node.on("close", function() { + // Workaround https://github.com/einaros/ws/pull/253 + // Remove listeners from RED.server + var listener = null; + for(var event in node._serverListeners) { + if (node._serverListeners.hasOwnProperty(event)) { + listener = node._serverListeners[event]; + if(typeof listener === "function"){ + RED.server.removeListener(event,listener); + } + } + } + node._serverListeners = {}; + node.server.close(); + node._inputNodes = []; + }); + } + RED.nodes.registerType("websocket-listener",WebSocketListenerNode); + + WebSocketListenerNode.prototype.registerInputNode = function(/*Node*/handler){ + this._inputNodes.push(handler); + } + + WebSocketListenerNode.prototype.handleEvent = function(id,/*socket*/socket,/*String*/event,/*Object*/data,/*Object*/flags){ + var msg; + if (this.wholemsg) { + try { + msg = JSON.parse(data); + } + catch(err) { + msg = { payload:data }; + } + } else { + msg = { + payload:data + }; + } + msg._session = {type:"websocket",id:id}; + + for (var i = 0; i < this._inputNodes.length; i++) { + this._inputNodes[i].send(msg); + } + } + + WebSocketListenerNode.prototype.broadcast = function(data){ + try { + for (var i = 0; i < this.server.clients.length; i++) { + this.server.clients[i].send(data); + } + } + catch(e) { // swallow any errors + this.warn("ws:"+i+" : "+e); + } + } + + WebSocketListenerNode.prototype.send = function(id,data) { + var session = this._clients[id]; + if (session) { + try { + session.send(data); + } + catch(e) { // swallow any errors + } + } + } + + function WebSocketInNode(n) { + RED.nodes.createNode(this,n); + this.server = n.server; + var node = this; + this.serverConfig = RED.nodes.getNode(this.server); + if (this.serverConfig) { + this.serverConfig.registerInputNode(this); + } else { + this.error("Missing server configuration"); + } + } + RED.nodes.registerType("websocket in",WebSocketInNode); + + function WebSocketOutNode(n) { + RED.nodes.createNode(this,n); + var node = this; + this.server = n.server; + this.serverConfig = RED.nodes.getNode(this.server); + if (!this.serverConfig) { + this.error("Missing server configuration"); + } + this.on("input", function(msg) { + var payload; + if (this.serverConfig.wholemsg) { + delete msg._session; + payload = JSON.stringify(msg); + } else { + if (!Buffer.isBuffer(msg.payload)) { // if it's not a buffer make sure it's a string. + payload = RED.util.ensureString(msg.payload); + } + else { + payload = msg.payload; + } + } + if (msg._session && msg._session.type == "websocket") { + node.serverConfig.send(msg._session.id,payload); + } else { + node.serverConfig.broadcast(payload,function(error){ + if (!!error) { + node.warn("An error occurred while sending:" + inspect(error)); + } + }); + } + }); + } + RED.nodes.registerType("websocket out",WebSocketOutNode); +} diff --git a/dgbuilder/core_nodes/io/23-watch.html b/dgbuilder/core_nodes/io/23-watch.html new file mode 100644 index 00000000..8bf22be5 --- /dev/null +++ b/dgbuilder/core_nodes/io/23-watch.html @@ -0,0 +1,57 @@ + + + + + + + diff --git a/dgbuilder/core_nodes/io/23-watch.js b/dgbuilder/core_nodes/io/23-watch.js new file mode 100644 index 00000000..8a17f5ac --- /dev/null +++ b/dgbuilder/core_nodes/io/23-watch.js @@ -0,0 +1,51 @@ +/** + * Copyright 2013 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + var Notify = require("fs.notify"); + var fs = require("fs"); + var sep = require("path").sep; + + function WatchNode(n) { + RED.nodes.createNode(this,n); + + this.files = n.files.split(","); + for (var f =0; f < this.files.length; f++) { + this.files[f] = this.files[f].trim(); + } + this.p = (this.files.length == 1) ? this.files[0] : JSON.stringify(this.files); + var node = this; + + var notifications = new Notify(node.files); + notifications.on('change', function (file, event, path) { + try { + if (fs.statSync(path).isDirectory()) { path = path + sep + file; } + } catch(e) { } + var msg = { payload: path, topic: node.p, file: file }; + node.send(msg); + }); + + notifications.on('error', function (error, path) { + node.warn(error); + }); + + this.close = function() { + notifications.close(); + } + } + RED.nodes.registerType("watch",WatchNode); +} diff --git a/dgbuilder/core_nodes/io/25-serial.html b/dgbuilder/core_nodes/io/25-serial.html new file mode 100644 index 00000000..225e4dc3 --- /dev/null +++ b/dgbuilder/core_nodes/io/25-serial.html @@ -0,0 +1,265 @@ + + + + + + + + + + + + + + + + + + + diff --git a/dgbuilder/core_nodes/io/25-serial.js b/dgbuilder/core_nodes/io/25-serial.js new file mode 100644 index 00000000..96e4aca6 --- /dev/null +++ b/dgbuilder/core_nodes/io/25-serial.js @@ -0,0 +1,310 @@ +/** +* Copyright 2013,2014 IBM Corp. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +**/ + +module.exports = function(RED) { + "use strict"; + var settings = RED.settings; + var events = require("events"); + var util = require("util"); + var serialp = require("serialport"); + var bufMaxSize = 32768; // Max serial buffer size, for inputs... + + // TODO: 'serialPool' should be encapsulated in SerialPortNode + + function SerialPortNode(n) { + RED.nodes.createNode(this,n); + this.serialport = n.serialport; + this.newline = n.newline; + this.addchar = n.addchar || "false"; + this.serialbaud = parseInt(n.serialbaud) || 57600; + this.databits = parseInt(n.databits) || 8; + this.parity = n.parity || "none"; + this.stopbits = parseInt(n.stopbits) || 1; + this.bin = n.bin || "false"; + this.out = n.out || "char"; + } + RED.nodes.registerType("serial-port",SerialPortNode); + + function SerialOutNode(n) { + RED.nodes.createNode(this,n); + this.serial = n.serial; + this.serialConfig = RED.nodes.getNode(this.serial); + + if (this.serialConfig) { + var node = this; + node.port = serialPool.get(this.serialConfig.serialport, + this.serialConfig.serialbaud, + this.serialConfig.databits, + this.serialConfig.parity, + this.serialConfig.stopbits, + this.serialConfig.newline); + node.addCh = ""; + if (node.serialConfig.addchar == "true") { + node.addCh = this.serialConfig.newline.replace("\\n","\n").replace("\\r","\r").replace("\\t","\t").replace("\\e","\e").replace("\\f","\f").replace("\\0","\0"); + } + node.on("input",function(msg) { + var payload = msg.payload; + if (!Buffer.isBuffer(payload)) { + if (typeof payload === "object") { + payload = JSON.stringify(payload); + } else { + payload = payload.toString(); + } + payload += node.addCh; + } else if (node.addCh !== "") { + payload = Buffer.concat([payload,new Buffer(node.addCh)]); + } + node.port.write(payload,function(err,res) { + if (err) { + node.error(err); + } + }); + }); + node.port.on('ready', function() { + node.status({fill:"green",shape:"dot",text:"connected"}); + }); + node.port.on('closed', function() { + node.status({fill:"red",shape:"ring",text:"not connected"}); + }); + } else { + this.error("missing serial config"); + } + + this.on("close", function(done) { + if (this.serialConfig) { + serialPool.close(this.serialConfig.serialport,done); + } else { + done(); + } + }); + } + RED.nodes.registerType("serial out",SerialOutNode); + + + function SerialInNode(n) { + RED.nodes.createNode(this,n); + this.serial = n.serial; + this.serialConfig = RED.nodes.getNode(this.serial); + + if (this.serialConfig) { + var node = this; + node.tout = null; + var buf; + if (node.serialConfig.out != "count") { buf = new Buffer(bufMaxSize); } + else { buf = new Buffer(Number(node.serialConfig.newline)); } + var i = 0; + node.status({fill:"grey",shape:"dot",text:"unknown"}); + node.port = serialPool.get(this.serialConfig.serialport, + this.serialConfig.serialbaud, + this.serialConfig.databits, + this.serialConfig.parity, + this.serialConfig.stopbits, + this.serialConfig.newline + ); + + var splitc; + if (node.serialConfig.newline.substr(0,2) == "0x") { + splitc = new Buffer([parseInt(node.serialConfig.newline)]); + } else { + splitc = new Buffer(node.serialConfig.newline.replace("\\n","\n").replace("\\r","\r").replace("\\t","\t").replace("\\e","\e").replace("\\f","\f").replace("\\0","\0")); + } + + this.port.on('data', function(msg) { + // single char buffer + if ((node.serialConfig.newline === 0)||(node.serialConfig.newline === "")) { + if (node.serialConfig.bin !== "bin") { node.send({"payload": String.fromCharCode(msg)}); } + else { node.send({"payload": new Buffer([msg])}); } + } + else { + // do the timer thing + if (node.serialConfig.out === "time") { + if (node.tout) { + i += 1; + buf[i] = msg; + } + else { + node.tout = setTimeout(function () { + node.tout = null; + var m = new Buffer(i+1); + buf.copy(m,0,0,i+1); + if (node.serialConfig.bin !== "bin") { m = m.toString(); } + node.send({"payload": m}); + m = null; + }, node.serialConfig.newline); + i = 0; + buf[0] = msg; + } + } + // count bytes into a buffer... + else if (node.serialConfig.out === "count") { + buf[i] = msg; + i += 1; + if ( i >= parseInt(node.serialConfig.newline)) { + var m = new Buffer(i); + buf.copy(m,0,0,i); + if (node.serialConfig.bin !== "bin") { m = m.toString(); } + node.send({"payload":m}); + m = null; + i = 0; + } + } + // look to match char... + else if (node.serialConfig.out === "char") { + buf[i] = msg; + i += 1; + if ((msg === splitc[0]) || (i === bufMaxSize)) { + var m = new Buffer(i); + buf.copy(m,0,0,i); + if (node.serialConfig.bin !== "bin") { m = m.toString(); } + node.send({"payload":m}); + m = null; + i = 0; + } + } + else { console.log("Should never get here"); } + } + }); + this.port.on('ready', function() { + node.status({fill:"green",shape:"dot",text:"connected"}); + }); + this.port.on('closed', function() { + node.status({fill:"red",shape:"ring",text:"not connected"}); + }); + } else { + this.error("missing serial config"); + } + + this.on("close", function(done) { + if (this.serialConfig) { + serialPool.close(this.serialConfig.serialport,done); + } else { + done(); + } + }); + } + RED.nodes.registerType("serial in",SerialInNode); + + + var serialPool = function() { + var connections = {}; + return { + get:function(port,baud,databits,parity,stopbits,newline,callback) { + var id = port; + if (!connections[id]) { + connections[id] = function() { + var obj = { + _emitter: new events.EventEmitter(), + serial: null, + _closing: false, + tout: null, + on: function(a,b) { this._emitter.on(a,b); }, + close: function(cb) { this.serial.close(cb); }, + write: function(m,cb) { this.serial.write(m,cb); }, + } + //newline = newline.replace("\\n","\n").replace("\\r","\r"); + var setupSerial = function() { + //if (newline == "") { + obj.serial = new serialp.SerialPort(port,{ + baudrate: baud, + databits: databits, + parity: parity, + stopbits: stopbits, + parser: serialp.parsers.raw + },true, function(err, results) { if (err) { obj.serial.emit('error',err); } }); + //} + //else { + // obj.serial = new serialp.SerialPort(port,{ + // baudrate: baud, + // databits: databits, + // parity: parity, + // stopbits: stopbits, + // parser: serialp.parsers.readline(newline) + // },true, function(err, results) { if (err) obj.serial.emit('error',err); }); + //} + obj.serial.on('error', function(err) { + util.log("[serial] serial port "+port+" error "+err); + obj._emitter.emit('closed'); + obj.tout = setTimeout(function() { + setupSerial(); + }, settings.serialReconnectTime); + }); + obj.serial.on('close', function() { + if (!obj._closing) { + util.log("[serial] serial port "+port+" closed unexpectedly"); + obj._emitter.emit('closed'); + obj.tout = setTimeout(function() { + setupSerial(); + }, settings.serialReconnectTime); + } + }); + obj.serial.on('open',function() { + util.log("[serial] serial port "+port+" opened at "+baud+" baud "+databits+""+parity.charAt(0).toUpperCase()+stopbits); + if (obj.tout) { clearTimeout(obj.tout); } + //obj.serial.flush(); + obj._emitter.emit('ready'); + }); + obj.serial.on('data',function(d) { + //console.log(Buffer.isBuffer(d),d.length,d); + //if (typeof d !== "string") { + // //d = d.toString(); + for (var z=0; z + + + + + + + + + + + + + + + + + + + + diff --git a/dgbuilder/core_nodes/io/31-tcpin.js b/dgbuilder/core_nodes/io/31-tcpin.js new file mode 100644 index 00000000..2e4e5e7b --- /dev/null +++ b/dgbuilder/core_nodes/io/31-tcpin.js @@ -0,0 +1,472 @@ +/** + * Copyright 2013,2014 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + var reconnectTime = RED.settings.socketReconnectTime||10000; + var socketTimeout = RED.settings.socketTimeout||null; + var net = require('net'); + + var connectionPool = {}; + + function TcpIn(n) { + RED.nodes.createNode(this,n); + this.host = n.host; + this.port = n.port * 1; + this.topic = n.topic; + this.stream = (!n.datamode||n.datamode=='stream'); /* stream,single*/ + this.datatype = n.datatype||'buffer'; /* buffer,utf8,base64 */ + this.newline = (n.newline||"").replace("\\n","\n").replace("\\r","\r"); + this.base64 = n.base64; + this.server = (typeof n.server == 'boolean')?n.server:(n.server == "server"); + this.closing = false; + var node = this; + var count = 0; + + if (!node.server) { + var buffer = null; + var client; + var reconnectTimeout; + var end = false; + var setupTcpClient = function() { + node.log("connecting to "+node.host+":"+node.port); + node.status({fill:"grey",shape:"dot",text:"connecting"}); + var id = (1+Math.random()*4294967295).toString(16); + client = net.connect(node.port, node.host, function() { + buffer = (node.datatype == 'buffer')? new Buffer(0):""; + node.log("connected to "+node.host+":"+node.port); + node.status({fill:"green",shape:"dot",text:"connected"}); + }); + connectionPool[id] = client; + + client.on('data', function (data) { + if (node.datatype != 'buffer') { + data = data.toString(node.datatype); + } + if (node.stream) { + if ((node.datatype) === "utf8" && node.newline != "") { + buffer = buffer+data; + var parts = buffer.split(node.newline); + for (var i = 0;i 0)) { + var msg = {topic:node.topic,payload:buffer}; + msg._session = {type:"tcp",id:id}; + if (buffer.length !== 0) { + end = true; // only ask for fast re-connect if we actually got something + node.send(msg); + } + buffer = null; + } + }); + client.on('close', function() { + delete connectionPool[id]; + node.status({fill:"red",shape:"ring",text:"disconnected"}); + if (!node.closing) { + if (end) { // if we were asked to close then try to reconnect once very quick. + end = false; + reconnectTimeout = setTimeout(setupTcpClient, 20); + } + else { + node.log("connection lost to "+node.host+":"+node.port); + reconnectTimeout = setTimeout(setupTcpClient, reconnectTime); + } + } + }); + client.on('error', function(err) { + node.log(err); + }); + } + setupTcpClient(); + + this.on('close', function() { + this.closing = true; + client.end(); + clearTimeout(reconnectTimeout); + }); + } else { + var server = net.createServer(function (socket) { + if (socketTimeout !== null) { socket.setTimeout(socketTimeout); } + var id = (1+Math.random()*4294967295).toString(16); + connectionPool[id] = socket; + node.status({text:++count+" connections"}); + + var buffer = (node.datatype == 'buffer')? new Buffer(0):""; + socket.on('data', function (data) { + if (node.datatype != 'buffer') { + data = data.toString(node.datatype); + } + if (node.stream) { + if ((typeof data) === "string" && node.newline != "") { + buffer = buffer+data; + var parts = buffer.split(node.newline); + for (var i = 0;i 0) { + var msg = {topic:node.topic,payload:buffer}; + msg._session = {type:"tcp",id:id}; + node.send(msg); + } + buffer = null; + } + }); + socket.on('timeout', function() { + node.log('timeout closed socket port '+node.port); + socket.end(); + }); + socket.on('close', function() { + delete connectionPool[id]; + node.status({text:--count+" connections"}); + }); + socket.on('error',function(err) { + node.log(err); + }); + }); + server.on('error', function(err) { + if (err) { + node.error('unable to listen on port '+node.port+' : '+err); + } + }); + server.listen(node.port, function(err) { + if (err) { + node.error('unable to listen on port '+node.port+' : '+err); + } else { + node.log('listening on port '+node.port); + + node.on('close', function() { + node.closing = true; + server.close(); + node.log('stopped listening on port '+node.port); + }); + } + }); + } + + } + RED.nodes.registerType("tcp in",TcpIn); + + function TcpOut(n) { + RED.nodes.createNode(this,n); + this.host = n.host; + this.port = n.port * 1; + this.base64 = n.base64; + this.doend = n.end || false; + this.beserver = n.beserver; + this.name = n.name; + this.closing = false; + var node = this; + + if (!node.beserver||node.beserver=="client") { + var reconnectTimeout; + var client = null; + var connected = false; + var end = false; + + var setupTcpClient = function() { + node.log("connecting to "+node.host+":"+node.port); + node.status({fill:"grey",shape:"dot",text:"connecting"}); + client = net.connect(node.port, node.host, function() { + connected = true; + node.log("connected to "+node.host+":"+node.port); + node.status({fill:"green",shape:"dot",text:"connected"}); + }); + client.on('error', function (err) { + node.log('error : '+err); + }); + client.on('end', function (err) { + }); + client.on('close', function() { + node.status({fill:"red",shape:"ring",text:"disconnected"}); + connected = false; + client.destroy(); + if (!node.closing) { + if (end) { + end = false; + reconnectTimeout = setTimeout(setupTcpClient,20); + } + else { + node.log("connection lost to "+node.host+":"+node.port); + reconnectTimeout = setTimeout(setupTcpClient,reconnectTime); + } + } + }); + } + setupTcpClient(); + + node.on("input", function(msg) { + if (connected && msg.payload != null) { + if (Buffer.isBuffer(msg.payload)) { + client.write(msg.payload); + } else if (typeof msg.payload === "string" && node.base64) { + client.write(new Buffer(msg.payload,'base64')); + } else { + client.write(new Buffer(""+msg.payload)); + } + if (node.doend === true) { + end = true; + client.end(); + } + } + }); + + node.on("close", function() { + this.closing = true; + client.end(); + clearTimeout(reconnectTimeout); + }); + + } else if (node.beserver == "reply") { + node.on("input",function(msg) { + if (msg._session && msg._session.type == "tcp") { + var client = connectionPool[msg._session.id]; + if (client) { + if (Buffer.isBuffer(msg.payload)) { + client.write(msg.payload); + } else if (typeof msg.payload === "string" && node.base64) { + client.write(new Buffer(msg.payload,'base64')); + } else { + client.write(new Buffer(""+msg.payload)); + } + } + } + }); + } else { + var connectedSockets = []; + node.status({text:"0 connections"}); + var server = net.createServer(function (socket) { + if (socketTimeout !== null) { socket.setTimeout(socketTimeout); } + var remoteDetails = socket.remoteAddress+":"+socket.remotePort; + node.log("connection from "+remoteDetails); + connectedSockets.push(socket); + node.status({text:connectedSockets.length+" connections"}); + socket.on('timeout', function() { + node.log('timeout closed socket port '+node.port); + socket.end(); + }); + socket.on('close',function() { + node.log("connection closed from "+remoteDetails); + connectedSockets.splice(connectedSockets.indexOf(socket),1); + node.status({text:connectedSockets.length+" connections"}); + }); + socket.on('error',function() { + node.log("socket error from "+remoteDetails); + connectedSockets.splice(connectedSockets.indexOf(socket),1); + node.status({text:connectedSockets.length+" connections"}); + }); + }); + + node.on("input", function(msg) { + if (msg.payload != null) { + var buffer; + if (Buffer.isBuffer(msg.payload)) { + buffer = msg.payload; + } else if (typeof msg.payload === "string" && node.base64) { + buffer = new Buffer(msg.payload,'base64'); + } else { + buffer = new Buffer(""+msg.payload); + } + for (var i = 0; i= node.serialConfig.count) { + node.send({"payload": buf}); + client.end(); + i = 0; + } + } + // look for a char + else { + buf[i] = data[j]; + i += 1; + if (data[j] == node.splitc) { + var m = new Buffer(i); + buf.copy(m,0,0,i); + node.send({"payload": m}); + client.end(); + m = null; + i = 0; + } + } + } + } + }); + + client.on('end', function() { + //node.log('client disconnected'); + node.connected = false; + node.status({}); + client = null; + }); + + client.on('error', function() { + node.log('connect failed'); + node.status({fill:"red",shape:"ring",text:"error"}); + if (client) { client.end(); } + }); + + client.on('timeout',function() { + node.log('connect timeout'); + if (client) { + client.end(); + setTimeout(function() { + client.connect(node.port, node.server, function() { + //node.log('client connected'); + node.connected = true; + client.write(msg.payload); + }); + },reconnectTime); + } + }); + } + else { client.write(msg.payload); } + }); + + this.on("close", function() { + if (client) { buf = null; client.end(); } + }); + + } + RED.nodes.registerType("tcp request",TcpGet); +} diff --git a/dgbuilder/core_nodes/io/32-udp.html b/dgbuilder/core_nodes/io/32-udp.html new file mode 100644 index 00000000..1c2eed57 --- /dev/null +++ b/dgbuilder/core_nodes/io/32-udp.html @@ -0,0 +1,212 @@ + + + + + + + + + + + + + + + + + + diff --git a/dgbuilder/core_nodes/io/32-udp.js b/dgbuilder/core_nodes/io/32-udp.js new file mode 100644 index 00000000..a7968e3a --- /dev/null +++ b/dgbuilder/core_nodes/io/32-udp.js @@ -0,0 +1,171 @@ +/** + * Copyright 2013 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + var dgram = require('dgram'); + + // The Input Node + function UDPin(n) { + RED.nodes.createNode(this,n); + this.group = n.group; + this.port = n.port; + this.datatype = n.datatype; + this.iface = n.iface || null; + this.multicast = n.multicast; + var node = this; + + var server = dgram.createSocket('udp4'); + + server.on("error", function (err) { + if ((err.code == "EACCES") && (node.port < 1024)) { + node.error("UDP access error, you may need root access for ports below 1024"); + } else { + node.error("UDP error : "+err.code); + } + server.close(); + }); + + server.on('message', function (message, remote) { + var msg; + if (node.datatype =="base64") { + msg = { payload:message.toString('base64'), fromip:remote.address+':'+remote.port }; + } else if (node.datatype =="utf8") { + msg = { payload:message.toString('utf8'), fromip:remote.address+':'+remote.port }; + } else { + msg = { payload:message, fromip:remote.address+':'+remote.port, ip:remote.address, port:remote.port }; + } + node.send(msg); + }); + + server.on('listening', function () { + var address = server.address(); + node.log('udp listener at ' + address.address + ":" + address.port); + if (node.multicast == "true") { + server.setBroadcast(true); + try { + server.setMulticastTTL(128); + server.addMembership(node.group,node.iface); + node.log("udp multicast group "+node.group); + } catch (e) { + if (e.errno == "EINVAL") { + node.error("Bad Multicast Address"); + } else if (e.errno == "ENODEV") { + node.error("Must be ip address of the required interface"); + } else { + node.error("Error :"+e.errno); + } + } + } + }); + + node.on("close", function() { + try { + server.close(); + node.log('udp listener stopped'); + } catch (err) { + node.error(err); + } + }); + + server.bind(node.port,node.iface); + } + RED.nodes.registerType("udp in",UDPin); + + + // The Output Node + function UDPout(n) { + RED.nodes.createNode(this,n); + //this.group = n.group; + this.port = n.port; + this.outport = n.outport||""; + this.base64 = n.base64; + this.addr = n.addr; + this.iface = n.iface || null; + this.multicast = n.multicast; + var node = this; + + var sock = dgram.createSocket('udp4'); // only use ipv4 for now + + if (node.multicast != "false") { + if (node.outport == "") { node.outport = node.port; } + sock.bind(node.outport, function() { // have to bind before you can enable broadcast... + sock.setBroadcast(true); // turn on broadcast + if (node.multicast == "multi") { + try { + sock.setMulticastTTL(128); + sock.addMembership(node.addr,node.iface); // Add to the multicast group + node.log('udp multicast ready : '+node.outport+' -> '+node.addr+":"+node.port); + } catch (e) { + if (e.errno == "EINVAL") { + node.error("Bad Multicast Address"); + } else if (e.errno == "ENODEV") { + node.error("Must be ip address of the required interface"); + } else { + node.error("Error :"+e.errno); + } + } + } else { + node.log('udp broadcast ready : '+node.outport+' -> '+node.addr+":"+node.port); + } + }); + } else if (node.outport != "") { + sock.bind(node.outport); + node.log('udp ready : '+node.outport+' -> '+node.addr+":"+node.port); + } else { + node.log('udp ready : '+node.addr+":"+node.port); + } + + node.on("input", function(msg) { + if (msg.payload != null) { + var add = node.addr || msg.ip || ""; + var por = node.port || msg.port || 0; + if (add == "") { + node.warn("udp: ip address not set"); + } else if (por == 0) { + node.warn("udp: port not set"); + } else if (isNaN(por) || (por < 1) || (por > 65535)) { + node.warn("udp: port number not valid"); + } else { + var message; + if (node.base64) { + message = new Buffer(msg.payload, 'base64'); + } else if (msg.payload instanceof Buffer) { + message = msg.payload; + } else { + message = new Buffer(""+msg.payload); + } + sock.send(message, 0, message.length, por, add, function(err, bytes) { + if (err) { + node.error("udp : "+err); + } + message = null; + }); + } + } + }); + + node.on("close", function() { + try { + sock.close(); + node.log('udp output stopped'); + } catch (err) { + node.error(err); + } + }); + } + RED.nodes.registerType("udp out",UDPout); +} diff --git a/dgbuilder/core_nodes/io/lib/mqtt.js b/dgbuilder/core_nodes/io/lib/mqtt.js new file mode 100644 index 00000000..141a8889 --- /dev/null +++ b/dgbuilder/core_nodes/io/lib/mqtt.js @@ -0,0 +1,254 @@ +/** + * Copyright 2013 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ +var util = require("util"); +var mqtt = require("mqtt"); +var events = require("events"); +//var inspect = require("sys").inspect; + +//var Client = module.exports.Client = function( + +var port = 1883; +var host = "localhost"; + +function MQTTClient(port,host) { + this.port = port||1883; + this.host = host||"localhost"; + this.messageId = 1; + this.pendingSubscriptions = {}; + this.inboundMessages = {}; + this.lastOutbound = (new Date()).getTime(); + this.lastInbound = (new Date()).getTime(); + this.connected = false; + + this._nextMessageId = function() { + this.messageId += 1; + if (this.messageId > 0xFFFF) { + this.messageId = 1; + } + return this.messageId; + } + events.EventEmitter.call(this); +} +util.inherits(MQTTClient, events.EventEmitter); + +MQTTClient.prototype.connect = function(options) { + if (!this.connected) { + var self = this; + options = options||{}; + self.options = options; + self.options.keepalive = options.keepalive||15; + self.options.clean = self.options.clean||true; + self.options.protocolId = 'MQIsdp'; + self.options.protocolVersion = 3; + + self.client = mqtt.createConnection(this.port,this.host,function(err,client) { + if (err) { + self.connected = false; + clearInterval(self.watchdog); + self.connectionError = true; + //util.log('[mqtt] ['+self.uid+'] connection error 1 : '+inspect(err)); + self.emit('connectionlost',err); + return; + } + client.on('close',function(e) { + //util.log('[mqtt] ['+self.uid+'] on close'); + clearInterval(self.watchdog); + if (!self.connectionError) { + if (self.connected) { + self.connected = false; + self.emit('connectionlost',e); + } else { + self.emit('disconnect'); + } + } + }); + client.on('error',function(e) { + //util.log('[mqtt] ['+self.uid+'] on error : '+inspect(e)); + clearInterval(self.watchdog); + if (self.connected) { + self.connected = false; + self.emit('connectionlost',e); + } + }); + client.on('connack',function(packet) { + if (packet.returnCode == 0) { + self.watchdog = setInterval(function(self) { + var now = (new Date()).getTime(); + + //util.log('[mqtt] ['+self.uid+'] watchdog '+inspect({connected:self.connected,connectionError:self.connectionError,pingOutstanding:self.pingOutstanding,now:now,lastOutbound:self.lastOutbound,lastInbound:self.lastInbound})); + + if (now - self.lastOutbound > self.options.keepalive*500 || now - self.lastInbound > self.options.keepalive*500) { + if (self.pingOutstanding) { + //util.log('[mqtt] ['+self.uid+'] watchdog pingOustanding - disconnect'); + try { + self.client.disconnect(); + } catch (err) { + } + } else { + //util.log('[mqtt] ['+self.uid+'] watchdog pinging'); + self.lastOutbound = (new Date()).getTime(); + self.lastInbound = (new Date()).getTime(); + self.pingOutstanding = true; + self.client.pingreq(); + } + } + + },self.options.keepalive*500,self); + self.pingOutstanding = false; + self.lastInbound = (new Date()).getTime() + self.lastOutbound = (new Date()).getTime() + self.connected = true; + self.connectionError = false; + self.emit('connect'); + } else { + self.connected = false; + self.emit('connectionlost'); + } + }); + client.on('suback',function(packet) { + self.lastInbound = (new Date()).getTime() + var topic = self.pendingSubscriptions[packet.messageId]; + self.emit('subscribe',topic,packet.granted[0]); + delete self.pendingSubscriptions[packet.messageId]; + }); + client.on('unsuback',function(packet) { + self.lastInbound = (new Date()).getTime() + var topic = self.pendingSubscriptions[packet.messageId]; + self.emit('unsubscribe',topic,packet.granted[0]); + delete self.pendingSubscriptions[packet.messageId]; + }); + client.on('publish',function(packet) { + self.lastInbound = (new Date()).getTime() + if (packet.qos < 2) { + var p = packet; + self.emit('message',p.topic,p.payload,p.qos,p.retain); + } else { + self.inboundMessages[packet.messageId] = packet; + this.lastOutbound = (new Date()).getTime() + self.client.pubrec(packet); + } + if (packet.qos == 1) { + this.lastOutbound = (new Date()).getTime() + self.client.puback(packet); + } + }); + + client.on('pubrel',function(packet) { + self.lastInbound = (new Date()).getTime() + var p = self.inboundMessages[packet.messageId]; + if (p) { + self.emit('message',p.topic,p.payload,p.qos,p.retain); + delete self.inboundMessages[packet.messageId]; + } + self.lastOutbound = (new Date()).getTime() + self.client.pubcomp(packet); + }); + + client.on('puback',function(packet) { + self.lastInbound = (new Date()).getTime() + // outbound qos-1 complete + }); + + client.on('pubrec',function(packet) { + self.lastInbound = (new Date()).getTime() + self.lastOutbound = (new Date()).getTime() + self.client.pubrel(packet); + }); + client.on('pubcomp',function(packet) { + self.lastInbound = (new Date()).getTime() + // outbound qos-2 complete + }); + client.on('pingresp',function(packet) { + //util.log('[mqtt] ['+self.uid+'] received pingresp'); + self.lastInbound = (new Date()).getTime() + self.pingOutstanding = false; + }); + + this.lastOutbound = (new Date()).getTime() + this.connectionError = false; + client.connect(self.options); + }); + } +} + +MQTTClient.prototype.subscribe = function(topic,qos) { + var self = this; + if (self.connected) { + var options = { + subscriptions:[{topic:topic,qos:qos}], + messageId: self._nextMessageId() + }; + this.pendingSubscriptions[options.messageId] = topic; + this.lastOutbound = (new Date()).getTime() + self.client.subscribe(options); + } +} +MQTTClient.prototype.unsubscribe = function(topic) { + var self = this; + if (self.connected) { + var options = { + topic:topic, + messageId: self._nextMessageId() + }; + this.pendingSubscriptions[options.messageId] = topic; + this.lastOutbound = (new Date()).getTime() + self.client.unsubscribe(options); + } +} + +MQTTClient.prototype.publish = function(topic,payload,qos,retain) { + var self = this; + if (self.connected) { + + if (!Buffer.isBuffer(payload)) { + if (typeof payload === "object") { + payload = JSON.stringify(payload); + } else if (typeof payload !== "string") { + payload = ""+payload; + } + } + var options = { + topic: topic, + payload: payload, + qos: qos||0, + retain:retain||false + }; + if (options.qos != 0) { + options.messageId = self._nextMessageId(); + } + this.lastOutbound = (new Date()).getTime() + self.client.publish(options); + } +} + +MQTTClient.prototype.disconnect = function() { + var self = this; + if (this.connected) { + this.connected = false; + try { + this.client.disconnect(); + } catch(err) { + } + } +} +MQTTClient.prototype.isConnected = function() { + return this.connected; +} +module.exports.createClient = function(port,host) { + var mqtt_client = new MQTTClient(port,host); + return mqtt_client; +} + diff --git a/dgbuilder/core_nodes/io/lib/mqttConnectionPool.js b/dgbuilder/core_nodes/io/lib/mqttConnectionPool.js new file mode 100644 index 00000000..d15f0fc7 --- /dev/null +++ b/dgbuilder/core_nodes/io/lib/mqttConnectionPool.js @@ -0,0 +1,128 @@ +/** + * Copyright 2013 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ +var util = require("util"); +var mqtt = require("./mqtt"); +var settings = require(process.env.NODE_RED_HOME+"/red/red").settings; + +var connections = {}; + +function matchTopic(ts,t) { + if (ts == "#") { + return true; + } + var re = new RegExp("^"+ts.replace(/([\[\]\?\(\)\\\\$\^\*\.|])/g,"\\$1").replace(/\+/g,"[^/]+").replace(/\/#$/,"(\/.*)?")+"$"); + return re.test(t); +} + +module.exports = { + get: function(broker,port,clientid,username,password,will) { + var id = "["+(username||"")+":"+(password||"")+"]["+(clientid||"")+"]@"+broker+":"+port; + if (!connections[id]) { + connections[id] = function() { + var uid = (1+Math.random()*4294967295).toString(16); + var client = mqtt.createClient(port,broker); + client.uid = uid; + client.setMaxListeners(0); + var options = {keepalive:15}; + options.clientId = clientid || 'mqtt_' + (1+Math.random()*4294967295).toString(16); + options.username = username; + options.password = password; + options.will = will; + var queue = []; + var subscriptions = []; + var connecting = false; + var obj = { + _instances: 0, + publish: function(msg) { + if (client.isConnected()) { + client.publish(msg.topic,msg.payload,msg.qos,msg.retain); + } else { + if (!connecting) { + connecting = true; + client.connect(options); + } + queue.push(msg); + } + }, + subscribe: function(topic,qos,callback) { + subscriptions.push({topic:topic,qos:qos,callback:callback}); + client.on('message',function(mtopic,mpayload,mqos,mretain) { + if (matchTopic(topic,mtopic)) { + callback(mtopic,mpayload,mqos,mretain); + } + }); + if (client.isConnected()) { + client.subscribe(topic,qos); + } + }, + on: function(a,b){ + client.on(a,b); + }, + once: function(a,b){ + client.once(a,b); + }, + connect: function() { + if (client && !client.isConnected() && !connecting) { + connecting = true; + client.connect(options); + } + }, + disconnect: function() { + this._instances -= 1; + if (this._instances == 0) { + client.disconnect(); + client = null; + delete connections[id]; + } + } + }; + client.on('connect',function() { + if (client) { + util.log('[mqtt] ['+uid+'] connected to broker tcp://'+broker+':'+port); + connecting = false; + for (var s in subscriptions) { + var topic = subscriptions[s].topic; + var qos = subscriptions[s].qos; + var callback = subscriptions[s].callback; + client.subscribe(topic,qos); + } + //console.log("connected - publishing",queue.length,"messages"); + while(queue.length) { + var msg = queue.shift(); + //console.log(msg); + client.publish(msg.topic,msg.payload,msg.qos,msg.retain); + } + } + }); + client.on('connectionlost', function(err) { + util.log('[mqtt] ['+uid+'] connection lost to broker tcp://'+broker+':'+port); + connecting = false; + setTimeout(function() { + obj.connect(); + }, settings.mqttReconnectTime||5000); + }); + client.on('disconnect', function() { + connecting = false; + util.log('[mqtt] ['+uid+'] disconnected from broker tcp://'+broker+':'+port); + }); + + return obj + }(); + } + connections[id]._instances += 1; + return connections[id]; + } +}; diff --git a/dgbuilder/core_nodes/logic/10-switch.html b/dgbuilder/core_nodes/logic/10-switch.html new file mode 100644 index 00000000..4e02f446 --- /dev/null +++ b/dgbuilder/core_nodes/logic/10-switch.html @@ -0,0 +1,198 @@ + + + + + + + diff --git a/dgbuilder/core_nodes/logic/10-switch.js b/dgbuilder/core_nodes/logic/10-switch.js new file mode 100644 index 00000000..8bcb8571 --- /dev/null +++ b/dgbuilder/core_nodes/logic/10-switch.js @@ -0,0 +1,78 @@ +/** + * Copyright 2013 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + var operators = { + 'eq': function(a, b) { return a == b; }, + 'neq': function(a, b) { return a != b; }, + 'lt': function(a, b) { return a < b; }, + 'lte': function(a, b) { return a <= b; }, + 'gt': function(a, b) { return a > b; }, + 'gte': function(a, b) { return a >= b; }, + 'btwn': function(a, b, c) { return a >= b && a <= c; }, + 'cont': function(a, b) { return (a + "").indexOf(b) != -1; }, + 'regex': function(a, b) { return (a + "").match(new RegExp(b)); }, + 'true': function(a) { return a === true; }, + 'false': function(a) { return a === false; }, + 'null': function(a) { return typeof a == "undefined"; }, + 'nnull': function(a) { return typeof a != "undefined"; }, + 'else': function(a) { return a === true; } + }; + + function SwitchNode(n) { + RED.nodes.createNode(this, n); + this.rules = n.rules; + this.property = n.property; + this.checkall = n.checkall || "true"; + var propertyParts = n.property.split("."); + var node = this; + + for (var i=0; i + + + + + + diff --git a/dgbuilder/core_nodes/logic/15-change.js b/dgbuilder/core_nodes/logic/15-change.js new file mode 100644 index 00000000..b7ef62e1 --- /dev/null +++ b/dgbuilder/core_nodes/logic/15-change.js @@ -0,0 +1,74 @@ +/** + * Copyright 2013 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + function ChangeNode(n) { + RED.nodes.createNode(this, n); + this.action = n.action; + this.property = n.property || ""; + this.from = n.from || " "; + this.to = n.to || " "; + this.reg = (n.reg === null || n.reg); + var node = this; + if (node.reg === false) { + this.from = this.from.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"); + } + var makeNew = function( stem, path, value ) { + var lastPart = (arguments.length === 3) ? path.pop() : false; + for (var i = 0; i < path.length; i++) { + stem = stem[path[i]] = stem[path[i]] || {}; + } + if (lastPart) { stem = stem[lastPart] = value; } + return stem; + }; + + this.on('input', function (msg) { + if (node.action == "change") { + try { + node.re = new RegExp(this.from, "g"); + } catch (e) { + node.error(e.message); + } + if (typeof msg[node.property] === "string") { + msg[node.property] = (msg[node.property]).replace(node.re, node.to); + } + } + //else if (node.action == "replace") { + //if (node.to.indexOf("msg.") == 0) { + //msg[node.property] = eval(node.to); + //} + //else { + //msg[node.property] = node.to; + //} + //} + else if (node.action == "replace") { + if (node.to.indexOf("msg.") === 0) { + makeNew( msg, node.property.split("."), eval(node.to) ); + } + else { + makeNew( msg, node.property.split("."), node.to ); + } + //makeNew( msg, node.property.split("."), node.to ); + } + else if (node.action == "delete") { + delete(msg[node.property]); + } + node.send(msg); + }); + } + RED.nodes.registerType("change", ChangeNode); +} diff --git a/dgbuilder/core_nodes/logic/16-range.html b/dgbuilder/core_nodes/logic/16-range.html new file mode 100644 index 00000000..5f87128f --- /dev/null +++ b/dgbuilder/core_nodes/logic/16-range.html @@ -0,0 +1,81 @@ + + + + + + + diff --git a/dgbuilder/core_nodes/logic/16-range.js b/dgbuilder/core_nodes/logic/16-range.js new file mode 100644 index 00000000..ec39342a --- /dev/null +++ b/dgbuilder/core_nodes/logic/16-range.js @@ -0,0 +1,48 @@ +/** + * Copyright 2013 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + function RangeNode(n) { + RED.nodes.createNode(this, n); + this.action = n.action; + this.round = n.round || false; + this.minin = Number(n.minin); + this.maxin = Number(n.maxin); + this.minout = Number(n.minout); + this.maxout = Number(n.maxout); + var node = this; + + this.on('input', function (msg) { + var n = Number(msg.payload); + if (!isNaN(n)) { + if (node.action == "clamp") { + if (n < node.minin) { n = node.minin; } + if (n > node.maxin) { n = node.maxin; } + } + if (node.action == "roll") { + if (n >= node.maxin) { n = (n - node.minin) % (node.maxin - node.minin) + node.minin; } + if (n < node.minin) { n = (n - node.minin) % (node.maxin - node.minin) + node.maxin; } + } + msg.payload = ((n - node.minin) / (node.maxin - node.minin) * (node.maxout - node.minout)) + node.minout; + if (node.round) { msg.payload = Math.round(msg.payload); } + node.send(msg); + } + else { node.log("Not a number: "+msg.payload); } + }); + } + RED.nodes.registerType("range", RangeNode); +} diff --git a/dgbuilder/core_nodes/parsers/70-CSV.html b/dgbuilder/core_nodes/parsers/70-CSV.html new file mode 100644 index 00000000..5632246f --- /dev/null +++ b/dgbuilder/core_nodes/parsers/70-CSV.html @@ -0,0 +1,123 @@ + + + + + + + + diff --git a/dgbuilder/core_nodes/parsers/70-CSV.js b/dgbuilder/core_nodes/parsers/70-CSV.js new file mode 100644 index 00000000..56aa7c72 --- /dev/null +++ b/dgbuilder/core_nodes/parsers/70-CSV.js @@ -0,0 +1,157 @@ +/** + * Copyright 2014 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + function CSVNode(n) { + RED.nodes.createNode(this,n); + this.template = n.temp.split(","); + this.sep = (n.sep || ',').replace("\\t","\t").replace("\\n","\n").replace("\\r","\r"); + this.quo = '"'; + this.ret = (n.ret || "\n").replace("\\n","\n").replace("\\r","\r"); + this.winflag = (this.ret === "\r\n"); + this.lineend = "\n"; + this.multi = n.multi || "one"; + this.hdrin = n.hdrin || false; + this.hdrout = n.hdrout || false; + this.goodtmpl = true; + var node = this; + + // pass in an array of column names to be trimed, de-quoted and retrimed + var clean = function(col) { + for (var t = 0; t < col.length; t++) { + col[t] = col[t].trim(); // remove leading and trailing whitespace + if (col[t].charAt(0) === '"' && col[t].charAt(col[t].length -1) === '"') { + // remove leading and trailing quotes (if they exist) - and remove whitepace again. + col[t] = col[t].substr(1,col[t].length -2).trim(); + } + } + if ((col.length === 1) && (col[0] === "")) { node.goodtmpl = false; } + else { node.goodtmpl = true; } + return col; + } + node.template = clean(node.template); + + this.on("input", function(msg) { + if (msg.hasOwnProperty("payload")) { + if (typeof msg.payload == "object") { // convert object to CSV string + try { + var ou = ""; + if (node.hdrout) { + ou += node.template.join(node.sep) + node.ret; + } + if (!Array.isArray(msg.payload)) { msg.payload = [ msg.payload ]; } + for (var s = 0; s < msg.payload.length; s++) { + for (var t=0; t < node.template.length; t++) { + + // aaargh - resorting to eval here - but fairly contained front and back. + var p = RED.util.ensureString(eval("msg.payload[s]."+node.template[t])); + + if (p === "undefined") { p = ""; } + if (p.indexOf(node.sep) != -1) { // add quotes if any "commas" + ou += node.quo + p + node.quo + node.sep; + } + else if (p.indexOf(node.quo) != -1) { // add double quotes if any quotes + p = p.replace(/"/g, '""'); + ou += node.quo + p + node.quo + node.sep; + } + else { ou += p + node.sep; } // otherwise just add + } + ou = ou.slice(0,-1) + node.ret; // remove final "comma" and add "newline" + } + node.send({payload:ou}); + } + catch(e) { node.log(e); } + } + else if (typeof msg.payload == "string") { // convert CSV string to object + try { + var f = true; // flag to indicate if inside or outside a pair of quotes true = outside. + var j = 0; // pointer into array of template items + var k = [""]; // array of data for each of the template items + var o = {}; // output object to build up + var a = []; // output array is needed for multiline option + var first = true; // is this the first line + var tmp = ""; + + // For now we are just going to assume that any \r or \n means an end of line... + // got to be a weird csv that has singleton \r \n in it for another reason... + + // Now process the whole file/line + for (var i = 0; i < msg.payload.length; i++) { + if ((node.hdrin === true) && first) { // if the template is in the first line + if ((msg.payload[i] === "\n")||(msg.payload[i] === "\r")) { // look for first line break + node.template = clean(tmp.split(node.sep)); + first = false; + } + else { tmp += msg.payload[i]; } + } + else { + if (msg.payload[i] === node.quo) { // if it's a quote toggle inside or outside + f = !f; + if (msg.payload[i-1] === node.quo) { k[j] += '\"'; } // if it's a quotequote then it's actually a quote + } + else if ((msg.payload[i] === node.sep) && f) { // if we are outside of quote (ie valid separator + if (!node.goodtmpl) { node.template[j] = "col"+(j+1); } + if ( node.template[j] && (node.template[j] !== "") && (k[j] !== "" ) ) { + if (!isNaN(Number(k[j]))) { k[j] = Number(k[j]); } + o[node.template[j]] = k[j]; + } + j += 1; + k[j] = ""; + } + else if (f && ((msg.payload[i] === "\n") || (msg.payload[i] === "\r"))) { // handle multiple lines + //console.log(j,k,o,k[j]); + if ( node.template[j] && (node.template[j] !== "") && (k[j] !== "") ) { + if (!isNaN(Number(k[j]))) { k[j] = Number(k[j]); } + else { k[j].replace(/\r$/,''); } + o[node.template[j]] = k[j]; + } + if (JSON.stringify(o) !== "{}") { // don't send empty objects + if (node.multi === "one") { node.send({payload:o}); } // either send + else { a.push(o); } // or add to the array + } + j = 0; + k = [""]; + o = {}; + } + else { // just add to the part of the message + k[j] += msg.payload[i]; + } + } + } + // Finished so finalize and send anything left + //console.log(j,k,o,k[j]); + if (!node.goodtmpl) { node.template[j] = "col"+(j+1); } + if ( node.template[j] && (node.template[j] !== "") && (k[j] !== "") ) { + if (!isNaN(Number(k[j]))) { k[j] = Number(k[j]); } + else { k[j].replace(/\r$/,''); } + o[node.template[j]] = k[j]; + } + msg.payload = o; + if (JSON.stringify(o) !== "{}") { // don't send empty objects + if (node.multi === "one") { node.send({payload:o}); } // either send + else { a.push(o); } // or add to the aray + } + if (node.multi !== "one") { node.send({payload:a}); } // finally send the array + } + catch(e) { node.log(e); } + } + else { node.log("This node only handles csv strings or js objects."); } + } + }); + } + RED.nodes.registerType("csv",CSVNode); +} diff --git a/dgbuilder/core_nodes/parsers/70-HTML.html b/dgbuilder/core_nodes/parsers/70-HTML.html new file mode 100644 index 00000000..2b73b49c --- /dev/null +++ b/dgbuilder/core_nodes/parsers/70-HTML.html @@ -0,0 +1,73 @@ + + + + + + + diff --git a/dgbuilder/core_nodes/parsers/70-HTML.js b/dgbuilder/core_nodes/parsers/70-HTML.js new file mode 100644 index 00000000..7a9450f3 --- /dev/null +++ b/dgbuilder/core_nodes/parsers/70-HTML.js @@ -0,0 +1,60 @@ +/** + * Copyright 2014 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + var cheerio = require('cheerio'); + + function CheerioNode(n) { + RED.nodes.createNode(this,n); + this.tag = n.tag || "h1"; + this.ret = n.ret || "html"; + this.as = n.as || "single"; + var node = this; + this.on("input", function(msg) { + try { + var $ = cheerio.load(msg.payload); + var pay = []; + $(node.tag).each(function() { + if (node.as === "multi") { + var pay2 = null; + if (node.ret === "html") { pay2 = $(this).html(); } + if (node.ret === "text") { pay2 = $(this).text(); } + //if (node.ret === "attr") { pay2 = $(this)[0]["attribs"]; } + //if (node.ret === "val") { pay2 = $(this).val(); } + if (pay2) { + msg.payload = pay2; + node.send(msg); + } + } + if (node.as === "single") { + if (node.ret === "html") { pay.push( $(this).html() ); } + if (node.ret === "text") { pay.push( $(this).text() ); } + //if (node.ret === "attr") { pay.push( $(this)[0]["attribs"] ); } + //if (node.ret === "val") { pay.push( $(this).val() ); } + } + }); + if ((node.as === "single") && (pay.length !== 0)) { + msg.payload = pay; + node.send(msg); + } + } catch (error) { + node.log('Error: '+error.message); + } + }); + } + RED.nodes.registerType("html",CheerioNode); +} diff --git a/dgbuilder/core_nodes/parsers/70-JSON.html b/dgbuilder/core_nodes/parsers/70-JSON.html new file mode 100644 index 00000000..864974ab --- /dev/null +++ b/dgbuilder/core_nodes/parsers/70-JSON.html @@ -0,0 +1,47 @@ + + + + + + + diff --git a/dgbuilder/core_nodes/parsers/70-JSON.js b/dgbuilder/core_nodes/parsers/70-JSON.js new file mode 100644 index 00000000..e216bd4f --- /dev/null +++ b/dgbuilder/core_nodes/parsers/70-JSON.js @@ -0,0 +1,46 @@ +/** + * Copyright 2014 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + var util = require("util"); + + function JSONNode(n) { + RED.nodes.createNode(this,n); + var node = this; + this.on("input", function(msg) { + if (msg.hasOwnProperty("payload")) { + if (typeof msg.payload === "string") { + try { + msg.payload = JSON.parse(msg.payload); + node.send(msg); + } + catch(e) { node.log(e+ "\n"+msg.payload); } + } + else if (typeof msg.payload === "object") { + if (!Buffer.isBuffer(msg.payload) ) { + if (!util.isArray(msg.payload)) { + msg.payload = JSON.stringify(msg.payload); + node.send(msg); + } + } + } + else { node.log("dropped: "+msg.payload); } + } + }); + } + RED.nodes.registerType("json",JSONNode); +} diff --git a/dgbuilder/core_nodes/parsers/70-XML.html b/dgbuilder/core_nodes/parsers/70-XML.html new file mode 100644 index 00000000..8b0a2843 --- /dev/null +++ b/dgbuilder/core_nodes/parsers/70-XML.html @@ -0,0 +1,48 @@ + + + + + + + diff --git a/dgbuilder/core_nodes/parsers/70-XML.js b/dgbuilder/core_nodes/parsers/70-XML.js new file mode 100644 index 00000000..931de7f5 --- /dev/null +++ b/dgbuilder/core_nodes/parsers/70-XML.js @@ -0,0 +1,46 @@ +/** + * Copyright 2014 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + var xml2js = require('xml2js'); + var parseString = xml2js.parseString; + var builder = new xml2js.Builder({renderOpts:{pretty:false}}); + + function XMLNode(n) { + RED.nodes.createNode(this,n); + var node = this; + this.on("input", function(msg) { + if (msg.hasOwnProperty("payload")) { + if (typeof msg.payload == "object") { + msg.payload = builder.buildObject(msg.payload); + node.send(msg); + } + else if (typeof msg.payload == "string") { + parseString(msg.payload, {strict:true,async:true}, function (err, result) { + if (err) { node.error(err); } + else { + msg.payload = result; + node.send(msg); + } + }); + } + else { node.log("This node only handles xml strings or js objects."); } + } + }); + } + RED.nodes.registerType("xml",XMLNode); +} diff --git a/dgbuilder/core_nodes/social/27-twitter.html b/dgbuilder/core_nodes/social/27-twitter.html new file mode 100644 index 00000000..99d45213 --- /dev/null +++ b/dgbuilder/core_nodes/social/27-twitter.html @@ -0,0 +1,223 @@ + + + + + + + + + + + + + + + + + + diff --git a/dgbuilder/core_nodes/social/27-twitter.js b/dgbuilder/core_nodes/social/27-twitter.js new file mode 100644 index 00000000..5cacd9eb --- /dev/null +++ b/dgbuilder/core_nodes/social/27-twitter.js @@ -0,0 +1,347 @@ +/** + * Copyright 2013 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + var ntwitter = require('twitter-ng'); + var OAuth= require('oauth').OAuth; + var request = require('request'); + + function TwitterNode(n) { + RED.nodes.createNode(this,n); + this.screen_name = n.screen_name; + } + RED.nodes.registerType("twitter-credentials",TwitterNode,{ + credentials: { + screen_name: {type:"text"}, + access_token: {type: "password"}, + access_token_secret: {type:"password"} + } + }); + + function TwitterInNode(n) { + RED.nodes.createNode(this,n); + this.active = true; + this.user = n.user; + //this.tags = n.tags.replace(/ /g,''); + this.tags = n.tags; + this.twitter = n.twitter; + this.topic = n.topic||"tweets"; + this.twitterConfig = RED.nodes.getNode(this.twitter); + var credentials = RED.nodes.getCredentials(this.twitter); + + if (credentials && credentials.screen_name == this.twitterConfig.screen_name) { + var twit = new ntwitter({ + consumer_key: "OKjYEd1ef2bfFolV25G5nQ", + consumer_secret: "meRsltCktVMUI8gmggpXett7WBLd1k0qidYazoML6g", + access_token_key: credentials.access_token, + access_token_secret: credentials.access_token_secret + }); + + + //setInterval(function() { + // twit.get("/application/rate_limit_status.json",null,function(err,cb) { + // console.log("direct_messages:",cb["resources"]["direct_messages"]); + // }); + // + //},10000); + + var node = this; + if (this.user === "user") { + node.poll_ids = []; + node.since_ids = {}; + var users = node.tags.split(","); + for (var i=0;i=0;t-=1) { + var tweet = cb[t]; + var where = tweet.user.location||""; + var la = tweet.lang || tweet.user.lang; + //console.log(tweet.user.location,"=>",tweet.user.screen_name,"=>",pay); + var msg = { topic:node.topic+"/"+tweet.user.screen_name, payload:tweet.text, location:where, lang:la, tweet:tweet }; + node.send(msg); + if (t == 0) { + node.since_ids[u] = tweet.id_str; + } + } + } + if (err) { + node.error(err); + } + }); + },60000)); + } + }()); + } + } else if (this.user === "dm") { + node.poll_ids = []; + twit.getDirectMessages({ + screen_name:node.twitterConfig.screen_name, + trim_user:0, + count:1 + },function(err,cb) { + if (err) { + node.error(err); + return; + } + if (cb[0]) { + node.since_id = cb[0].id_str; + } else { + node.since_id = '0'; + } + node.poll_ids.push(setInterval(function() { + twit.getDirectMessages({ + screen_name:node.twitterConfig.screen_name, + trim_user:0, + since_id:node.since_id + },function(err,cb) { + if (cb) { + for (var t=cb.length-1;t>=0;t-=1) { + var tweet = cb[t]; + var msg = { topic:node.topic+"/"+tweet.sender.screen_name, payload:tweet.text, tweet:tweet }; + node.send(msg); + if (t == 0) { + node.since_id = tweet.id_str; + } + } + } + if (err) { + node.error(err); + } + }); + },120000)); + }); + + } else if (this.tags !== "") { + try { + var thing = 'statuses/filter'; + if (this.user === "true") { thing = 'user'; } + var st = { track: [node.tags] }; + var bits = node.tags.split(","); + if ((bits.length > 0) && (bits.length % 4 == 0)) { + if ((Number(bits[0]) < Number(bits[2])) && (Number(bits[1]) < Number(bits[3]))) { + st = { locations: node.tags }; + } + else { + node.log("possible bad geo area format. Should be lower-left lon, lat, upper-right lon, lat"); + } + } + + var setupStream = function() { + if (node.active) { + twit.stream(thing, st, function(stream) { + //console.log(st); + //twit.stream('user', { track: [node.tags] }, function(stream) { + //twit.stream('site', { track: [node.tags] }, function(stream) { + //twit.stream('statuses/filter', { track: [node.tags] }, function(stream) { + node.stream = stream; + stream.on('data', function(tweet) { + //console.log(tweet.user); + if (tweet.user !== undefined) { + var where = tweet.user.location||""; + var la = tweet.lang || tweet.user.lang; + //console.log(tweet.user.location,"=>",tweet.user.screen_name,"=>",pay); + var msg = { topic:node.topic+"/"+tweet.user.screen_name, payload:tweet.text, location:where, lang:la, tweet:tweet }; + node.send(msg); + } + }); + stream.on('limit', function(tweet) { + node.log("tweet rate limit hit"); + }); + stream.on('error', function(tweet,rc) { + if (rc == 420) { + node.warn("Twitter rate limit hit"); + } else { + node.warn("Stream error:"+tweet.toString()+" ("+rc+")"); + } + setTimeout(setupStream,10000); + }); + stream.on('destroy', function (response) { + if (this.active) { + node.warn("twitter ended unexpectedly"); + setTimeout(setupStream,10000); + } + }); + }); + } + } + setupStream(); + } + catch (err) { + node.error(err); + } + } else { + this.error("Invalid tag property"); + } + } else { + this.error("missing twitter credentials"); + } + + this.on('close', function() { + if (this.stream) { + this.active = false; + this.stream.destroy(); + } + if (this.poll_ids) { + for (var i=0;i 140) { + msg.payload = msg.payload.slice(0,139); + node.warn("Tweet greater than 140 : truncated"); + } + + if (msg.media && Buffer.isBuffer(msg.media)) { + var apiUrl = "https://api.twitter.com/1.1/statuses/update_with_media.json"; + var signedUrl = oa.signUrl(apiUrl, + credentials.access_token, + credentials.access_token_secret, + "POST"); + + var r = request.post(signedUrl,function(err,httpResponse,body) { + if (err) { + node.error(err.toString()); + node.status({fill:"red",shape:"ring",text:"failed"}); + } else { + var response = JSON.parse(body); + if (body.errors) { + var errorList = body.errors.map(function(er) { return er.code+": "+er.message }).join(", "); + node.error("tweet failed: "+errorList); + node.status({fill:"red",shape:"ring",text:"failed"}); + } else { + node.status({}); + } + } + }); + var form = r.form(); + form.append("status",msg.payload); + form.append("media[]",msg.media,{filename:"image"}); + + } else { + twit.updateStatus(msg.payload, function (err, data) { + if (err) { + node.status({fill:"red",shape:"ring",text:"failed"}); + node.error(err); + } + node.status({}); + }); + } + }); + } + } + RED.nodes.registerType("twitter out",TwitterOutNode); + + var oa = new OAuth( + "https://api.twitter.com/oauth/request_token", + "https://api.twitter.com/oauth/access_token", + "OKjYEd1ef2bfFolV25G5nQ", + "meRsltCktVMUI8gmggpXett7WBLd1k0qidYazoML6g", + "1.0", + null, + "HMAC-SHA1" + ); + + RED.httpAdmin.get('/twitter-credentials/:id/auth', function(req, res){ + var credentials = {}; + oa.getOAuthRequestToken({ + oauth_callback: req.query.callback + },function(error, oauth_token, oauth_token_secret, results){ + if (error) { + var resp = '

Oh no!

'+ + '

Something went wrong with the authentication process. The following error was returned:

'+ + '

'+error.statusCode+': '+error.data+'

'+ + '

One known cause of this type of failure is if the clock is wrong on system running Node-RED.'; + res.send(resp) + } else { + credentials.oauth_token = oauth_token; + credentials.oauth_token_secret = oauth_token_secret; + res.redirect('https://twitter.com/oauth/authorize?oauth_token='+oauth_token) + RED.nodes.addCredentials(req.params.id,credentials); + } + }); + }); + + RED.httpAdmin.get('/twitter-credentials/:id/auth/callback', function(req, res, next){ + var credentials = RED.nodes.getCredentials(req.params.id); + credentials.oauth_verifier = req.query.oauth_verifier; + + oa.getOAuthAccessToken( + credentials.oauth_token, + credentials.token_secret, + credentials.oauth_verifier, + function(error, oauth_access_token, oauth_access_token_secret, results){ + if (error){ + console.log(error); + res.send("yeah something broke."); + } else { + credentials = {}; + credentials.access_token = oauth_access_token; + credentials.access_token_secret = oauth_access_token_secret; + credentials.screen_name = "@"+results.screen_name; + RED.nodes.addCredentials(req.params.id,credentials); + res.send("Authorised - you can close this window and return to Node-RED"); + } + } + ); + }); +} diff --git a/dgbuilder/core_nodes/social/32-feedparse.html b/dgbuilder/core_nodes/social/32-feedparse.html new file mode 100644 index 00000000..a7954277 --- /dev/null +++ b/dgbuilder/core_nodes/social/32-feedparse.html @@ -0,0 +1,57 @@ + + + + + + + diff --git a/dgbuilder/core_nodes/social/32-feedparse.js b/dgbuilder/core_nodes/social/32-feedparse.js new file mode 100644 index 00000000..97630e7d --- /dev/null +++ b/dgbuilder/core_nodes/social/32-feedparse.js @@ -0,0 +1,71 @@ +/** + * Copyright 2013 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + var FeedParser = require("feedparser"); + var request = require("request"); + + function FeedParseNode(n) { + RED.nodes.createNode(this,n); + this.url = n.url; + this.interval = (parseInt(n.interval)||15)*60000; + var node = this; + this.interval_id = null; + this.seen = {}; + if (this.url !== "") { + var getFeed = function() { + request(node.url,function(err) { + if (err) node.error(err); + }) + .pipe(new FeedParser({feedurl:node.url})) + .on('error', function(error) { + node.error(error); + }) + .on('meta', function (meta) {}) + .on('readable', function () { + var stream = this, article; + while (article = stream.read()) { + if (!(article.guid in node.seen) || ( node.seen[article.guid] != 0 && node.seen[article.guid] != article.date.getTime())) { + node.seen[article.guid] = article.date?article.date.getTime():0; + var msg = { + topic:article.origlink||article.link, + payload: article.description, + article: article + }; + node.send(msg); + } + } + }) + .on('end', function () { + }); + }; + this.interval_id = setInterval(getFeed,node.interval); + getFeed(); + + } else { + this.error("Invalid url"); + } + } + + RED.nodes.registerType("feedparse",FeedParseNode); + + FeedParseNode.prototype.close = function() { + if (this.interval_id != null) { + clearInterval(this.interval_id); + } + } +} diff --git a/dgbuilder/core_nodes/social/61-email.html b/dgbuilder/core_nodes/social/61-email.html new file mode 100644 index 00000000..37397083 --- /dev/null +++ b/dgbuilder/core_nodes/social/61-email.html @@ -0,0 +1,189 @@ + + + + + + + + + + + + + + diff --git a/dgbuilder/core_nodes/social/61-email.js b/dgbuilder/core_nodes/social/61-email.js new file mode 100644 index 00000000..7d0f8cb9 --- /dev/null +++ b/dgbuilder/core_nodes/social/61-email.js @@ -0,0 +1,246 @@ +/** + * Copyright 2013,2014 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + var nodemailer = require("nodemailer"); + var Imap = require('imap'); + + //console.log(nodemailer.Transport.transports.SMTP.wellKnownHosts); + + try { + var globalkeys = RED.settings.email || require(process.env.NODE_RED_HOME+"/../emailkeys.js"); + } catch(err) { + } + + function EmailNode(n) { + RED.nodes.createNode(this,n); + this.topic = n.topic; + this.name = n.name; + this.outserver = n.server; + this.outport = n.port; + var flag = false; + if (this.credentials && this.credentials.hasOwnProperty("userid")) { + this.userid = this.credentials.userid; + } else { + if (globalkeys) { + this.userid = globalkeys.user; + flag = true; + } else { + this.error("No e-mail userid set"); + } + } + if (this.credentials && this.credentials.hasOwnProperty("password")) { + this.password = this.credentials.password; + } else { + if (globalkeys) { + this.password = globalkeys.pass; + flag = true; + } else { + this.error("No e-mail password set"); + } + } + if (flag) { + RED.nodes.addCredentials(n.id,{userid:this.userid, password:this.password, global:true}); + } + var node = this; + + var smtpTransport = nodemailer.createTransport({ + host: node.outserver, + port: node.outport, + secure: true, + auth: { + user: node.userid, + pass: node.password + } + }); + + this.on("input", function(msg) { + if (smtpTransport) { + node.status({fill:"blue",shape:"dot",text:"sending"}); + var payload = RED.util.ensureString(msg.payload); + smtpTransport.sendMail({ + from: node.userid, // sender address + to: msg.to || node.name, // comma separated list of addressees + subject: msg.topic, // subject line + text: payload // plaintext body + }, function(error, info) { + if (error) { + node.error(error); + node.status({fill:"red",shape:"ring",text:"send failed"}); + } else { + node.log("Message sent: " + info.response); + node.status({}); + } + }); + } + else { node.warn("No Email credentials found. See info panel."); } + }); + } + RED.nodes.registerType("e-mail",EmailNode,{ + credentials: { + userid: {type:"text"}, + password: {type: "password"}, + global: { type:"boolean"} + } + }); + + function EmailInNode(n) { + RED.nodes.createNode(this,n); + this.name = n.name; + this.repeat = n.repeat * 1000 || 300000; + this.inserver = n.server || globalkeys.server || "imap.gmail.com"; + this.inport = n.port || globalkeys.port || "993"; + var flag = false; + + if (this.credentials && this.credentials.hasOwnProperty("userid")) { + this.userid = this.credentials.userid; + } else { + if (globalkeys) { + this.userid = globalkeys.user; + flag = true; + } else { + this.error("No e-mail userid set"); + } + } + if (this.credentials && this.credentials.hasOwnProperty("password")) { + this.password = this.credentials.password; + } else { + if (globalkeys) { + this.password = globalkeys.pass; + flag = true; + } else { + this.error("No e-mail password set"); + } + } + if (flag) { + RED.nodes.addCredentials(n.id,{userid:this.userid, password:this.password, global:true}); + } + + var node = this; + this.interval_id = null; + var oldmail = {}; + + var imap = new Imap({ + user: node.userid, + password: node.password, + host: node.inserver, + port: node.inport, + tls: true, + tlsOptions: { rejectUnauthorized: false }, + connTimeout: node.repeat, + authTimeout: node.repeat + }); + + if (!isNaN(this.repeat) && this.repeat > 0) { + node.log("repeat = "+this.repeat); + this.interval_id = setInterval( function() { + node.emit("input",{}); + }, this.repeat ); + } + + this.on("input", function(msg) { + imap.once('ready', function() { + node.status({fill:"blue",shape:"dot",text:"fetching"}); + var pay = {}; + imap.openBox('INBOX', true, function(err, box) { + if (box.messages.total > 0) { + var f = imap.seq.fetch(box.messages.total + ':*', { bodies: ['HEADER.FIELDS (FROM SUBJECT DATE)','TEXT'] }); + f.on('message', function(msg, seqno) { + node.log('message: #'+ seqno); + var prefix = '(#' + seqno + ') '; + msg.on('body', function(stream, info) { + var buffer = ''; + stream.on('data', function(chunk) { + buffer += chunk.toString('utf8'); + }); + stream.on('end', function() { + if (info.which !== 'TEXT') { + pay.from = Imap.parseHeader(buffer).from[0]; + pay.topic = Imap.parseHeader(buffer).subject[0]; + pay.date = Imap.parseHeader(buffer).date[0]; + } else { + var parts = buffer.split("Content-Type"); + for (var p = 0; p < parts.length; p++) { + if (parts[p].indexOf("text/plain") >= 0) { + pay.payload = parts[p].split("\n").slice(1,-2).join("\n").trim(); + } + if (parts[p].indexOf("text/html") >= 0) { + pay.html = parts[p].split("\n").slice(1,-2).join("\n").trim(); + } + } + //pay.body = buffer; + } + }); + }); + msg.on('end', function() { + //node.log('Finished: '+prefix); + }); + }); + f.on('error', function(err) { + node.warn('fetch error: ' + err); + node.status({fill:"red",shape:"ring",text:"fetch error"}); + }); + f.on('end', function() { + if (JSON.stringify(pay) !== oldmail) { + node.send(pay); + oldmail = JSON.stringify(pay); + node.log('received new email: '+pay.topic); + } + else { node.log('duplicate not sent: '+pay.topic); } + //node.status({fill:"green",shape:"dot",text:"ok"}); + node.status({}); + imap.end(); + }); + } + else { + node.log("you have achieved inbox zero"); + //node.status({fill:"green",shape:"dot",text:"ok"}); + node.status({}); + imap.end(); + } + }); + }); + node.status({fill:"grey",shape:"dot",text:"connecting"}); + imap.connect(); + }); + + imap.on('error', function(err) { + node.log(err); + node.status({fill:"red",shape:"ring",text:"connect error"}); + }); + + this.on("error", function(err) { + node.log("error: ",err); + }); + + this.on("close", function() { + if (this.interval_id != null) { + clearInterval(this.interval_id); + } + if (imap) { imap.destroy(); } + }); + + node.emit("input",{}); + } + RED.nodes.registerType("e-mail in",EmailInNode,{ + credentials: { + userid: {type:"text"}, + password: {type: "password"}, + global: { type:"boolean"} + } + }); +} diff --git a/dgbuilder/core_nodes/social/91-irc.html b/dgbuilder/core_nodes/social/91-irc.html new file mode 100644 index 00000000..11112374 --- /dev/null +++ b/dgbuilder/core_nodes/social/91-irc.html @@ -0,0 +1,206 @@ + + + + + + + + + + + + + + + + + + + diff --git a/dgbuilder/core_nodes/social/91-irc.js b/dgbuilder/core_nodes/social/91-irc.js new file mode 100644 index 00000000..c520e44f --- /dev/null +++ b/dgbuilder/core_nodes/social/91-irc.js @@ -0,0 +1,237 @@ +/** + * Copyright 2013 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + var irc = require("irc"); + + // The Server Definition - this opens (and closes) the connection + function IRCServerNode(n) { + RED.nodes.createNode(this,n); + this.server = n.server; + this.channel = n.channel; + this.nickname = n.nickname; + this.lastseen = 0; + this.ircclient = null; + this.on("close", function() { + if (this.ircclient != null) { + this.ircclient.removeAllListeners(); + this.ircclient.disconnect(); + } + }); + } + RED.nodes.registerType("irc-server",IRCServerNode); + + + // The Input Node + function IrcInNode(n) { + RED.nodes.createNode(this,n); + this.ircserver = n.ircserver; + this.serverConfig = RED.nodes.getNode(this.ircserver); + this.channel = n.channel || this.serverConfig.channel; + var node = this; + if (node.serverConfig.ircclient === null) { + node.log("Connecting to "+node.serverConfig.server); + node.status({fill:"grey",shape:"dot",text:"connecting"}); + node.serverConfig.ircclient = new irc.Client(node.serverConfig.server, node.serverConfig.nickname,{autoConnect:false,retryDelay:20000}); + node.serverConfig.ircclient.setMaxListeners(0); + node.serverConfig.ircclient.addListener('error', function(message) { + node.log(JSON.stringify(message)); + }); + node.serverConfig.ircclient.addListener('netError', function(message) { + node.log(JSON.stringify("NET "+message)); + node.serverConfig.lastseen = Date.now(); + }); + node.serverConfig.ircclient.addListener('connect', function() { + node.serverConfig.lastseen = Date.now(); + }); + node.serverConfig.ircclient.addListener('ping', function(server) { + node.serverConfig.lastseen = Date.now(); + //node.log("PING "+JSON.stringify(server)); + }); + node.recon = setInterval( function() { + //console.log("CHK ",(Date.now()-node.serverConfig.lastseen)/1000); + if ((Date.now()-node.serverConfig.lastseen) > 300000) { // if more than 5 mins since last seen + node.ircclient.send.apply(node.ircclient,["TIME"]); // request time to check link + } + if ((Date.now()-node.serverConfig.lastseen) > 400000) { // If more than 6.5 mins + node.serverConfig.ircclient.disconnect(); + node.serverConfig.ircclient.connect(); + node.log("reconnect"); // then retry + } + node.ircclient.send.apply(node.ircclient,["TIME"]); // request time to check link + }, 60000); // check every 1 min + } + else { node.status({text:""}); } + node.ircclient = node.serverConfig.ircclient; + + node.ircclient.addListener('registered', function(message) { + //node.log(node.ircclient.nick+" ONLINE"); + node.status({fill:"yellow",shape:"dot",text:"connected"}); + node.ircclient.join( node.channel, function(data) { + // node.log(data+" JOINED "+node.channel); + node.status({fill:"green",shape:"dot",text:"joined"}); + }); + }); + node.ircclient.addListener('message', function (from, to, message) { + //node.log(from + ' => ' + to + ' : ' + message); + if (~node.channel.toLowerCase().indexOf(to.toLowerCase())) { + var msg = { "topic":from, "from":from, "to":to, "payload":message }; + node.send([msg,null]); + } + //else { console.log(node.channel,to); } + }); + node.ircclient.addListener('pm', function(from, message) { + //node.log("PM => "+from + ': ' + message); + var msg = { "topic":from, "from":from, "to":"PRIV", "payload":message }; + node.send([msg,null]); + }); + node.ircclient.addListener('join', function(channel, who) { + var msg = { "payload": { "type":"join", "who":who, "channel":channel } }; + node.send([null,msg]); + //node.log(who+' has joined '+channel); + }); + node.ircclient.addListener('invite', function(channel, from, message) { + var msg = { "payload": { "type":"invite", "who":from, "channel":channel, "message":message } }; + node.send([null,msg]); + //node.log(from+' sent invite to '+channel+': '+message); + }); + node.ircclient.addListener('part', function(channel, who, reason) { + var msg = { "payload": { "type":"part", "who":who, "channel":channel, "reason":reason } }; + node.send([null,msg]); + //node.log(who+' has left '+channel+': '+reason); + }); + node.ircclient.addListener('quit', function(nick, reason, channels, message) { + var msg = { "payload": { "type":"quit", "who":nick, "channel":channels, "reason":reason } }; + node.send([null,msg]); + //node.log(nick+' has quit '+channels+': '+reason); + }); + node.ircclient.addListener('kick', function(channel, who, by, reason) { + var msg = { "payload": { "type":"kick", "who":who, "channel":channel, "by":by, "reason":reason } }; + node.send([null,msg]); + //node.log(who+' was kicked from '+channel+' by '+by+': '+reason); + }); + node.ircclient.addListener('names', function (channel, nicks) { + var msg = { "payload": { "type": "names", "channel": channel, "names": nicks} }; + node.send([null, msg]); + }); + node.ircclient.addListener('raw', function (message) { // any message means we are alive + node.serverConfig.lastseen = Date.now(); + }); + node.on("close", function() { + node.ircclient.removeAllListeners(); + if (node.recon) { clearInterval(node.recon); } + }); + } + RED.nodes.registerType("irc in",IrcInNode); + + + // The Output Node + function IrcOutNode(n) { + RED.nodes.createNode(this,n); + this.sendFlag = n.sendObject; + this.ircserver = n.ircserver; + this.serverConfig = RED.nodes.getNode(this.ircserver); + this.channel = n.channel || this.serverConfig.channel; + var node = this; + if (node.serverConfig.ircclient === null) { + node.log("connecting to "+node.serverConfig.server); + node.status({fill:"grey",shape:"dot",text:"connecting"}); + node.serverConfig.ircclient = new irc.Client(node.serverConfig.server, node.serverConfig.nickname,{autoConnect:false,retryDelay:20000}); + node.serverConfig.ircclient.setMaxListeners(0); + node.serverConfig.ircclient.addListener('error', function(message) { + node.log(JSON.stringify(message)); + }); + node.serverConfig.ircclient.addListener('netError', function(message) { + node.log(JSON.stringify("NET "+message)); + node.serverConfig.lastseen = Date.now(); + }); + node.serverConfig.ircclient.addListener('connect', function() { + node.serverConfig.lastseen = Date.now(); + }); + node.serverConfig.ircclient.addListener('ping', function(server) { + node.serverConfig.lastseen = Date.now(); + //node.log("PING "+JSON.stringify(server)); + }); + node.serverConfig.ircclient.addListener('raw', function (message) { // any message received means we are alive + if (message.commandType === "reply") { node.serverConfig.lastseen = Date.now(); } + }); + node.recon = setInterval( function() { + //console.log("CHK ",(Date.now()-node.serverConfig.lastseen)/1000); + if ((Date.now()-node.serverConfig.lastseen) > 300000) { // if more than 5 mins since last seen + node.ircclient.send.apply(node.ircclient,["TIME"]); // request time to check link + } + if ((Date.now()-node.serverConfig.lastseen) > 400000) { // If more than 6.5 mins + node.serverConfig.ircclient.disconnect(); + node.serverConfig.ircclient.connect(); + node.log("reconnect"); // then retry + } + node.ircclient.send.apply(node.ircclient,["TIME"]); // request time to check link + }, 60000); // check every 1 min + node.serverConfig.ircclient.connect(); + } + else { node.status({text:""}); } + node.ircclient = node.serverConfig.ircclient; + + node.ircclient.addListener('registered', function(message) { + node.log(node.ircclient.nick+" ONLINE"); + node.status({fill:"yellow",shape:"dot",text:"connected"}); + node.ircclient.join( node.channel, function(data) { + //node.log(data+" JOINED "+node.channel); + node.status({fill:"green",shape:"dot",text:"joined"}); + }); + }); + + node.on("input", function(msg) { + if (Object.prototype.toString.call( msg.raw ) === '[object Array]') { + node.log("RAW command:"+msg.raw); + node.ircclient.send.apply(node.ircclient,msg.raw); + //var m = msg.raw; + //for (var i = 0; i < 10; i++) { + //if (typeof m[i] !== "string") { m[i] = ""; } + //m[i] = m[i].replace(/"/g, ""); + //} + //node.log("RAW command:"+m); + //node.ircclient.send(m[0],m[1],m[2],m[3],m[4],m[5],m[6],m[7],m[8],m[9]); + } + else { + if (msg._topic) { delete msg._topic; } + var ch = node.channel.split(","); // split on , so we can send to multiple + if (node.sendFlag == "true") { // override channels with msg.topic + if ((msg.hasOwnProperty('topic'))&&(typeof msg.topic === "string")) { + ch = msg.topic.split(","); // split on , so we can send to multiple + } + else { node.warn("msg.topic not set"); } + } + for (var c = 0; c < ch.length; c++) { + if (node.sendFlag == "false") { // send whole message object to each channel + node.ircclient.say(ch[c], JSON.stringify(msg)); + } + else { // send just the payload to each channel + if (typeof msg.payload === "object") { msg.payload = JSON.stringify(msg.payload); } + node.ircclient.say(ch[c], msg.payload); + } + } + } + }); + + node.on("close", function() { + node.ircclient.removeAllListeners(); + if (node.recon) { clearInterval(node.recon); } + }); + } + RED.nodes.registerType("irc out",IrcOutNode); +} diff --git a/dgbuilder/core_nodes/storage/28-tail.html b/dgbuilder/core_nodes/storage/28-tail.html new file mode 100644 index 00000000..c094d064 --- /dev/null +++ b/dgbuilder/core_nodes/storage/28-tail.html @@ -0,0 +1,58 @@ + + + + + + + diff --git a/dgbuilder/core_nodes/storage/28-tail.js b/dgbuilder/core_nodes/storage/28-tail.js new file mode 100644 index 00000000..89c7a639 --- /dev/null +++ b/dgbuilder/core_nodes/storage/28-tail.js @@ -0,0 +1,69 @@ +/** + * Copyright 2013, 2014 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + var spawn = require('child_process').spawn; + var plat = require('os').platform(); + + if (plat.match(/^win/)) { + throw "Info : Currently not supported on Windows."; + } + + function TailNode(n) { + RED.nodes.createNode(this,n); + + this.filename = n.filename; + this.split = n.split; + var node = this; + + var err = ""; + // TODO: rewrite to use node-tail + var tail = spawn("tail", ["-F", "-n", "0", this.filename]); + tail.stdout.on("data", function (data) { + if (node.split) { + // TODO: allow customisation of the line break - as we do elsewhere + var strings = data.toString().split("\n"); + for (var s in strings) { + //TODO: should we really filter blanks? Is that expected? + if (strings[s] !== "") { + node.send({ + topic: node.filename, + payload: strings[s] + }); + } + } + } + else { + var msg = { + topic:node.filename, + payload: data.toString() + }; + node.send(msg); + } + }); + + tail.stderr.on("data", function(data) { + node.warn(data.toString()); + }); + + this.on("close", function() { + if (tail) { tail.kill(); } + }); + } + + RED.nodes.registerType("tail",TailNode); +} diff --git a/dgbuilder/core_nodes/storage/50-file.html b/dgbuilder/core_nodes/storage/50-file.html new file mode 100644 index 00000000..5113a17d --- /dev/null +++ b/dgbuilder/core_nodes/storage/50-file.html @@ -0,0 +1,110 @@ + + + + + + + + + + + diff --git a/dgbuilder/core_nodes/storage/50-file.js b/dgbuilder/core_nodes/storage/50-file.js new file mode 100644 index 00000000..d6cc4410 --- /dev/null +++ b/dgbuilder/core_nodes/storage/50-file.js @@ -0,0 +1,93 @@ +/** + * Copyright 2013, 2014 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + var fs = require("fs"); + + function FileNode(n) { + RED.nodes.createNode(this,n); + this.filename = n.filename || ""; + this.appendNewline = n.appendNewline; + this.overwriteFile = n.overwriteFile; + var node = this; + this.on("input",function(msg) { + var filename = msg.filename || this.filename; + if (filename === "") { + node.warn('No filename specified'); + } else if (msg.hasOwnProperty('delete')) { + fs.unlink(filename, function (err) { + if (err) { node.warn('Failed to delete file : '+err); } + //console.log('Deleted file",filename); + }); + } else if (typeof msg.payload != "undefined") { + var data = msg.payload; + if (typeof data === "object") { + if (!Buffer.isBuffer(data)) { + data = JSON.stringify(data); + } + } + if (typeof data === "boolean") { data = data.toString(); } + if ((this.appendNewline)&&(!Buffer.isBuffer(data))) { data += "\n"; } + if (this.overwriteFile) { + // using "binary" not {encoding:"binary"} to be 0.8 compatible for a while + fs.writeFile(filename, data, "binary", function (err) { + if (err) { node.warn('Failed to write to file : '+err); } + //console.log('Message written to file',filename); + }); + } + else { + // using "binary" not {encoding:"binary"} to be 0.8 compatible for a while + fs.appendFile(filename, data, "binary", function (err) { + if (err) { node.warn('Failed to append to file : '+err); } + //console.log('Message appended to file',filename); + }); + } + } + }); + } + RED.nodes.registerType("file",FileNode); + + function FileInNode(n) { + RED.nodes.createNode(this,n); + + this.filename = n.filename || ""; + this.format = n.format; + var node = this; + var options = {}; + if (this.format) { + options['encoding'] = this.format; + } + this.on("input",function(msg) { + var filename = msg.filename || this.filename; + if (filename === "") { + node.warn('No filename specified'); + } else { + fs.readFile(filename,options,function(err,data) { + if (err) { + node.warn(err); + msg.error = err; + } else { + msg.filename = filename; + msg.payload = data; + } + node.send(msg); + }); + } + }); + } + RED.nodes.registerType("file in",FileInNode); +} diff --git a/dgbuilder/core_nodes/storage/65-redisout.html b/dgbuilder/core_nodes/storage/65-redisout.html new file mode 100644 index 00000000..9000dfd6 --- /dev/null +++ b/dgbuilder/core_nodes/storage/65-redisout.html @@ -0,0 +1,105 @@ + + + + + + + diff --git a/dgbuilder/core_nodes/storage/65-redisout.js b/dgbuilder/core_nodes/storage/65-redisout.js new file mode 100644 index 00000000..907e2a55 --- /dev/null +++ b/dgbuilder/core_nodes/storage/65-redisout.js @@ -0,0 +1,107 @@ +/** + * Copyright 2013 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + var util = require("util"); + var redis = require("redis"); + + var hashFieldRE = /^([^=]+)=(.*)$/; + + var redisConnectionPool = function() { + var connections = {}; + var obj = { + get: function(host,port) { + var id = host+":"+port; + if (!connections[id]) { + connections[id] = redis.createClient(port,host); + connections[id].on("error",function(err) { + util.log("[redis] "+err); + }); + connections[id].on("connect",function() { + util.log("[redis] connected to "+host+":"+port); + }); + connections[id]._id = id; + connections[id]._nodeCount = 0; + } + connections[id]._nodeCount += 1; + return connections[id]; + }, + close: function(connection) { + connection._nodeCount -= 1; + if (connection._nodeCount === 0) { + if (connection) { + clearTimeout(connection.retry_timer); + connection.end(); + } + delete connections[connection._id]; + } + } + }; + return obj; + }(); + + + function RedisOutNode(n) { + RED.nodes.createNode(this,n); + this.port = n.port||"6379"; + this.hostname = n.hostname||"127.0.0.1"; + this.key = n.key; + this.structtype = n.structtype; + + this.client = redisConnectionPool.get(this.hostname,this.port); + + if (this.client.connected) { + this.status({fill:"green",shape:"dot",text:"connected"}); + } else { + this.status({fill:"red",shape:"ring",text:"disconnected"},true); + } + + var node = this; + this.client.on("end", function() { + node.status({fill:"red",shape:"ring",text:"disconnected"}); + }); + this.client.on("connect", function() { + node.status({fill:"green",shape:"dot",text:"connected"}); + }); + + this.on("input", function(msg) { + var k = this.key || msg.topic; + if (k) { + if (this.structtype == "string") { + this.client.set(k,RED.util.ensureString(msg.payload)); + } else if (this.structtype == "hash") { + var r = hashFieldRE.exec(msg.payload); + if (r) { + this.client.hset(k,r[1],r[2]); + } else { + this.warn("Invalid payload for redis hash"); + } + } else if (this.structtype == "set") { + this.client.sadd(k,msg.payload); + } else if (this.structtype == "list") { + this.client.rpush(k,msg.payload); + } + } else { + this.warn("No key or topic set"); + } + }); + this.on("close", function() { + redisConnectionPool.close(node.client); + }); + } + RED.nodes.registerType("redis out",RedisOutNode); +} diff --git a/dgbuilder/core_nodes/storage/66-mongodb.html b/dgbuilder/core_nodes/storage/66-mongodb.html new file mode 100644 index 00000000..81c56389 --- /dev/null +++ b/dgbuilder/core_nodes/storage/66-mongodb.html @@ -0,0 +1,231 @@ + + + + + + + + + + + + + + + + + + + diff --git a/dgbuilder/core_nodes/storage/66-mongodb.js b/dgbuilder/core_nodes/storage/66-mongodb.js new file mode 100644 index 00000000..3a71407c --- /dev/null +++ b/dgbuilder/core_nodes/storage/66-mongodb.js @@ -0,0 +1,233 @@ +/** + * Copyright 2013,2014 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + var mongo = require('mongodb'); + var MongoClient = mongo.MongoClient; + + function MongoNode(n) { + RED.nodes.createNode(this,n); + this.hostname = n.hostname; + this.port = n.port; + this.db = n.db; + this.name = n.name; + + var url = "mongodb://"; + if (this.credentials && this.credentials.user && this.credentials.password) { + url += this.credentials.user+":"+this.credentials.password+"@"; + } + url += this.hostname+":"+this.port+"/"+this.db; + + this.url = url; + } + + RED.nodes.registerType("mongodb",MongoNode,{ + credentials: { + user: {type:"text"}, + password: {type: "password"} + } + }); + + function ensureValidSelectorObject(selector) { + if (selector != null && (typeof selector != 'object' || Buffer.isBuffer(selector))) { + return {}; + } + return selector; + } + + + function MongoOutNode(n) { + RED.nodes.createNode(this,n); + this.collection = n.collection; + this.mongodb = n.mongodb; + this.payonly = n.payonly || false; + this.upsert = n.upsert || false; + this.multi = n.multi || false; + this.operation = n.operation; + this.mongoConfig = RED.nodes.getNode(this.mongodb); + + if (this.mongoConfig) { + var node = this; + MongoClient.connect(this.mongoConfig.url, function(err, db) { + if (err) { + node.error(err); + } else { + node.clientDb = db; + var coll; + if (node.collection) { + coll = db.collection(node.collection); + } + node.on("input",function(msg) { + if (!coll) { + if (msg.collection) { + coll = db.collection(msg.collection); + } else { + node.error("No collection defined"); + return; + } + } + delete msg._topic; + delete msg.collection; + if (node.operation === "store") { + if (node.payonly) { + if (typeof msg.payload !== "object") { + msg.payload = {"payload": msg.payload}; + } + coll.save(msg.payload,function(err, item) { + if (err) { + node.error(err); + } + }); + } else { + coll.save(msg,function(err, item) { + if (err) { + node.error(err); + } + }); + } + } else if (node.operation === "insert") { + if (node.payonly) { + if (typeof msg.payload !== "object") { + msg.payload = {"payload": msg.payload}; + } + coll.insert(msg.payload, function(err, item) { + if (err) { + node.error(err); + } + }); + } else { + coll.insert(msg, function(err,item) { + if (err) { + node.error(err); + } + }); + } + } else if (node.operation === "update") { + if (typeof msg.payload !== "object") { + msg.payload = {"payload": msg.payload}; + } + var query = msg.query || {}; + var payload = msg.payload || {}; + var options = { + upsert: node.upsert, + multi: node.multi + }; + + coll.update(query, payload, options, function(err, item) { + if (err) { + node.error(err + " " + payload); + } + }); + } else if (node.operation === "delete") { + coll.remove(msg.payload, function(err, items) { + if (err) { + node.error(err); + } + }); + } + }); + } + }); + } else { + this.error("missing mongodb configuration"); + } + + this.on("close", function() { + if (this.clientDb) { + this.clientDb.close(); + } + }); + } + RED.nodes.registerType("mongodb out",MongoOutNode); + + function MongoInNode(n) { + RED.nodes.createNode(this,n); + this.collection = n.collection; + this.mongodb = n.mongodb; + this.operation = n.operation || "find"; + this.mongoConfig = RED.nodes.getNode(this.mongodb); + + if (this.mongoConfig) { + var node = this; + MongoClient.connect(this.mongoConfig.url, function(err,db) { + if (err) { + node.error(err); + } else { + node.clientDb = db; + var coll; + if (node.collection) { + coll = db.collection(node.collection); + } + node.on("input", function(msg) { + if (!coll) { + if (msg.collection) { + coll = db.collection(msg.collection); + } else { + node.error("No collection defined"); + return; + } + } + if (node.operation === "find") { + msg.projection = msg.projection || {}; + var selector = ensureValidSelectorObject(msg.payload); + coll.find(selector,msg.projection).sort(msg.sort).limit(msg.limit).toArray(function(err, items) { + if (err) { + node.error(err); + } else { + msg.payload = items; + delete msg.projection; + delete msg.sort; + delete msg.limit; + node.send(msg); + } + }); + } else if (node.operation === "count") { + var selector = ensureValidSelectorObject(msg.payload); + coll.count(selector, function(err, count) { + if (err) { + node.error(err); + } else { + msg.payload = count; + node.send(msg); + } + }); + } else if (node.operation === "aggregate") { + msg.payload = (msg.payload instanceof Array) ? msg.payload : []; + coll.aggregate(msg.payload, function(err, result) { + if (err) { + node.error(err); + } else { + msg.payload = result; + node.send(msg); + } + }); + } + }); + } + }); + } else { + this.error("missing mongodb configuration"); + } + + this.on("close", function() { + if (this.clientDb) { + this.clientDb.close(); + } + }); + } + RED.nodes.registerType("mongodb in",MongoInNode); +} diff --git a/dgbuilder/createReleaseDir.sh b/dgbuilder/createReleaseDir.sh new file mode 100755 index 00000000..00d185f7 --- /dev/null +++ b/dgbuilder/createReleaseDir.sh @@ -0,0 +1,129 @@ +#!/bin/bash +export PATH=$PATH:. +appDir=$(pwd) +if [ "$#" != 3 -a "$#" != 4 ] +then + echo "Usage $0 releaseDir loginId emailAddress [gitLocalRepository]" + echo "Note: Specify the gitLocalRepository path if you would want to be able to import flows from your local git repository" + exit +fi +if [ ! -e "releases" ] +then + mkdir releases +fi +releaseDir="$1" +name="Release $releaseDir" +loginId="$2" +emailid="$3" +dbHost="dbhost" +dbPort="3306" +dbName="sdnctl" +dbUser="sdnctl" +dbPassword="gamma" +gitLocalRepository="$4" + +lastPort=$(find "releases/" -name "customSettings.js" |xargs grep uiPort|cut -d: -f2|sed -e s/,//|sort|tail -1) +echo $lastPort|grep uiPort >/dev/null 2>&1 +if [ "$?" == "0" ] +then +lastPort=$(find "releases/" -name "customSettings.js" |xargs grep uiPort|cut -d: -f3|sed -e s/,//|sort|tail -1) +fi +#echo $lastPort +if [ "${lastPort}" == "" ] +then + lastPort="3099" +fi +let nextPort=$(expr $lastPort+1) +#echo $nextPort +if [ ! -e "releases/$releaseDir" ] +then +mkdir releases/$releaseDir +cd releases/$releaseDir +mkdir flows +mkdir flows/shared +mkdir flows/shared/backups +mkdir html +mkdir xml +mkdir lib +mkdir lib/flows +mkdir logs +mkdir conf +mkdir codecloud +customSettingsFile="customSettings.js" +if [ ! -e "./$customSettingsFile" ] +then + echo "module.exports = {" >$customSettingsFile + echo " 'name' : '$name'," >>$customSettingsFile + echo " 'emailAddress' :'$emailid'," >>$customSettingsFile + echo " 'uiPort' :$nextPort," >>$customSettingsFile + echo " 'mqttReconnectTime': 15000," >>$customSettingsFile + echo " 'serialReconnectTime' : 15000," >>$customSettingsFile + echo " 'debugMaxLength': 1000," >>$customSettingsFile + echo " 'htmlPath': 'releases/$releaseDir/html/'," >>$customSettingsFile + echo " 'xmlPath': 'releases/$releaseDir/xml/'," >>$customSettingsFile + echo " 'flowFile' : 'releases/$releaseDir/flows/flows.json'," >>$customSettingsFile + echo " 'sharedDir': 'releases/$releaseDir/flows/shared'," >>$customSettingsFile + echo " 'userDir' : 'releases/$releaseDir'," >>$customSettingsFile + echo " 'httpAuth': {user:'$loginId',pass:'cc03e747a6afbbcbf8be7668acfebee5'}," >>$customSettingsFile + echo " 'dbHost': '$dbHost'," >>$customSettingsFile + echo " 'dbPort': '$dbPort'," >>$customSettingsFile + echo " 'dbName': '$dbName'," >>$customSettingsFile + echo " 'dbUser': '$dbUser'," >>$customSettingsFile + echo " 'dbPassword': '$dbPassword'," >>$customSettingsFile + echo " 'gitLocalRepository': '$gitLocalRepository'" >>$customSettingsFile + echo " }" >>$customSettingsFile +fi + #echo "Created custom settings file $customSettingsFile" + echo "Done ....." +else + echo "ERROR:customSettings file $customSettingsFile already exists for $releaseDir" + exit +fi +#echo "Content of custom settings file" +#echo "============================================================================" +# cat $customSettingsFile +#echo "============================================================================" +svclogicPropFile="./conf/svclogic.properties" +if [ ! -d "${appDir}/yangFiles" ] +then + mkdir -p "${appDir}/yangFiles" +fi +if [ ! -d "${appDir}/generatedJS" ] +then + mkdir -p "${appDir}/generatedJS" +fi + +if [ ! -e "./$svclogicPropFile" ] +then + echo "org.onap.ccsdk.sli.dbtype=jdbc" >$svclogicPropFile + echo "org.onap.ccsdk.sli.jdbc.url=jdbc:mysql://dbhost:3306/sdnctl" >>$svclogicPropFile + echo "org.onap.ccsdk.sli.jdbc.database=sdnctl" >>$svclogicPropFile + echo "org.onap.ccsdk.sli.jdbc.user=sdnctl" >>$svclogicPropFile + echo "org.onap.ccsdk.sli.jdbc.password=gamma" >>$svclogicPropFile +fi +if [ ! -e "${appDir}/flowShareUsers.js" ] +then + echo "module.exports = {\"flowShareUsers\":" >${appDir}/flowShareUsers.js + echo " [" >>${appDir}/flowShareUsers.js + echo " ]" >>${appDir}/flowShareUsers.js + echo "}" >>${appDir}/flowShareUsers.js +fi +grep "$releaseDir" ${appDir}/flowShareUsers.js >/dev/null 2>&1 +if [ "$?" != "0" ] +then + num_of_lines=$(cat ${appDir}/flowShareUsers.js|wc -l) + if [ $num_of_lines -gt 4 ] + then + content=$(head -n -2 ${appDir}/flowShareUsers.js) + echo "${content}," > ${appDir}/flowShareUsers.js + else + content=$(head -n -2 ${appDir}/flowShareUsers.js) + echo "$content" > ${appDir}/flowShareUsers.js + fi + echo " {" >> ${appDir}/flowShareUsers.js + echo " \"name\" : \"$name\"," >> ${appDir}/flowShareUsers.js + echo " \"rootDir\" : \"$releaseDir\"" >> ${appDir}/flowShareUsers.js + echo " }" >> ${appDir}/flowShareUsers.js + echo " ]" >> ${appDir}/flowShareUsers.js + echo "}" >> ${appDir}/flowShareUsers.js +fi diff --git a/dgbuilder/flowShareUsers.js b/dgbuilder/flowShareUsers.js new file mode 100644 index 00000000..d132116d --- /dev/null +++ b/dgbuilder/flowShareUsers.js @@ -0,0 +1,16 @@ +module.exports = {"flowShareUsers": + [ + { + "name" : "Release sdnc1.0", + "rootDir" : "sdnc1.0" + }, + { + "name" : "Release sdnc2.0", + "rootDir" : "sdnc2.0" + }, + { + "name" : "Release sdnc3.0", + "rootDir" : "sdnc3.0" + } + ] +} diff --git a/dgbuilder/generatedJS/.gitignore b/dgbuilder/generatedJS/.gitignore new file mode 100644 index 00000000..d6b7ef32 --- /dev/null +++ b/dgbuilder/generatedJS/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/dgbuilder/git_scripts/gitcheckout b/dgbuilder/git_scripts/gitcheckout new file mode 100755 index 00000000..ca01dd79 --- /dev/null +++ b/dgbuilder/git_scripts/gitcheckout @@ -0,0 +1,17 @@ +if [ "$#" != "2" ] +then + echo "Usage $0 gitLocalRepositoryDir branch" + exit +fi +branch=$2 +localGitRepository=$1 +cd $localGitRepository +if [ -e "$localGitRepository" ] +then + git checkout $branch + echo + echo -n "Now on Branch:" + git rev-parse --abbrev-ref HEAD +else + echo Git Local repository not set +fi diff --git a/dgbuilder/git_scripts/gitckout b/dgbuilder/git_scripts/gitckout new file mode 100755 index 00000000..3db9db82 --- /dev/null +++ b/dgbuilder/git_scripts/gitckout @@ -0,0 +1,15 @@ +if [ "$#" != "2" ] +then + echo "Usage $0 commitId full_path_to_the_source_file" + exit +fi +fileName=$(basename $2) +dirName=$(dirname $2) +commitId=$1 +cd $dirName +if [ -e "$2" ] +then + rm $2 2>/dev/null +fi +git checkout $commitId $fileName +cat $fileName diff --git a/dgbuilder/git_scripts/gitcurbranch b/dgbuilder/git_scripts/gitcurbranch new file mode 100755 index 00000000..5a82e483 --- /dev/null +++ b/dgbuilder/git_scripts/gitcurbranch @@ -0,0 +1,13 @@ +if [ "$#" != "1" ] +then + echo "Usage $0 gitLocalRepositoryDir" + exit +fi +localGitRepository=$1 +cd $localGitRepository +if [ -e "$localGitRepository" ] +then + git rev-parse --abbrev-ref HEAD +else + echo Git Local repository not set +fi diff --git a/dgbuilder/git_scripts/gitlog b/dgbuilder/git_scripts/gitlog new file mode 100755 index 00000000..fd8cd379 --- /dev/null +++ b/dgbuilder/git_scripts/gitlog @@ -0,0 +1,18 @@ +if [ "$#" != "1" ] +then + echo "Usage $0 full_path_to_the_source_file" + exit +fi +fileName=$(basename $1) +dirName=$(dirname $1) +cd $dirName +glog=$(git log --pretty=format:'%H %cD %an %s' -n 25 ${fileName}|awk ' ORS=" "{print \ +"\n{\n" \ +"\"commit\": \"" $1 "\",\n" \ +"\"date\": \""$2 " "$3" "$4" "$5 " "$6 "\",\n" \ +"\"author\": \"" $8 ", "$9 "\",\n" \ +"\"comment\": \""} { s = ""; for (i = 10; i <= NF; i++) s = s $i " "; print s } { print "\"\n},"}') +echo "[" +update_glog=$(echo $glog|sed -e 's/,$//g') +echo $update_glog +echo "]" diff --git a/dgbuilder/git_scripts/gitpull b/dgbuilder/git_scripts/gitpull new file mode 100755 index 00000000..8d475adf --- /dev/null +++ b/dgbuilder/git_scripts/gitpull @@ -0,0 +1,7 @@ +if [ "$#" != "1" ] +then + echo "Usage $0 full_path_to_local_repository" + exit +fi +cd $1 +git pull diff --git a/dgbuilder/git_scripts/gitstatus b/dgbuilder/git_scripts/gitstatus new file mode 100755 index 00000000..9b24ea79 --- /dev/null +++ b/dgbuilder/git_scripts/gitstatus @@ -0,0 +1,7 @@ +if [ "$#" != "1" ] +then + echo "Usage $0 full_path_to_local_repository" + exit +fi +cd $1 +git status diff --git a/dgbuilder/nodes/99-sample.html.demo b/dgbuilder/nodes/99-sample.html.demo new file mode 100644 index 00000000..4dcc8ba5 --- /dev/null +++ b/dgbuilder/nodes/99-sample.html.demo @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + diff --git a/dgbuilder/nodes/99-sample.js.demo b/dgbuilder/nodes/99-sample.js.demo new file mode 100644 index 00000000..f9269451 --- /dev/null +++ b/dgbuilder/nodes/99-sample.js.demo @@ -0,0 +1,64 @@ +/** + * Copyright 2014 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +// If you use this as a template, update the copyright with your own name. + +// Sample Node-RED node file + + +module.exports = function(RED) { + "use strict"; + // require any external libraries we may need.... + //var foo = require("foo-library"); + + // The main node definition - most things happen in here + function SampleNode(n) { + // Create a RED node + RED.nodes.createNode(this,n); + + // Store local copies of the node configuration (as defined in the .html) + this.topic = n.topic; + + // Do whatever you need to do in here - declare callbacks etc + // Note: this sample doesn't do anything much - it will only send + // this message once at startup... + // Look at other real nodes for some better ideas of what to do.... + var msg = {}; + msg.topic = this.topic; + msg.payload = "Hello world !" + + // send out the message to the rest of the workspace. + this.send(msg); + + // respond to inputs.... + this.on('input', function (msg) { + node.warn("I saw a payload: "+msg.payload); + // in this example just send it straight on... should process it here really + this.send(msg); + }); + + this.on("close", function() { + // Called when the node is shutdown - eg on redeploy. + // Allows ports to be closed, connections dropped etc. + // eg: this.client.disconnect(); + }); + } + + // Register the node by name. This must be called before overriding any of the + // Node functions. + RED.nodes.registerType("sample",SampleNode); + +} diff --git a/dgbuilder/nodes/dge/dgelogic/block.html b/dgbuilder/nodes/dge/dgelogic/block.html new file mode 100644 index 00000000..fadf8a8c --- /dev/null +++ b/dgbuilder/nodes/dge/dgelogic/block.html @@ -0,0 +1,223 @@ + + + + + + + diff --git a/dgbuilder/nodes/dge/dgelogic/block.js b/dgbuilder/nodes/dge/dgelogic/block.js new file mode 100644 index 00000000..4414d86d --- /dev/null +++ b/dgbuilder/nodes/dge/dgelogic/block.js @@ -0,0 +1,31 @@ +/** + * Copyright 2013 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + var util = require("util"); + var vm = require("vm"); + + function block(n) { + RED.nodes.createNode(this,n); + this.name = n.name; + this.xml = n.xml; + this.topic = n.topic; + } + + RED.nodes.registerType("block",block); + // RED.library.register("block"); +} diff --git a/dgbuilder/nodes/dge/dgelogic/breakNode.html b/dgbuilder/nodes/dge/dgelogic/breakNode.html new file mode 100644 index 00000000..e3edef9d --- /dev/null +++ b/dgbuilder/nodes/dge/dgelogic/breakNode.html @@ -0,0 +1,161 @@ + + + + + + + + diff --git a/dgbuilder/nodes/dge/dgelogic/breakNode.js b/dgbuilder/nodes/dge/dgelogic/breakNode.js new file mode 100644 index 00000000..9b0b1b00 --- /dev/null +++ b/dgbuilder/nodes/dge/dgelogic/breakNode.js @@ -0,0 +1,31 @@ +/** + * Copyright 2013 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + var util = require("util"); + var vm = require("vm"); + + function breakNode(n) { + RED.nodes.createNode(this,n); + this.name = n.name; + this.xml = n.xml; + this.topic = n.topic; + } + + RED.nodes.registerType("break",breakNode); + // RED.library.register("block"); +} diff --git a/dgbuilder/nodes/dge/dgelogic/call.html b/dgbuilder/nodes/dge/dgelogic/call.html new file mode 100644 index 00000000..0e49e26c --- /dev/null +++ b/dgbuilder/nodes/dge/dgelogic/call.html @@ -0,0 +1,183 @@ + + + + + + + + diff --git a/dgbuilder/nodes/dge/dgelogic/call.js b/dgbuilder/nodes/dge/dgelogic/call.js new file mode 100644 index 00000000..3570e3db --- /dev/null +++ b/dgbuilder/nodes/dge/dgelogic/call.js @@ -0,0 +1,31 @@ +/** + * Copyright 2013 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + var util = require("util"); + var vm = require("vm"); + + function call(n) { + RED.nodes.createNode(this,n); + this.name = n.name; + this.xml = n.xml; + this.topic = n.topic; + } + + RED.nodes.registerType("call",call); + // RED.library.register("call"); +} diff --git a/dgbuilder/nodes/dge/dgelogic/configure.html b/dgbuilder/nodes/dge/dgelogic/configure.html new file mode 100644 index 00000000..7503b1f1 --- /dev/null +++ b/dgbuilder/nodes/dge/dgelogic/configure.html @@ -0,0 +1,227 @@ + + + + + + + + diff --git a/dgbuilder/nodes/dge/dgelogic/configure.js b/dgbuilder/nodes/dge/dgelogic/configure.js new file mode 100644 index 00000000..7345750d --- /dev/null +++ b/dgbuilder/nodes/dge/dgelogic/configure.js @@ -0,0 +1,31 @@ +/** + * Copyright 2013 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + var util = require("util"); + var vm = require("vm"); + + function configure(n) { + RED.nodes.createNode(this,n); + this.name = n.name; + this.xml = n.xml; + this.topic = n.topic; + } + + RED.nodes.registerType("configure",configure); + // RED.library.register("configure"); +} diff --git a/dgbuilder/nodes/dge/dgelogic/delete.html b/dgbuilder/nodes/dge/dgelogic/delete.html new file mode 100644 index 00000000..b4c7f52f --- /dev/null +++ b/dgbuilder/nodes/dge/dgelogic/delete.html @@ -0,0 +1,187 @@ + + + + + + + + diff --git a/dgbuilder/nodes/dge/dgelogic/delete.js b/dgbuilder/nodes/dge/dgelogic/delete.js new file mode 100644 index 00000000..37731061 --- /dev/null +++ b/dgbuilder/nodes/dge/dgelogic/delete.js @@ -0,0 +1,31 @@ +/** + * Copyright 2013 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + var util = require("util"); + var vm = require("vm"); + + function deleteNode(n) { + RED.nodes.createNode(this,n); + this.name = n.name; + this.xml = n.xml; + this.topic = n.topic; + } + + RED.nodes.registerType("delete",deleteNode); + // RED.library.register("delete"); +} diff --git a/dgbuilder/nodes/dge/dgelogic/execute.html b/dgbuilder/nodes/dge/dgelogic/execute.html new file mode 100644 index 00000000..3d5fc6d7 --- /dev/null +++ b/dgbuilder/nodes/dge/dgelogic/execute.html @@ -0,0 +1,197 @@ + + + + + + + + diff --git a/dgbuilder/nodes/dge/dgelogic/execute.js b/dgbuilder/nodes/dge/dgelogic/execute.js new file mode 100644 index 00000000..66265f98 --- /dev/null +++ b/dgbuilder/nodes/dge/dgelogic/execute.js @@ -0,0 +1,31 @@ +/** + * Copyright 2013 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + var util = require("util"); + var vm = require("vm"); + + function execute(n) { + RED.nodes.createNode(this,n); + this.name = n.name; + this.xml = n.xml; + this.topic = n.topic; + } + + RED.nodes.registerType("execute",execute); + // RED.library.register("configure"); +} diff --git a/dgbuilder/nodes/dge/dgelogic/exists.html b/dgbuilder/nodes/dge/dgelogic/exists.html new file mode 100644 index 00000000..001e8ca1 --- /dev/null +++ b/dgbuilder/nodes/dge/dgelogic/exists.html @@ -0,0 +1,187 @@ + + + + + + + + diff --git a/dgbuilder/nodes/dge/dgelogic/exists.js b/dgbuilder/nodes/dge/dgelogic/exists.js new file mode 100644 index 00000000..d4482afc --- /dev/null +++ b/dgbuilder/nodes/dge/dgelogic/exists.js @@ -0,0 +1,31 @@ +/** + * Copyright 2013 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + var util = require("util"); + var vm = require("vm"); + + function exists(n) { + RED.nodes.createNode(this,n); + this.name = n.name; + this.xml = n.xml; + this.topic = n.topic; + } + + RED.nodes.registerType("exists",exists); + // RED.library.register("exists"); +} diff --git a/dgbuilder/nodes/dge/dgelogic/forNode.html b/dgbuilder/nodes/dge/dgelogic/forNode.html new file mode 100644 index 00000000..c7327db4 --- /dev/null +++ b/dgbuilder/nodes/dge/dgelogic/forNode.html @@ -0,0 +1,172 @@ + + + + + + + + diff --git a/dgbuilder/nodes/dge/dgelogic/forNode.js b/dgbuilder/nodes/dge/dgelogic/forNode.js new file mode 100644 index 00000000..567da858 --- /dev/null +++ b/dgbuilder/nodes/dge/dgelogic/forNode.js @@ -0,0 +1,31 @@ +/** + * Copyright 2013 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + var util = require("util"); + var vm = require("vm"); + + function forNode(n) { + RED.nodes.createNode(this,n); + this.name = n.name; + this.xml = n.xml; + this.topic = n.topic; + } + + RED.nodes.registerType("for",forNode); + // RED.library.register("for"); +} diff --git a/dgbuilder/nodes/dge/dgelogic/get-resource.html b/dgbuilder/nodes/dge/dgelogic/get-resource.html new file mode 100644 index 00000000..b3b65581 --- /dev/null +++ b/dgbuilder/nodes/dge/dgelogic/get-resource.html @@ -0,0 +1,192 @@ + + + + + + + + diff --git a/dgbuilder/nodes/dge/dgelogic/get-resource.js b/dgbuilder/nodes/dge/dgelogic/get-resource.js new file mode 100644 index 00000000..597e0219 --- /dev/null +++ b/dgbuilder/nodes/dge/dgelogic/get-resource.js @@ -0,0 +1,31 @@ +/** + * Copyright 2013 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + var util = require("util"); + var vm = require("vm"); + + function getResource(n) { + RED.nodes.createNode(this,n); + this.name = n.name; + this.xml = n.xml; + this.topic = n.topic; + } + + RED.nodes.registerType("get-resource",getResource); + // RED.library.register("get-resource"); +} diff --git a/dgbuilder/nodes/dge/dgelogic/is-available.html b/dgbuilder/nodes/dge/dgelogic/is-available.html new file mode 100644 index 00000000..8bc45ef5 --- /dev/null +++ b/dgbuilder/nodes/dge/dgelogic/is-available.html @@ -0,0 +1,186 @@ + + + + + + + + diff --git a/dgbuilder/nodes/dge/dgelogic/is-available.js b/dgbuilder/nodes/dge/dgelogic/is-available.js new file mode 100644 index 00000000..93f23f48 --- /dev/null +++ b/dgbuilder/nodes/dge/dgelogic/is-available.js @@ -0,0 +1,31 @@ +/** + * Copyright 2013 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + var util = require("util"); + var vm = require("vm"); + + function isAvailable(n) { + RED.nodes.createNode(this,n); + this.name = n.name; + this.xml = n.xml; + this.topic = n.topic; + } + + RED.nodes.registerType("is-available",isAvailable); + // RED.library.register("is-available"); +} diff --git a/dgbuilder/nodes/dge/dgelogic/notify.html b/dgbuilder/nodes/dge/dgelogic/notify.html new file mode 100644 index 00000000..e5bc24bc --- /dev/null +++ b/dgbuilder/nodes/dge/dgelogic/notify.html @@ -0,0 +1,195 @@ + + + + + + + + diff --git a/dgbuilder/nodes/dge/dgelogic/notify.js b/dgbuilder/nodes/dge/dgelogic/notify.js new file mode 100644 index 00000000..8b58e9e4 --- /dev/null +++ b/dgbuilder/nodes/dge/dgelogic/notify.js @@ -0,0 +1,31 @@ +/** + * Copyright 2013 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + var util = require("util"); + var vm = require("vm"); + + function notify(n) { + RED.nodes.createNode(this,n); + this.name = n.name; + this.xml = n.xml; + this.topic = n.topic; + } + + RED.nodes.registerType("notify",notify); + // RED.library.register("configure"); +} diff --git a/dgbuilder/nodes/dge/dgelogic/record.html b/dgbuilder/nodes/dge/dgelogic/record.html new file mode 100644 index 00000000..3eb7a2e6 --- /dev/null +++ b/dgbuilder/nodes/dge/dgelogic/record.html @@ -0,0 +1,185 @@ + + + + + + + + diff --git a/dgbuilder/nodes/dge/dgelogic/record.js b/dgbuilder/nodes/dge/dgelogic/record.js new file mode 100644 index 00000000..f29bf8f5 --- /dev/null +++ b/dgbuilder/nodes/dge/dgelogic/record.js @@ -0,0 +1,31 @@ +/** + * Copyright 2013 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + var util = require("util"); + var vm = require("vm"); + + function record(n) { + RED.nodes.createNode(this,n); + this.name = n.name; + this.xml = n.xml; + this.topic = n.topic; + } + + RED.nodes.registerType("record",record); + // RED.library.register("record"); +} diff --git a/dgbuilder/nodes/dge/dgelogic/release.html b/dgbuilder/nodes/dge/dgelogic/release.html new file mode 100644 index 00000000..044616a9 --- /dev/null +++ b/dgbuilder/nodes/dge/dgelogic/release.html @@ -0,0 +1,192 @@ + + + + + + + + diff --git a/dgbuilder/nodes/dge/dgelogic/release.js b/dgbuilder/nodes/dge/dgelogic/release.js new file mode 100644 index 00000000..ff03fff6 --- /dev/null +++ b/dgbuilder/nodes/dge/dgelogic/release.js @@ -0,0 +1,31 @@ +/** + * Copyright 2013 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + var util = require("util"); + var vm = require("vm"); + + function release(n) { + RED.nodes.createNode(this,n); + this.name = n.name; + this.xml = n.xml; + this.topic = n.topic; + } + + RED.nodes.registerType("release",release); + // RED.library.register("release"); +} diff --git a/dgbuilder/nodes/dge/dgelogic/reserve.html b/dgbuilder/nodes/dge/dgelogic/reserve.html new file mode 100644 index 00000000..bcd3fcb9 --- /dev/null +++ b/dgbuilder/nodes/dge/dgelogic/reserve.html @@ -0,0 +1,189 @@ + + + + + + + + diff --git a/dgbuilder/nodes/dge/dgelogic/reserve.js b/dgbuilder/nodes/dge/dgelogic/reserve.js new file mode 100644 index 00000000..6aab1bd7 --- /dev/null +++ b/dgbuilder/nodes/dge/dgelogic/reserve.js @@ -0,0 +1,31 @@ +/** + * Copyright 2013 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + var util = require("util"); + var vm = require("vm"); + + function reserve(n) { + RED.nodes.createNode(this,n); + this.name = n.name; + this.xml = n.xml; + this.topic = n.topic; + } + + RED.nodes.registerType("reserve",reserve); + // RED.library.register("reserve"); +} diff --git a/dgbuilder/nodes/dge/dgelogic/save.html b/dgbuilder/nodes/dge/dgelogic/save.html new file mode 100644 index 00000000..6e022154 --- /dev/null +++ b/dgbuilder/nodes/dge/dgelogic/save.html @@ -0,0 +1,189 @@ + + + + + + + + diff --git a/dgbuilder/nodes/dge/dgelogic/save.js b/dgbuilder/nodes/dge/dgelogic/save.js new file mode 100644 index 00000000..5771ae98 --- /dev/null +++ b/dgbuilder/nodes/dge/dgelogic/save.js @@ -0,0 +1,31 @@ +/** + * Copyright 2013 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + var util = require("util"); + var vm = require("vm"); + + function save(n) { + RED.nodes.createNode(this,n); + this.name = n.name; + this.xml = n.xml; + this.topic = n.topic; + } + + RED.nodes.registerType("save",save); + // RED.library.register("save"); +} diff --git a/dgbuilder/nodes/dge/dgelogic/set.html b/dgbuilder/nodes/dge/dgelogic/set.html new file mode 100644 index 00000000..bcbcae30 --- /dev/null +++ b/dgbuilder/nodes/dge/dgelogic/set.html @@ -0,0 +1,162 @@ + + + + + + + + diff --git a/dgbuilder/nodes/dge/dgelogic/set.js b/dgbuilder/nodes/dge/dgelogic/set.js new file mode 100644 index 00000000..9b939507 --- /dev/null +++ b/dgbuilder/nodes/dge/dgelogic/set.js @@ -0,0 +1,31 @@ +/** + * Copyright 2013 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + var util = require("util"); + var vm = require("vm"); + + function set(n) { + RED.nodes.createNode(this,n); + this.name = n.name; + this.xml = n.xml; + this.topic = n.topic; + } + + RED.nodes.registerType("set",set); + // RED.library.register("set"); +} diff --git a/dgbuilder/nodes/dge/dgelogic/switchNode.html b/dgbuilder/nodes/dge/dgelogic/switchNode.html new file mode 100644 index 00000000..35c9fe67 --- /dev/null +++ b/dgbuilder/nodes/dge/dgelogic/switchNode.html @@ -0,0 +1,232 @@ + + + + + + + + diff --git a/dgbuilder/nodes/dge/dgelogic/switchNode.js b/dgbuilder/nodes/dge/dgelogic/switchNode.js new file mode 100644 index 00000000..6a7a545d --- /dev/null +++ b/dgbuilder/nodes/dge/dgelogic/switchNode.js @@ -0,0 +1,31 @@ +/** + * Copyright 2013 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + var util = require("util"); + var vm = require("vm"); + + function switchNode(n) { + RED.nodes.createNode(this,n); + this.name = n.name; + this.xml = n.xml; + this.topic = n.topic; + } + + RED.nodes.registerType("switchNode",switchNode); + // RED.library.register("switch"); +} diff --git a/dgbuilder/nodes/dge/dgelogic/update.html b/dgbuilder/nodes/dge/dgelogic/update.html new file mode 100644 index 00000000..a7d28283 --- /dev/null +++ b/dgbuilder/nodes/dge/dgelogic/update.html @@ -0,0 +1,195 @@ + + + + + + + + diff --git a/dgbuilder/nodes/dge/dgelogic/update.js b/dgbuilder/nodes/dge/dgelogic/update.js new file mode 100644 index 00000000..f614af8b --- /dev/null +++ b/dgbuilder/nodes/dge/dgelogic/update.js @@ -0,0 +1,31 @@ +/** + * Copyright 2013 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + var util = require("util"); + var vm = require("vm"); + + function update(n) { + RED.nodes.createNode(this,n); + this.name = n.name; + this.xml = n.xml; + this.topic = n.topic; + } + + RED.nodes.registerType("update",update); + // RED.library.register("configure"); +} diff --git a/dgbuilder/nodes/dge/dgemain/GenericXML.html b/dgbuilder/nodes/dge/dgemain/GenericXML.html new file mode 100644 index 00000000..4c9c01a6 --- /dev/null +++ b/dgbuilder/nodes/dge/dgemain/GenericXML.html @@ -0,0 +1,140 @@ + + + + + + + + diff --git a/dgbuilder/nodes/dge/dgemain/GenericXML.js b/dgbuilder/nodes/dge/dgemain/GenericXML.js new file mode 100644 index 00000000..e5fc0624 --- /dev/null +++ b/dgbuilder/nodes/dge/dgemain/GenericXML.js @@ -0,0 +1,31 @@ +/** + * Copyright 2013 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + var util = require("util"); + var vm = require("vm"); + + function GenericXML(n) { + RED.nodes.createNode(this,n); + this.name = n.name; + this.xml = n.xml; + this.topic = n.topic; + } + + RED.nodes.registerType("GenericXML",GenericXML); + // RED.library.register("GenericXML"); +} diff --git a/dgbuilder/nodes/dge/dgemain/comment.html b/dgbuilder/nodes/dge/dgemain/comment.html new file mode 100644 index 00000000..c34d14c9 --- /dev/null +++ b/dgbuilder/nodes/dge/dgemain/comment.html @@ -0,0 +1,97 @@ + + + + + + + diff --git a/dgbuilder/nodes/dge/dgemain/comment.js b/dgbuilder/nodes/dge/dgemain/comment.js new file mode 100644 index 00000000..ef5f0800 --- /dev/null +++ b/dgbuilder/nodes/dge/dgemain/comment.js @@ -0,0 +1,23 @@ +/** + * Copyright 2013 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + function CommentNode(n) { + RED.nodes.createNode(this,n); + } + RED.nodes.registerType("comment",CommentNode); +} diff --git a/dgbuilder/nodes/dge/dgemain/dgstart.html b/dgbuilder/nodes/dge/dgemain/dgstart.html new file mode 100644 index 00000000..9caa841a --- /dev/null +++ b/dgbuilder/nodes/dge/dgemain/dgstart.html @@ -0,0 +1,1322 @@ + +

+ + + + + + + +
+ diff --git a/dgbuilder/nodes/dge/dgemain/dgstart.js b/dgbuilder/nodes/dge/dgemain/dgstart.js new file mode 100644 index 00000000..f2b4815e --- /dev/null +++ b/dgbuilder/nodes/dge/dgemain/dgstart.js @@ -0,0 +1,594 @@ +/** + * Copyright 2013 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + + +module.exports = function(RED) { + "use strict"; + var util = require("util"); + var vm = require("vm"); + //var dgxml=require("/home/users/schinthakayala/nodered/sheshi/dgxml/dgxml2"); + var _=require('lodash'); + var fs=require('fs'); + var path = require('path'); + var appDir = path.dirname(require.main.filename); + var userDir = appDir + "/" + RED.settings.userDir; + var dbHost = RED.settings.dbHost; + var request = require('request'); + var sharedDir = appDir + "/" + RED.settings.sharedDir; + var xmlDir = appDir + "/" + RED.settings.xmlPath; + + //console.log("appDir:" + appDir); + //var dgeraw=fs.readFileSync(appDir + "/dge.json").toString(); + //var dgejson=JSON.parse(dgeraw); + //var uploadUrl=dgejson.slaHost + dgejson.uploadUrl; + //var slaUrl=dgejson.slaHost + dgejson.slaUrl; + //var uploadUrl=RED.settings.slaHost + RED.settings.uploadUrl; + //var slaUrl=RED.settings.slaHost + RED.settings.slaUrl; + var uploadUrl=""; + var slaUrl=""; + //console.log("Upload url: " + uploadUrl); + + function dgstart(n) { + RED.nodes.createNode(this,n); + this.name = n.name; + this.topic = n.topic; + } + + function writeHtmlToFile(fileName,str){ + var localfile = appDir + "/" + RED.settings.htmlPath + fileName; + try{ + fs.writeFileSync(localfile,str); + }catch(e){ + console.log("Error:" + e); + } + } + + function writeXmlToFile(fileName,str){ + var localfile = appDir + "/" + RED.settings.xmlPath + fileName; + try{ + fs.writeFileSync(localfile,str); + }catch(e){ + console.log("Error:" + e); + } + } + + function sendXml(fileName,res) { + var needle, localfile, data; + needle = require('needle') + localfile = appDir + "/" + RED.settings.xmlPath + fileName; + console.log("localfile:" + localfile); + data={ + uploadedfile: { file: localfile, content_type: 'text/xml' } + } + needle.post(uploadUrl, data, { multipart: true }, function(err, resp, body) { + //console.log(body) + if(resp != undefined && resp != null){ + console.log("resp Code for sendXml:" + resp.statusCode); + } + fs.unlink(localfile, function (error) { + if (error) { + console.log("Error deleting file "+localfile); + }else{ + //console.log("deleted file:" + localfile); + } + }); + + if(err){ + console.log("Error posting to slaUrl:" + slaUrl); + console.log("Error:" +err); + res.json({"error":err}); + }else{ + //console.dir(resp); + //console.log("slaUrl:" + slaUrl); + res.json({"url":slaUrl}); + } + + }); + } + + function oldsendXml(fileName) { + console.log("In sendXML for file: " + fileName); + var fileStream, formdata, localfile; + localfile = appDir + "/" + RED.settings.xmlPath + fileName; + + formdata = { + MAX_FILE_SIZE: "100000", + uploadedfile: { + options: { + contentType: 'audio/mpeg' + } + } + + }; + + console.log("Attempting to upload file: " + localfile); + console.log("Sending to: " + uploadUrl); + formdata.uploadedfile.value = fs.createReadStream(localfile); + fileStream = formdata.uploadedfile.value; + +//console.log("Formdata:"); +//console.dir(formdata); + + request.post({ + url: uploadUrl, + proxy: false, + formData: formdata + }, function(err, resp, body) { + fileStream.close(); + console.log("err: " + err); + return console.log("body: " + body); + }); + + }; + + RED.nodes.registerType("dgstart",dgstart); +/* + RED.httpAdmin.post("/uploadxml", function(req,res) { + console.dir(req); + console.log("USER:" + req.user); + console.log("Got request to upload xml to SDN-C."); + console.log("Requested filename to upload: " + req.params.fileName); + console.log("Requested xml to upload: " + req.params.xmlStr); + writeToFile( req.params.fileName,req.params.xmlStr); + + sendXml(req.params.fileName,res); + // res.send("Attempt complete."); + // res.redirect(slaUrl); + }); +*/ + + RED.httpAdmin.post("/OldUploadxml", function(req,res) { + //console.dir(req); + //console.log("USER:" + req.user); + var qs = require('querystring'); + var body = ''; + req.on('data', function (data) { + body += data; + // Too much POST data, kill the connection! + /*if (body.length > 1e6) + request.connection.destroy(); + */ + }); + req.on('end', function () { + //console.log("BODY:" + body); + var d = new Date().getTime(); + var user = req.user; + var fileName= user + "_" + d +".xml"; + var post = qs.parse(body); + //console.log(JSON.stringify(post)); + // use post['blah'], etc. + var localfile = appDir + "/" + RED.settings.xmlPath + fileName; + //console.log("localfile:" + localfile); + var xmlStr = post['flowXml']; + writeXmlToFile(fileName,xmlStr); + sendXml(fileName,res); + + }); + + }); + + RED.httpAdmin.post("/uploadxml", function(req,res) { + //console.dir(req); + //console.log("USER:" + req.user); + var qs = require('querystring'); + var body = ''; + req.on('data', function (data) { + body += data; + // Too much POST data, kill the connection! + /*if (body.length > 1e6) + request.connection.destroy(); + */ + }); + req.on('end', function () { + //console.log("BODY:" + body); + var d = new Date().getTime(); + var user = req.user; + var fileName= user + "_" + d +".xml"; + var post = qs.parse(body); + //console.log(JSON.stringify(post)); + // use post['blah'], etc. + var localfile = appDir + "/" + RED.settings.xmlPath + fileName; + //console.log("localfile:" + localfile); + var xmlStr = post['flowXml']; + var moduleName = post['module']; + var rpc = post['rpc']; + writeXmlToFile(fileName,xmlStr); + uploadDG(localfile,moduleName,rpc,res); + }); + + }); + + +function uploadDG(filePath,moduleName,rpc,res){ + console.log("called uploadDG..."); + var exec = require('child_process').exec; + var commandToExec = appDir + "/svclogic/svclogic.sh load " + filePath + " " + userDir + "/conf/svclogic.properties"; + console.log("commandToExec:" + commandToExec); + var child = exec(commandToExec ,function (error,stdout,stderr){ + //console.log(error); + console.log("stdout:" + stdout); + console.log("stderr:" + stderr); + if(error){ + console.log("Error occured:" + error); + if(stderr){ + //console.log("stderr:" + stderr); + res.send(500,{'error':error,'stderr':stderr}); + }else{ + res.send(500,{'error':error}); + } + //console.log("stdout :" + stdout); + }else{ + if(stdout ){ + //console.log("output:" + stdout); + if(stdout.indexOf('Compiler error') != -1){ + //console.log("compileError occured."); + + var resp = { + 'stdout':stdout, + 'stderr':"COMPILE_ERROR", + 'url':dbHost, + 'module':moduleName, + 'rpc':rpc + } + res.send(500,resp); + }else{ + res.send(200,{'stdout':stdout,'stderr':stderr,"url":dbHost,"module" : moduleName,"rpc" : rpc}); + } + } + if(stderr && !stdout){ + //console.log("stderr:" + stderr); + if(stderr.indexOf("Saving SvcLogicGraph to database") != -1){ + res.send(200,{'error':error,'stdout' :'','stderr':stderr,"url":dbHost,"module" : moduleName,"rpc" : rpc}); + }else{ + res.send(500,{'error':error,'stdout' :'','stderr':stderr}); + } + } + } + }); +} + + RED.httpAdmin.get("/displayXml", function(req,res) { + var _module = req.query._module; + var rpc = req.query.rpc; + var version = req.query.version; + var mode = req.query.mode; + var d = new Date().getTime(); + displayXml(_module,rpc,version,mode,res); + }); + +function displayXml(_module,rpc,version,mode,res){ + var exec = require('child_process').exec; + var msg = { + '_module' : _module, + 'rpc' : rpc, + 'version' : version, + 'mode' : mode + } + var commandToExec = appDir + "/svclogic/svclogic.sh get-source " + _module + " " + + rpc + " " + mode + " " + version + " " + userDir + "/conf/svclogic.properties"; + console.log("commandToExec:" + commandToExec); + var child = exec(commandToExec ,{'maxBuffer':16*1024*1024},function (error,stdout,stderr){ + if(error){ + console.log("Error occured:" + error); + if(stderr){ + //console.log("stderr:" + stderr); + res.send(500,{'error':error,'stderr':stderr,'msg':msg}); + }else{ + res.send(500,{'error':error,'msg':msg}); + } + }else{ + if(stderr){ + console.log("stderr:" + stderr); + } + if(stdout){ + res.send({'xmldata' : "" + stdout + ""}); + } + } + }); +} + + + RED.httpAdmin.post("/downloadDGXml", function(req,res) { + //console.dir(req); + var qs = require('querystring'); + var body = ''; + req.on('data', function (data) { + body += data; + }); + + req.on('end', function () { + var post = qs.parse(body); + var _module = post._module; + var rpc = post.rpc; + var version = post.version; + var mode = post.mode; + var d = new Date().getTime(); + downloadDGXml(_module,rpc,version,mode,res); + }); + }); + +function downloadDGXml(_module,rpc,version,mode,res){ + var exec = require('child_process').exec; + var msg = { + '_module' : _module, + 'rpc' : rpc, + 'version' : version, + 'mode' : mode + } + var commandToExec = appDir + "/svclogic/svclogic.sh get-source " + _module + " " + + rpc + " " + mode + " " + version + " " + userDir + "/conf/svclogic.properties"; + console.log("commandToExec:" + commandToExec); + var child = exec(commandToExec ,function (error,stdout,stderr){ + if(error){ + console.log("Error occured:" + error); + if(stderr){ + //console.log("stderr:" + stderr); + res.send(500,{'error':error,'stderr':stderr,'msg':msg}); + }else{ + res.send(500,{'error':error,'msg':msg}); + } + }else{ + if(stderr){ + console.log("stderr:" + stderr); + } + if(stdout){ + //console.log("output:" + stdout); + //var newOutput = "
" + stdout.replace(/\n/g,'
') + "
"; + //res.json({'stdout': stdout ,'stderr':stderr,"msg":msg}); + //res.set('Content-Type', 'text/xml'); + //res.set('Content-Type', 'application/octet-stream'); + //res.end("" + stdout + "" ); + //var newOutput ="" + stdout + ""; + //res.send(new Buffer( "" + newOutput + "" ) ); + //res.send(newOutput); + + /* + var xslStr = '' + + '' + + '' + + '' + + '' + + '' + + '' + + ''; + */ + + var formatted_date = getCurrentDate(); + var fileName= "db_" + _module + "_" +rpc+ "_" + version + "_" + formatted_date + ".html"; + var file = xmlDir + "/" + fileName; + var xmlStr = '' + stdout + ""; + //var xmlStr = "/g,">"); + //xmlStr = xmlStr.replace(/\n>/g,"
"); + //xmlStr = xmlStr.replace(/\t>/g,"   "); + + writeToFile(file,"" +xmlStr+ ""); + //console.log("xmlStr:" + xmlStr); + res.setHeader('Content-disposition', 'attachment; filename=' + file); + //res.setHeader('Content-type', 'text/html'); + res.setHeader('Content-type', 'text/xml'); + res.download(file); + } + } + }); +} + + + RED.httpAdmin.get("/displayAsGv", function(req,res) { + var _module = req.query._module; + var rpc = req.query.rpc; + var version = req.query.version; + var mode = req.query.mode; + var d = new Date().getTime(); + displayAsGv(_module,rpc,version,mode,res); + }); + +function displayAsGv(_module,rpc,version,mode,res){ + var exec = require('child_process').exec; + var msg = { + '_module' : _module, + 'rpc' : rpc, + 'version' : version, + 'mode' : mode + } + var commandToExec = appDir + "/svclogic/svclogic.sh print " + + _module + " " + rpc + " " + mode + " " + version + " " + //+ userDir + "/conf/svclogic.properties | dot -Tpng "; + //the label="""" is giving an error so replacing it with "null" + + userDir + "/conf/svclogic.properties |sed -e 's%label=\"\"\"\"%label=\"null\"%g'| dot -Tsvg "; + console.log("commandToExec:" + commandToExec); + //+ userDir + "/conf/svclogic.properties | dot -Tsvg "; + //var child = exec(commandToExec ,function (error,stdout,stderr){ + //var child = exec(commandToExec ,{maxBuffer:16*1024*1024},function (error,stdout,stderr){ + //var child = exec(commandToExec ,{encoding:'base64',maxBuffer:20*1024*1024},function (error,stdout,stderr){ + var child = exec(commandToExec ,{maxBuffer:20*1024*1024},function (error,stdout,stderr){ + if(error){ + console.log("Error occured:" + error); + if(stderr){ + console.log("stderr:" + stderr); + res.send(500,{'error':error,'stderr':stderr,"msg":msg}); + }else{ + res.send(500,{'error':error,"msg":msg}); + } + }else{ + if(stderr){ + console.log("stderr:" + stderr); + //To convert base64 to ascii + //console.log(new Buffer(stderr, 'base64').toString('ascii')); + } + if(stdout){ + //console.log(stdout.length); + //console.log("output:" + stdout); + //var svg_html = stdout ; + //var image = ""; + //var image = "