Skip to content

Instantly share code, notes, and snippets.

@juzam

juzam/README.md Secret

Last active February 25, 2017 15:04
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save juzam/e172df1c478f1aa4e37eb007530261a9 to your computer and use it in GitHub Desktop.
Save juzam/e172df1c478f1aa4e37eb007530261a9 to your computer and use it in GitHub Desktop.
Twitter enabled web page slideshow

This flow is based almost entirely on https://flows.nodered.org/flow/8666510f94ad422e4765

It adds a Twitter user input (@archillect) extracts the https url of the posted media and feed said url to the websocket, so it can be displayed by the webpage available at 'http://{your-server-ip:1880/slideshow'

The image gets somewhat resized to the dimension of the browser window. It's not working 100% of the time i.e. with 16:10 aspect monitors the images get stretched too much, It's far from perfect, but it's a start. In the page template there's some javascript added so you can go fullscreen (but that gets resetted when the image changes) see: http://blogs.sitepointstatic.com/examples/tech/full-screen/index.html

It works quite well if you cast a tab of your browser to a chromecast, or if you have a spare tablet you can basically have a Twitter powered photo display.

[
{
"id": "affb0fda.9189c",
"type": "twitter in",
"z": "fb5b6e33.9bc11",
"twitter": "",
"tags": "@archillect",
"user": "user",
"name": "",
"topic": "tweets",
"x": 170,
"y": 60,
"wires": [
[
"2ee36506.9e365a",
"e27ad042.65f95"
]
]
},
{
"id": "e27ad042.65f95",
"type": "change",
"z": "fb5b6e33.9bc11",
"name": "get tweet object",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "tweet",
"tot": "msg"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 160,
"y": 140,
"wires": [
[
"62c28189.4ce19"
]
]
},
{
"id": "62c28189.4ce19",
"type": "change",
"z": "fb5b6e33.9bc11",
"name": "get media https url",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "payload.entities.media[0].media_url_https",
"tot": "msg"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 390,
"y": 140,
"wires": [
[
"b7450e85.a8207",
"fc94d254.85dd1"
]
]
},
{
"id": "fc94d254.85dd1",
"type": "websocket out",
"z": "fb5b6e33.9bc11",
"name": "",
"server": "bc725200.1dc2d",
"client": "",
"x": 550,
"y": 260,
"wires": []
},
{
"id": "8905b6ac.848648",
"type": "http in",
"z": "fb5b6e33.9bc11",
"name": "",
"url": "/slideshow",
"method": "get",
"swaggerDoc": "",
"x": 140,
"y": 200,
"wires": [
[
"6864b831.fe7818"
]
]
},
{
"id": "6864b831.fe7818",
"type": "template",
"z": "fb5b6e33.9bc11",
"name": "HTML Slideshow",
"field": "payload",
"fieldType": "msg",
"format": "html",
"syntax": "mustache",
"template": "<!DOCTYPE HTML>\n<html>\n <head>\n <style>\n*\n{\n\tpadding: 0;\n\tmargin: 0;\n}\n\nhtml, body\n{\n\tfont-family: \"Segoe UI\", arial, helvetica, freesans, sans-serif;\n\tcolor: #333;\n\tbackground-color: #000;\n\toverflow-y: auto;\n\toverflow-x: auto;\n}\n\nbody\n{\n\tmargin: 0 auto;\n\tmax-height: 100%;\n max-width: 100%;\n}\n\np\n{\n\tmargin: 0 0 1em 0;\n}\n\nsection\n{\n\tdisplay: block;\n\tfloat: center;\n\tpadding: 0;\n\tmargin: 0 auto;\n\tborder: 0 none;\n\tcursor: pointer;\n\tmax-height: 100%;\n max-width: 100%;\n}\n\n\nsection img\n{\n\twidth: 100%;\n\theight: 100%;\n}\n\n\nsection p\n{\n\tfont-weight: bold;\n\ttext-align: center;\n\tmargin: 0;\n}\n\nsection:-webkit-full-screen\n{\n\tfloat: none;\n\twidth: 100%;\n\theight: 100%;\n\tpadding: 0;\n\tmargin: 0;\n\tborder: 0 none;\n\tbackground-color: #f00;\n}\n\nsection:-moz-full-screen\n{\n\tfloat: none;\n\twidth: 100%;\n\theight: 100%;\n\tpadding: 0;\n\tmargin: 0;\n\tborder: 0 none;\n}\n\nsection:-ms-full-screen\n{\n\tfloat: none;\n\twidth: 100%;\n\theight: 100%;\n\tpadding: 0;\n\tmargin: 0;\n\tborder: 0 none;\n}\n\nsection:-o-full-screen\n{\n\tfloat: none;\n\twidth: 100%;\n\theight: 100%;\n\tpadding: 0;\n\tmargin: 0;\n\tborder: 0 none;\n}\n\nsection:full-screen\n{\n\tfloat: none;\n\twidth: 100%;\n\theight: 100%;\n\tpadding: 0;\n\tmargin: 0;\n\tborder: 0 none;\n}\n</style>\n <title>Simple Live Display</title>\n <script src=\"https://code.jquery.com/jquery-latest.js\"></script>\n <script type=\"text/javascript\">\n var ws;\n var wsUri = \"ws:\";\n var loc = window.location;\n console.log(loc);\n if (loc.protocol === \"https:\") { wsUri = \"wss:\"; }\n // This needs to point to the web socket in the Node-RED flow\n // ... in this case it's ws/simple\n wsUri += \"//\" + loc.host + loc.pathname.replace(\"slideshow\",\"ws/slideshow\");\n\n function wsConnect() {\n console.log(\"connect\",wsUri);\n ws = new WebSocket(wsUri);\n //var line = \"\"; // either uncomment this for a building list of messages\n ws.onmessage = function(msg) {\n var line = \"\"; // or uncomment this to overwrite the existing message\n // parse the incoming message as a JSON object\n var data = msg.data;\n //console.log(data);\n // build the output from the topic and payload parts of the object\n // line += \"<p>\"+data+\"</p>\";\n line += '<section id=\"fullscreen\" onclick=\"gofull();\"><img onload=\"fit_to_screen();\" src=\"' + data + '\"/></section>'\n // replace the messages div with the new \"line\"\n document.getElementById('messages').innerHTML = line;\n //ws.send(JSON.stringify({data:data}));\n set_body_height();\n }\n ws.onopen = function() {\n // update the status div with the connection status\n document.getElementById('status').innerHTML = \"connected\";\n //ws.send(\"Open for data\");\n console.log(\"connected\");\n }\n ws.onclose = function() {\n // update the status div with the connection status\n document.getElementById('status').innerHTML = \"not connected\";\n // in case of lost connection tries to reconnect every 3 secs\n setTimeout(wsConnect,3000);\n }\n }\n \n function set_body_height() { // set body height = window height\n $('body').height($(window).height());\n $('body').width($(window).width());\n fit_to_screen();\n }\n $(document).ready(function() {\n $(window).bind('resize', set_body_height);\n set_body_height();\n });\n \n function fit_to_screen() {\n img.removeAttribute(\"style\");\n // var winX = window.innerWidth + \"px\";\n var winX = $(window).width();\n // var winY = window.innerHeight + \"px\";\n var winY = $(window).height();\n var vbar = false;\n if (document.body.scrollHeight > document.body.clientHeight) // vertical scrollbar\n {\n img.style.height = winY;\n vbar = true;\n }\n if (document.body.scrollWidth > document.body.clientWidth) // horizontal scrollbar\n {\n if (vbar) // both scrollbars\n {\n if ((document.body.scrollHeight - document.body.clientHeight) > (document.body.scrollWidth - document.body.clientWidth)) // let's see which one is bigger\n {\n img.removeAttribute(\"style\");\n img.style.height = winY;\n }\n else\n {\n img.removeAttribute(\"style\");\n img.style.width = winX;\n }\n }\n else\n {\n img.removeAttribute(\"style\");\n img.style.width = winX;\n }\n }\n }\n \n function gofull() {\n \n var e = document.getElementById(\"fullscreen\");\n\n\t if (RunPrefixMethod(document, \"FullScreen\") || RunPrefixMethod(document, \"IsFullScreen\")) {\n\t\t RunPrefixMethod(document, \"CancelFullScreen\");\n\t }\n\t else {\n\t\t RunPrefixMethod(e, \"RequestFullScreen\");\n\t }\n\n }\n\n var pfx = [\"webkit\", \"moz\", \"ms\", \"o\", \"\"];\n function RunPrefixMethod(obj, method) {\n\t\n\t var p = 0, m, t;\n\t while (p < pfx.length && !obj[m]) {\n\t \tm = method;\n\t \tif (pfx[p] == \"\") {\n\t \t\tm = m.substr(0,1).toLowerCase() + m.substr(1);\n\t \t}\n \t\tm = pfx[p] + m;\n \t\tt = typeof obj[m];\n \t\tif (t != \"undefined\") {\n\t\t\t pfx = [pfx[p]];\n\t\t\t return (t == \"function\" ? obj[m]() : obj[m]);\n\t\t }\n\t\t p++;\n\t }\n\n }\n \n function doit(m) {\n if (ws) { ws.send(m); }\n }\n </script>\n </head>\n <body onload=\"wsConnect();\" onunload=\"ws.disconnect();\">\n <font face=\"Arial\">\n <div id=\"messages\"></div>\n <!-- <button type=\"button\" onclick='gofull();'>Full Screen</button> -->\n <!-- <button type=\"button\" onclick='fit_to_screen();'>Fit</button> -->\n <div id=\"status\">unknown</div>\n </font>\n </body>\n</html>\n",
"x": 338,
"y": 200,
"wires": [
[
"b7cabbb.ce8e248"
]
]
},
{
"id": "b7cabbb.ce8e248",
"type": "http response",
"z": "fb5b6e33.9bc11",
"name": "",
"x": 550,
"y": 200,
"wires": []
},
{
"id": "bc725200.1dc2d",
"type": "websocket-listener",
"z": "",
"path": "/ws/slideshow",
"wholemsg": "false"
}
]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment