initial checkin
This commit is contained in:
186
EventSource.js
Normal file
186
EventSource.js
Normal file
@@ -0,0 +1,186 @@
|
|||||||
|
;(function (global) {
|
||||||
|
|
||||||
|
if ("EventSource" in global) return;
|
||||||
|
|
||||||
|
var reTrim = /^(\s|\u00A0)+|(\s|\u00A0)+$/g;
|
||||||
|
|
||||||
|
var EventSource = function (url) {
|
||||||
|
var eventsource = this,
|
||||||
|
interval = 500, // polling interval
|
||||||
|
lastEventId = null,
|
||||||
|
cache = '';
|
||||||
|
|
||||||
|
if (!url || typeof url != 'string') {
|
||||||
|
throw new SyntaxError('Not enough arguments');
|
||||||
|
}
|
||||||
|
|
||||||
|
this.URL = url;
|
||||||
|
this.readyState = this.CONNECTING;
|
||||||
|
this._pollTimer = null;
|
||||||
|
this._xhr = null;
|
||||||
|
|
||||||
|
function pollAgain(interval) {
|
||||||
|
eventsource._pollTimer = setTimeout(function () {
|
||||||
|
poll.call(eventsource);
|
||||||
|
}, interval);
|
||||||
|
}
|
||||||
|
|
||||||
|
function poll() {
|
||||||
|
try { // force hiding of the error message... insane?
|
||||||
|
if (eventsource.readyState == eventsource.CLOSED) return;
|
||||||
|
|
||||||
|
// NOTE: IE7 and upwards support
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
xhr.open('GET', eventsource.URL, true);
|
||||||
|
xhr.setRequestHeader('Accept', 'text/event-stream');
|
||||||
|
xhr.setRequestHeader('Cache-Control', 'no-cache');
|
||||||
|
// we must make use of this on the server side if we're working with Android - because they don't trigger
|
||||||
|
// readychange until the server connection is closed
|
||||||
|
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
|
||||||
|
|
||||||
|
if (lastEventId != null) xhr.setRequestHeader('Last-Event-ID', lastEventId);
|
||||||
|
cache = '';
|
||||||
|
|
||||||
|
xhr.timeout = 50000;
|
||||||
|
xhr.onreadystatechange = function () {
|
||||||
|
if (this.readyState == 3 || (this.readyState == 4 && this.status == 200)) {
|
||||||
|
// on success
|
||||||
|
if (eventsource.readyState == eventsource.CONNECTING) {
|
||||||
|
eventsource.readyState = eventsource.OPEN;
|
||||||
|
eventsource.dispatchEvent('open', { type: 'open' });
|
||||||
|
}
|
||||||
|
|
||||||
|
var responseText = '';
|
||||||
|
try {
|
||||||
|
responseText = this.responseText || '';
|
||||||
|
} catch (e) {}
|
||||||
|
|
||||||
|
// process this.responseText
|
||||||
|
var parts = responseText.substr(cache.length).split("\n"),
|
||||||
|
eventType = 'message',
|
||||||
|
data = [],
|
||||||
|
i = 0,
|
||||||
|
line = '';
|
||||||
|
|
||||||
|
cache = responseText;
|
||||||
|
|
||||||
|
// TODO handle 'event' (for buffer name), retry
|
||||||
|
for (; i < parts.length; i++) {
|
||||||
|
line = parts[i].replace(reTrim, '');
|
||||||
|
if (line.indexOf('event') == 0) {
|
||||||
|
eventType = line.replace(/event:?\s*/, '');
|
||||||
|
} else if (line.indexOf('retry') == 0) {
|
||||||
|
retry = parseInt(line.replace(/retry:?\s*/, ''));
|
||||||
|
if(!isNaN(retry)) { interval = retry; }
|
||||||
|
} else if (line.indexOf('data') == 0) {
|
||||||
|
data.push(line.replace(/data:?\s*/, ''));
|
||||||
|
} else if (line.indexOf('id:') == 0) {
|
||||||
|
lastEventId = line.replace(/id:?\s*/, '');
|
||||||
|
} else if (line.indexOf('id') == 0) { // this resets the id
|
||||||
|
lastEventId = null;
|
||||||
|
} else if (line == '') {
|
||||||
|
if (data.length) {
|
||||||
|
var event = new MessageEvent(data.join('\n'), eventsource.url, lastEventId);
|
||||||
|
eventsource.dispatchEvent(eventType, event);
|
||||||
|
data = [];
|
||||||
|
eventType = 'message';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.readyState == 4) pollAgain(interval);
|
||||||
|
// don't need to poll again, because we're long-loading
|
||||||
|
} else if (eventsource.readyState !== eventsource.CLOSED) {
|
||||||
|
if (this.readyState == 4) { // and some other status
|
||||||
|
// dispatch error
|
||||||
|
eventsource.readyState = eventsource.CONNECTING;
|
||||||
|
eventsource.dispatchEvent('error', { type: 'error' });
|
||||||
|
pollAgain(interval);
|
||||||
|
} else if (this.readyState == 0) { // likely aborted
|
||||||
|
pollAgain(interval);
|
||||||
|
} else {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
xhr.send();
|
||||||
|
|
||||||
|
setTimeout(function () {
|
||||||
|
if (true || xhr.readyState == 3) xhr.abort();
|
||||||
|
}, xhr.timeout);
|
||||||
|
|
||||||
|
eventsource._xhr = xhr;
|
||||||
|
|
||||||
|
} catch (e) { // in an attempt to silence the errors
|
||||||
|
eventsource.dispatchEvent('error', { type: 'error', data: e.message }); // ???
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
poll(); // init now
|
||||||
|
};
|
||||||
|
|
||||||
|
EventSource.prototype = {
|
||||||
|
close: function () {
|
||||||
|
// closes the connection - disabling the polling
|
||||||
|
this.readyState = this.CLOSED;
|
||||||
|
clearInterval(this._pollTimer);
|
||||||
|
this._xhr.abort();
|
||||||
|
},
|
||||||
|
CONNECTING: 0,
|
||||||
|
OPEN: 1,
|
||||||
|
CLOSED: 2,
|
||||||
|
dispatchEvent: function (type, event) {
|
||||||
|
var handlers = this['_' + type + 'Handlers'];
|
||||||
|
if (handlers) {
|
||||||
|
for (var i = 0; i < handlers.length; i++) {
|
||||||
|
handlers[i].call(this, event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this['on' + type]) {
|
||||||
|
this['on' + type].call(this, event);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
addEventListener: function (type, handler) {
|
||||||
|
if (!this['_' + type + 'Handlers']) {
|
||||||
|
this['_' + type + 'Handlers'] = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
this['_' + type + 'Handlers'].push(handler);
|
||||||
|
},
|
||||||
|
removeEventListener: function (type, handler) {
|
||||||
|
var handlers = this['_' + type + 'Handlers'];
|
||||||
|
if (!handlers) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (var i = handlers.length - 1; i >= 0; --i) {
|
||||||
|
if (handlers[i] === handler) {
|
||||||
|
handlers.splice(i, 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onerror: null,
|
||||||
|
onmessage: null,
|
||||||
|
onopen: null,
|
||||||
|
readyState: 0,
|
||||||
|
URL: ''
|
||||||
|
};
|
||||||
|
|
||||||
|
var MessageEvent = function (data, origin, lastEventId) {
|
||||||
|
this.data = data;
|
||||||
|
this.origin = origin;
|
||||||
|
this.lastEventId = lastEventId || '';
|
||||||
|
};
|
||||||
|
|
||||||
|
MessageEvent.prototype = {
|
||||||
|
data: null,
|
||||||
|
type: 'message',
|
||||||
|
lastEventId: '',
|
||||||
|
origin: ''
|
||||||
|
};
|
||||||
|
|
||||||
|
if ('module' in global) module.exports = EventSource;
|
||||||
|
global.EventSource = EventSource;
|
||||||
|
|
||||||
|
})(this);
|
||||||
212
display.html
Normal file
212
display.html
Normal file
@@ -0,0 +1,212 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8"/>
|
||||||
|
<title>Joe's Web-Clipboard</title>
|
||||||
|
</head>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family:Verdana,sans-serif;
|
||||||
|
}
|
||||||
|
span.label {
|
||||||
|
float:left;
|
||||||
|
width:100px;
|
||||||
|
}
|
||||||
|
input.url {
|
||||||
|
width:350px;
|
||||||
|
border:1px solid;
|
||||||
|
}
|
||||||
|
span#pnlConnectionState {
|
||||||
|
font-size:10px;
|
||||||
|
position:fixed;
|
||||||
|
right:0;
|
||||||
|
border:1px solid;
|
||||||
|
padding:5px;
|
||||||
|
text-align:center;
|
||||||
|
background:#EEEEEE;
|
||||||
|
margin-right:10px;
|
||||||
|
}
|
||||||
|
div.circle {
|
||||||
|
position:relative;
|
||||||
|
left:40%;
|
||||||
|
width: 15px;
|
||||||
|
height: 15px;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
textarea#taValue {
|
||||||
|
width:95%;
|
||||||
|
display:block;
|
||||||
|
max-width:95%;
|
||||||
|
line-height:1.5;
|
||||||
|
padding:15px 15px 30px;
|
||||||
|
border-radius:3px;
|
||||||
|
border:1px solid #F7E98D;
|
||||||
|
font:13px Tahoma, cursive;
|
||||||
|
transition:box-shadow 0.5s ease;
|
||||||
|
box-shadow:0 4px 6px rgba(0,0,0,0.1);
|
||||||
|
font-smoothing:subpixel-antialiased;
|
||||||
|
background:linear-gradient(#F9EFAF, #F7E98D);
|
||||||
|
background:-o-linear-gradient(#F9EFAF, #F7E98D);
|
||||||
|
background:-ms-linear-gradient(#F9EFAF, #F7E98D);
|
||||||
|
background:-moz-linear-gradient(#F9EFAF, #F7E98D);
|
||||||
|
background:-webkit-linear-gradient(#F9EFAF, #F7E98D);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
|
||||||
|
<script src="EventSource.js"></script> <!-- polyfill for IE -->
|
||||||
|
<script src="autosize.min.js"></script>
|
||||||
|
<script>
|
||||||
|
var webclip = (function () {
|
||||||
|
"use strict";
|
||||||
|
var source;
|
||||||
|
var lastTimeStamp;
|
||||||
|
var oldContent;
|
||||||
|
|
||||||
|
function loadData(id) {
|
||||||
|
$.get("raw/" + id, function (data) {
|
||||||
|
$("#lbNew").hide();
|
||||||
|
$("#taValue").val(data);
|
||||||
|
oldContent=data;
|
||||||
|
enableDisableButtons();
|
||||||
|
autosize($('#taValue'));
|
||||||
|
}).fail(function () {
|
||||||
|
$("#lbNew").show();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function startEventStream() {
|
||||||
|
source = new EventSource('events/' + $("#tbId").val());
|
||||||
|
|
||||||
|
source.addEventListener('message', function (event) {
|
||||||
|
console.log(event.data);
|
||||||
|
var data = JSON.parse(event.data);
|
||||||
|
if (data.timeStamp !== lastTimeStamp) {
|
||||||
|
if (0 !== lastTimeStamp) {
|
||||||
|
console.log("dirty - reloading");
|
||||||
|
loadData($("#tbId").val());
|
||||||
|
}
|
||||||
|
lastTimeStamp = data.timeStamp;
|
||||||
|
}
|
||||||
|
}, false);
|
||||||
|
|
||||||
|
source.addEventListener('open', function (e) {
|
||||||
|
console.log('> Connection was opened', e);
|
||||||
|
}, false);
|
||||||
|
|
||||||
|
source.addEventListener('error', function (e) {
|
||||||
|
if (e.eventPhase === 2) { //EventSource.CLOSED
|
||||||
|
console.log('> Connection was closed [ERR]');
|
||||||
|
}
|
||||||
|
console.log('> Connection error', e);
|
||||||
|
}, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeEventStream() {
|
||||||
|
console.log('> Closing EventStream');
|
||||||
|
try {
|
||||||
|
source.close();
|
||||||
|
}finally{}
|
||||||
|
}
|
||||||
|
|
||||||
|
function monitorConnectionState() {
|
||||||
|
if (source.readyState === 1) {
|
||||||
|
$("#icoStateConnected").show();
|
||||||
|
$("#icoStateDisconnected").hide();
|
||||||
|
} else {
|
||||||
|
$("#icoStateConnected").hide();
|
||||||
|
$("#icoStateDisconnected").show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveData(id) {
|
||||||
|
closeEventStream();
|
||||||
|
$.post("save/" + id, {
|
||||||
|
data: $("#taValue").val()
|
||||||
|
}, function (data) {
|
||||||
|
$("#lbNew").hide();
|
||||||
|
console.log("AfterSave", data);
|
||||||
|
var jData = JSON.parse(data);
|
||||||
|
lastTimeStamp = jData.timeStamp;
|
||||||
|
oldContent=$("#taValue").val();
|
||||||
|
manageDirtyFlag();
|
||||||
|
startEventStream();
|
||||||
|
}).fail(function(xhr,textStatus,errorThrown){
|
||||||
|
console.log("ERROOOR",xhr,textStatus,errorThrown);
|
||||||
|
closeEventStream();
|
||||||
|
startEventStream();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function enableDisableButtons() {
|
||||||
|
if ($("#tbId").val() === "") {
|
||||||
|
$("#btnLoad").prop('disabled', true);
|
||||||
|
$("#btnSave").prop('disabled', true);
|
||||||
|
} else {
|
||||||
|
$("#btnLoad").prop('disabled', false);
|
||||||
|
if (!isContentChanged()){
|
||||||
|
$("#btnSave").prop('disabled', true);
|
||||||
|
$("#flgIsDirty").hide();
|
||||||
|
} else {
|
||||||
|
$("#btnSave").prop('disabled', false);
|
||||||
|
$("#flgIsDirty").show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function manageDirtyFlag(){
|
||||||
|
enableDisableButtons();
|
||||||
|
}
|
||||||
|
|
||||||
|
function isContentChanged(){
|
||||||
|
if (oldContent !== $("#taValue").val()) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$(document).ready(function () {
|
||||||
|
$("#tbId").val(location.href.substr(location.href.lastIndexOf('/') + 1));
|
||||||
|
$("#tbURLEdit").val($(location).attr("href"));
|
||||||
|
$("#tbURLRaw").val($(location).attr("href").replace("/wc/", "/wc/raw/"));
|
||||||
|
loadData($("#tbId").val());
|
||||||
|
|
||||||
|
lastTimeStamp = 0;
|
||||||
|
startEventStream();
|
||||||
|
window.setInterval(monitorConnectionState,1000);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
return {
|
||||||
|
saveData: saveData,
|
||||||
|
enableDisableButtons: enableDisableButtons,
|
||||||
|
manageDirtyFlag: manageDirtyFlag
|
||||||
|
};
|
||||||
|
}());
|
||||||
|
</script>
|
||||||
|
<body>
|
||||||
|
<span style='font-size:40px'><span style='color:#777777'>Web</span>-<span style='color:#FF0000'>Clipboard</span></span><span style='font-size:14px'> by <a href='mailto:joe@netsquat.com'>joe@netsquat.com</a></span>
|
||||||
|
<span id='pnlConnectionState'>
|
||||||
|
Connection
|
||||||
|
<hr/>
|
||||||
|
<div id='icoStateConnected' class='circle' style='background:#00FF00;display:none'></div>
|
||||||
|
<div id='icoStateDisconnected' class='circle' style='background:#FF0000;display:none'></div>
|
||||||
|
</span>
|
||||||
|
<hr />
|
||||||
|
<input id='tbId' onchange='webclip.enableDisableButtons();' onkeyup='webclip.enableDisableButtons();' placeholder="Clipboard-name" style='border:1px solid'/>
|
||||||
|
<span id='lbNew' style='display:none'>[NEW]</span>
|
||||||
|
<button id='btnLoad' onclick='window.location.replace($("#tbId").val());'>Load</button>
|
||||||
|
<button id='btnSave' onclick='webclip.saveData($("#tbId").val());'>Save<span style='display:none' id='flgIsDirty'>*</span></button>
|
||||||
|
<button style='font-weight:bold;color:#FF0000' onClick='$(".moreToggle").toggle();'><span class='moreToggle' id='darr'>↓</span><span class='moreToggle' style='display:none' id='uarr'>↑</span></button>
|
||||||
|
<br/>
|
||||||
|
<div id='pnlDetails' class='moreToggle' style='display:none'>
|
||||||
|
<span class='label'>Edit-URL</span> <input id='tbURLEdit' class='url' style='background-color:#CCCCCC' readonly='readonly'/><br/>
|
||||||
|
<span class='label'>Raw-URL</span> <input id='tbURLRaw' class='url' style='background-color:#CCCCCC' readonly='readonly'/>
|
||||||
|
</div>
|
||||||
|
<hr />
|
||||||
|
<textarea style='width:100%;font-family:courier,monospace' onkeyup='webclip.manageDirtyFlag();' onblur='webclip.manageDirtyFlag();' rows="20" id='taValue'>
|
||||||
|
</textarea>
|
||||||
|
<hr/>
|
||||||
|
$Revision: 15 $ -- $Date: 2016-02-07 12:09:18 -0600 (Sun, 07 Feb 2016) $
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
37
install.txt
Normal file
37
install.txt
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
put files into webserver-directory.
|
||||||
|
|
||||||
|
install nodejs package
|
||||||
|
install nodejs-legacy package
|
||||||
|
install npm package
|
||||||
|
[sudo] npm -g install forever
|
||||||
|
|
||||||
|
npm install autosize
|
||||||
|
ln -s node_modules/autosize/dist/autosize.min.js
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
copy files to some directory (/var/local/nodejs/wc/) and make sure permissions are good
|
||||||
|
in the directory get the Q-library for promises:
|
||||||
|
cd /var/loca/nodejs/wc && npm install q
|
||||||
|
|
||||||
|
configure a process to keep running node.js with the server.js:
|
||||||
|
---------------------------------------------------------------
|
||||||
|
[edit] /etc/rd.local:
|
||||||
|
su - <user> -c "cd /var/local/nodejs/wc; /usr/local/bin/forever start server.js"
|
||||||
|
|
||||||
|
|
||||||
|
Configure Lighttpd:
|
||||||
|
-------------------
|
||||||
|
cd /etc/lighttps/conf-enabled
|
||||||
|
ln -s ../conf-available/10-proxy.conf
|
||||||
|
|
||||||
|
add to 10-proxy.conf:
|
||||||
|
|
||||||
|
$HTTP["url"] =~ "^/wc/.*$" {
|
||||||
|
proxy.server = ( "" =>
|
||||||
|
(( "host" => "127.0.0.1", "port" => 8000 ))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
re-start lighttpd
|
||||||
19
package.json
Normal file
19
package.json
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"name": "webclip",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "Web-Clipboard",
|
||||||
|
"main": "EventSource.js",
|
||||||
|
"directories": {
|
||||||
|
"doc": "docs"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1",
|
||||||
|
"start": "node server.js"
|
||||||
|
},
|
||||||
|
"author": "j.tretter@gmail.com",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"q": "^1.4.1",
|
||||||
|
"querystring": "^0.2.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
180
server.js
Normal file
180
server.js
Normal file
@@ -0,0 +1,180 @@
|
|||||||
|
// $Revision: 16 $ -- $Date: 2016-02-08 15:14:12 -0600 (Mon, 08 Feb 2016) $
|
||||||
|
|
||||||
|
var http = require('http');
|
||||||
|
var sys = require('sys');
|
||||||
|
var fs = require('fs');
|
||||||
|
var moniFilename = 'abc';
|
||||||
|
var querystring = require('querystring');
|
||||||
|
var q = require('q');
|
||||||
|
|
||||||
|
var deferredAllDone;
|
||||||
|
|
||||||
|
http.createServer(function(req, res) {
|
||||||
|
//debugHeaders(req);
|
||||||
|
|
||||||
|
deferredAllDone = q.defer();
|
||||||
|
deferredAllDone.promise.done(function(pos) {
|
||||||
|
res.end();
|
||||||
|
console.log("Response END. [" + pos + "]");
|
||||||
|
});
|
||||||
|
|
||||||
|
if (req.headers.accept && req.headers.accept === 'text/event-stream') {
|
||||||
|
var arrMatches;
|
||||||
|
arrMatches = req.url.match(new RegExp(/\/events\/(.*)$/));
|
||||||
|
if (arrMatches) {
|
||||||
|
moniFilename = arrMatches[1];
|
||||||
|
console.log("Monitoring:" + moniFilename);
|
||||||
|
sendSSE(req, res);
|
||||||
|
} else {
|
||||||
|
res.writeHead(404);
|
||||||
|
deferredAllDone.resolve("404");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.log("RCV-HTML");
|
||||||
|
res.writeHead(200, { 'Content-Type': 'text/html', 'Cache-Control': 'no-cache' });
|
||||||
|
arrMatches = req.url.match(new RegExp(/\/(save|raw)\/(.*)$/));
|
||||||
|
console.log("Matches", arrMatches);
|
||||||
|
if ((arrMatches) && (arrMatches.length === 3)) {
|
||||||
|
var func = arrMatches[1];
|
||||||
|
moniFilename = arrMatches[2];
|
||||||
|
if ("save" === func) {
|
||||||
|
console.log("SAVE-Data");
|
||||||
|
//sys.puts(sys.inspect(req));
|
||||||
|
var fullBody = '';
|
||||||
|
|
||||||
|
req.on('data', function(chunk) {
|
||||||
|
// append the current chunk of data to the fullBody variable
|
||||||
|
fullBody += chunk.toString();
|
||||||
|
});
|
||||||
|
|
||||||
|
//req.on('end', (function(res) {
|
||||||
|
req.on('end', function() {
|
||||||
|
var decodedBody = querystring.parse(fullBody);
|
||||||
|
//sys.puts(sys.inspect(decodedBody));
|
||||||
|
|
||||||
|
fs.writeFile(__dirname + "/docs/" + moniFilename, decodedBody.data, function(err) {
|
||||||
|
if (err) {
|
||||||
|
res.write('ERROR : "' + err + '"');
|
||||||
|
deferredAllDone.resolve("OnEndERR");
|
||||||
|
console.log(err);
|
||||||
|
} else {
|
||||||
|
fs.stat(__dirname + "/docs/" + moniFilename, function(err, stats) {
|
||||||
|
if (stats) {
|
||||||
|
console.log('deb' + stats.mtime);
|
||||||
|
res.write(constructJSON("Saved", stats.mtime));
|
||||||
|
}
|
||||||
|
deferredAllDone.resolve("OnEndSaved");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
//}(res)));
|
||||||
|
} else if ("raw" === func) {
|
||||||
|
console.log("RAW");
|
||||||
|
try {
|
||||||
|
res.write(fs.readFileSync(__dirname + '/docs/' + moniFilename));
|
||||||
|
} catch (e) {
|
||||||
|
res.writeHead(404, { 'Content-Type': 'text/html' });
|
||||||
|
console.log("RAW - FAILED");
|
||||||
|
}
|
||||||
|
deferredAllDone.resolve("OnRaw");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var reqFile=req.url.replace("/wc/","");
|
||||||
|
|
||||||
|
console.log("Orig Requested File " + reqFile );
|
||||||
|
if ((reqFile!=='EventSource.js') && (reqFile!=='autosize.min.js') ) {
|
||||||
|
reqFile='display.html'
|
||||||
|
}
|
||||||
|
console.log("Requested File " + reqFile );
|
||||||
|
var contentType="text/html";
|
||||||
|
if (reqFile.match(/\.css/gi)) {
|
||||||
|
contentType="text/css";
|
||||||
|
}
|
||||||
|
if (reqFile.match(/\.js/gi)) {
|
||||||
|
contentType="application/javascript";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var filePath = __dirname + '/' + reqFile;
|
||||||
|
console.log("Full path " + filePath + " [" + contentType + "]" );
|
||||||
|
|
||||||
|
try {
|
||||||
|
var stat = fs.statSync(filePath);
|
||||||
|
|
||||||
|
var readStream = fs.createReadStream(filePath);
|
||||||
|
res.writeHead(200, {"Content-Type":contentType});
|
||||||
|
|
||||||
|
readStream.pipe(res); // this will do a res.end() by its own.
|
||||||
|
|
||||||
|
} catch (ex) {
|
||||||
|
res.writeHead(404,{"Content-Type":"text/html"});
|
||||||
|
res.write("Not found: " + reqFile );
|
||||||
|
deferredAllDone.resolve("OnDisplay");
|
||||||
|
console.log ("Not found: " + reqFile, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).listen(8001,'127.0.0.1');
|
||||||
|
|
||||||
|
// Send the server side event - consider that this response never ends, so no res.end() is called whatsowever!
|
||||||
|
function sendSSE(req, res) {
|
||||||
|
var theClient=req.socket.remoteAddress + ":" + req.socket.remotePort;
|
||||||
|
res.writeHead(200, {
|
||||||
|
'Content-Type': 'text/event-stream',
|
||||||
|
'Cache-Control': 'no-cache',
|
||||||
|
'Connection': 'keep-alive'
|
||||||
|
});
|
||||||
|
|
||||||
|
var id = (new Date()).toLocaleTimeString();
|
||||||
|
|
||||||
|
fs.stat(__dirname + "/docs/" + moniFilename, function(err, stats) {
|
||||||
|
if (stats) {
|
||||||
|
console.log('deb' + stats.mtime);
|
||||||
|
res.write(constructSSE("Modified", stats.mtime));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Watching directory for changes
|
||||||
|
fs.watch(__dirname + '/docs/', function(event, filename) {
|
||||||
|
console.log('event is: ' + event);
|
||||||
|
if (filename) {
|
||||||
|
console.log('filename provided: ' + filename);
|
||||||
|
console.log("Monitoring:" + moniFilename);
|
||||||
|
|
||||||
|
if (moniFilename === filename) {
|
||||||
|
fs.stat(__dirname + "/docs/" + filename, function(err, stats) {
|
||||||
|
console.log('deb 2 ' +theClient + " - " + stats.mtime);
|
||||||
|
res.write(constructSSE("Modified", stats.mtime));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.log('filename not provided');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// the SSE requires a "data" element
|
||||||
|
function constructSSE(type, timeStamp) {
|
||||||
|
var retVal = "data: " + constructJSON(type, timeStamp) + "\n\n";
|
||||||
|
console.log('MESSAGE-DEBUG-L: ' + type + " _ " + timeStamp);
|
||||||
|
return (retVal);
|
||||||
|
}
|
||||||
|
|
||||||
|
// just the JSON of the data
|
||||||
|
function constructJSON(type, timeStamp) {
|
||||||
|
var retVal = '{"type": "' + type + '",';
|
||||||
|
retVal += ('"timeStamp": "' + timeStamp + '"}');
|
||||||
|
return (retVal);
|
||||||
|
}
|
||||||
|
|
||||||
|
function debugHeaders(req) {
|
||||||
|
sys.puts('URL: ' + req.url);
|
||||||
|
for (var key in req.headers) {
|
||||||
|
sys.puts(key + ': ' + req.headers[key]);
|
||||||
|
}
|
||||||
|
sys.puts('\n\n');
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user