Commit bd6c0519 authored by Jan Grewe's avatar Jan Grewe

use WebSockets to tell frontend about new photos

parent 5be8e0de
Pipeline #4 passed with stage
......@@ -21,22 +21,21 @@ var net = require('net');
var dgram = require('dgram');
var fs = require('fs');
var gm = require('gm');
/* Express */
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var express = require('express');
var app = express();
var server = http.createServer(app);
var io = require('socket.io')(server);
var routes = require('./routes/index');
var latestPhoto = require('./routes/latest');
var allPhotos = require('./routes/all');
var app = express();
process.title = 'WiPho';
var gracefulShutdown = function() {
console.log("Shutting down...");
......@@ -44,7 +43,9 @@ var gracefulShutdown = function() {
}
process.on ('SIGTERM', gracefulShutdown);
process.on ('SIGINT', gracefulShutdown);
process.on ('SIGINT', gracefulShutdown);
app.set('port', config.httpPort || 3000);
// view engine setup
app.set('views', path.join(__dirname, 'views'));
......@@ -95,6 +96,25 @@ app.use(function(err, req, res, next) {
module.exports = app;
io.on('connection', function (socket) {
//console.log('Display connected!');
socket.on('disconnect', function(){
//console.log('Display disconnected');
});
socket.on('display', function(data) {
if(data.status == 'success') {
console.log('Photo displayed!');
} else {
console.log('Photo not displayed!');
}
});
});
server.listen(app.get('port'), function() {
console.log("WiPho is listening on port " + app.get('port'));
});
/* WiPho */
photos = new Array();
......@@ -108,227 +128,228 @@ findCard();
function downloadPhotos() {
if(alreadyDownloading == true || downloadList.length < 1)
return true;
alreadyDownloading = true;
var photo = downloadList.pop();
var localFile = pathPhotos+'/'+photo;
var localPreview = pathPreviews+'/'+photo;
console.log('['+photo+'] Downloading from http://'+cardAddr+cardPath+'/'+photo);
var file = fs.createWriteStream(localFile);
file.on('error', function(err) {
console.log("FS: "+err);
});
file.on('finish', function() {
file.close();
alreadyDownloading = false;
console.log('['+photo+'] Saved as '+localFile);
gm(localFile).autoOrient().resize(previewWidth, previewHeight).write(localPreview, function (err) {
if (!err) {
console.log('['+photo+'] Resized to '+previewWidth+'x'+previewHeight);
if(photos.length == 0 || photo != photos[photos.length-1].name) {
photos.push({id: photoIndex, name: photo});
photoIndex++;
}
}else{
console.log('Photo resize error: '+err);
}
});
if(downloadPrevious == true) {
getPhotoList();
}
if(downloadList.length > 0) {
downloadPhotos();
}else{
console.log("All photos downloaded, waiting for new ones...");
}
});
var options = {
hostname: cardAddr,
port: 80,
path: cardPath+'/'+photo,
method: 'GET'
};
var request = http.get(options, function(response) {
response.pipe(file);
});
request.on('error', function(e) {
console.log("HTTP Error: " + e.message);
});
if(alreadyDownloading == true || downloadList.length < 1)
return true;
alreadyDownloading = true;
var photo = downloadList.pop();
var localFile = pathPhotos+'/'+photo;
var localPreview = pathPreviews+'/'+photo;
console.log('['+photo+'] Downloading from http://'+cardAddr+cardPath+'/'+photo);
var file = fs.createWriteStream(localFile);
file.on('error', function(err) {
console.log("FS: "+err);
});
file.on('finish', function() {
file.close();
alreadyDownloading = false;
console.log('['+photo+'] Saved as '+localFile);
gm(localFile).autoOrient().resize(previewWidth, previewHeight).write(localPreview, function (err) {
if (!err) {
console.log('['+photo+'] Resized to '+previewWidth+'x'+previewHeight);
if(photos.length == 0 || photo != photos[photos.length-1].name) {
photos.push({id: photoIndex, name: photo});
photoIndex++;
io.emit('photo', { path: photo });
}
}else{
console.log('Photo resize error: '+err);
}
});
if(downloadPrevious == true) {
getPhotoList();
}
if(downloadList.length > 0) {
downloadPhotos();
}else{
console.log("All photos downloaded, waiting for new ones...");
}
});
var options = {
hostname: cardAddr,
port: 80,
path: cardPath+'/'+photo,
method: 'GET'
};
var request = http.get(options, function(response) {
response.pipe(file);
});
request.on('error', function(e) {
console.log("HTTP Error: " + e.message);
});
}
function getPhotoList() {
downloadPrevious = false;
var options = {
host: cardAddr,
port: 80,
path: '/cgi-bin/tslist?PATH=/www'+cardPath+'&keepfresh='+Date.now().toString()
};
http.get(options, function(resp){
console.log("Getting list of photos on card...");
resp.on('data', function(data){
var strFiles = data.toString().split(os.EOL)[2];
var regex = /FileName\d+=([a-zA-Z0-9_\.]+)&FileType\d+=File&/g;
var arrPhotos = new Array();
while (match = regex.exec(strFiles)) {
arrPhotos.push(match[1]);
}
var i = 0;
arrPhotos.forEach(function(photo) {
fs.exists(pathPhotos+'/'+photo, function(exists) {
if (exists) {
//console.log('['+photo+'] Photo '+photo+' already downloaded!');
}else{
console.log('['+photo+'] Photo '+photo+' not downloaded yet, adding to download list!');
downloadList.push(photo);
}
i++;
if(i == arrPhotos.length-1) {
if(downloadList.length > 0) {
downloadPhotos();
}else{
console.log("All photos already downloaded!");
}
}
});
});
});
}).on("error", function(e){
console.log("Error getting photo list: " + e.message);
getPhotoList();
});
downloadPrevious = false;
var options = {
host: cardAddr,
port: 80,
path: '/cgi-bin/tslist?PATH=/www'+cardPath+'&keepfresh='+Date.now().toString()
};
http.get(options, function(resp){
console.log("Getting list of photos on card...");
resp.on('data', function(data){
var strFiles = data.toString().split(os.EOL)[2];
var regex = /FileName\d+=([a-zA-Z0-9_\.]+)&FileType\d+=File&/g;
var arrPhotos = new Array();
while (match = regex.exec(strFiles)) {
arrPhotos.push(match[1]);
}
var i = 0;
arrPhotos.forEach(function(photo) {
fs.exists(pathPhotos+'/'+photo, function(exists) {
if (exists) {
//console.log('['+photo+'] Photo '+photo+' already downloaded!');
}else{
console.log('['+photo+'] Photo '+photo+' not downloaded yet, adding to download list!');
downloadList.push(photo);
}
i++;
if(i == arrPhotos.length-1) {
if(downloadList.length > 0) {
downloadPhotos();
}else{
console.log("All photos already downloaded!");
}
}
});
});
});
}).on("error", function(e){
console.log("Error getting photo list: " + e.message);
getPhotoList();
});
}
function enableShootAndView(ip) {
var client = net.connect({port: 5566, host: ip}, function() {
console.log('Enabling Shoot & View...');
});
client.on('connect', function() {
console.log('Shoot & View enabled, waiting for photos...');
if(cardPath != null) {
getPhotoList();
}
});
client.on('error', function(err) {
console.log('Shoot & View error: '+err);
findCard();
});
client.on('data', function(data) {
var path = data.toString().substr(5).replace(/\0/g, '');
var photo = path.split('/').pop();
cardPath = path.substring(0, path.lastIndexOf('/'));
downloadList.push(photo);
downloadPhotos();
});
client.on('end', function() {
console.log('Shoot & View stopped!');
});
var client = net.connect({port: 5566, host: ip}, function() {
console.log('Enabling Shoot & View...');
});
client.on('connect', function() {
console.log('Shoot & View enabled, waiting for photos...');
if(cardPath != null) {
getPhotoList();
}
});
client.on('error', function(err) {
console.log('Shoot & View error: '+err);
findCard();
});
client.on('data', function(data) {
var path = data.toString().substr(5).replace(/\0/g, '');
var photo = path.split('/').pop();
cardPath = path.substring(0, path.lastIndexOf('/'));
downloadList.push(photo);
downloadPhotos();
});
client.on('end', function() {
console.log('Shoot & View stopped!');
});
}
function pingCard(ip) {
req = http.get('http://'+ip+'/', function(res) {
//console.log('Card is alive!');
req.destroy();
});
req.on('error', function(err) {
cardFound = false;
console.log('ERROR: ' + err);
req.destroy();
clearInterval(itvPing);
findCard();
});
req.setTimeout(5000, function() {
cardFound = false;
downloadPrevious = true;
console.log('Card has disappeared!');
req.destroy();
clearInterval(itvPing);
findCard();
});
req = http.get('http://'+ip+'/', function(res) {
//console.log('Card is alive!');
req.destroy();
});
req.on('error', function(err) {
cardFound = false;
console.log('ERROR: ' + err);
req.destroy();
clearInterval(itvPing);
findCard();
});
req.setTimeout(5000, function() {
cardFound = false;
downloadPrevious = true;
console.log('Card has disappeared!');
req.destroy();
clearInterval(itvPing);
findCard();
});
}
function findCard() {
if(alreadySearching == true)
return;
else
alreadySearching = true;
console.log("Searching for card...");
var socket = dgram.createSocket('udp4');
var message = new Buffer('dummy');
var itvSearch;
socket.bind(58255, function() {
socket.setBroadcast(true);
});
socket.on('error', function (err) {
console.log("socket error:\n" + err.stack);
socket.close();
findCard();
});
socket.on('message', function (msg, rinfo) {
clearInterval(itvSearch);
socket.close();
msg = msg.toString();
cardAddr = msg.match(/ip=(.*)/)[1];
cardFound = true;
console.log("Found card on "+cardAddr);
enableShootAndView(cardAddr);
itvPing = setInterval(function() {
pingCard(cardAddr);
}, 5000);
alreadySearching = false;
});
socket.on('listening', function () {
var address = socket.address();
sendSearch();
itvSearch = setInterval(function() {
sendSearch();
}, 2000);
function sendSearch() {
socket.send(message, 0, message.length, 55777, cardAddr, function(err, bytes) {
if(err != null)
console.log("socket error:\n" + err.stack);
});
}
});
if(alreadySearching == true)
return;
else
alreadySearching = true;
console.log("Searching for card...");
var socket = dgram.createSocket('udp4');
var message = new Buffer('dummy');
var itvSearch;
socket.bind(58255, function() {
socket.setBroadcast(true);
});
socket.on('error', function (err) {
console.log("socket error:\n" + err.stack);
socket.close();
findCard();
});
socket.on('message', function (msg, rinfo) {
clearInterval(itvSearch);
socket.close();
msg = msg.toString();
cardAddr = msg.match(/ip=(.*)/)[1];
cardFound = true;
console.log("Found card on "+cardAddr);
enableShootAndView(cardAddr);
itvPing = setInterval(function() {
pingCard(cardAddr);
}, 5000);
alreadySearching = false;
});
socket.on('listening', function () {
var address = socket.address();
sendSearch();
itvSearch = setInterval(function() {
sendSearch();
}, 2000);
function sendSearch() {
socket.send(message, 0, message.length, 55777, cardAddr, function(err, bytes) {
if(err != null)
console.log("socket error:\n" + err.stack);
});
}
});
}
\ No newline at end of file
#!/usr/bin/env node
var config = require('../config.json');
var debug = require('debug')('foo');
var app = require('../app');
app.set('port', config.httpPort || 3000);
var server = app.listen(app.get('port'), function() {
console.log("Express server listening on port " + app.get('port'));
});
......@@ -3,17 +3,18 @@
"version": "0.0.1",
"private": true,
"scripts": {
"start": "node ./bin/www",
"start": "node app.js",
"stop": "pkill --signal SIGINT WiPho"
},
"dependencies": {
"express": "~4.9.0",
"body-parser": "~1.8.1",
"body-parser": "^1.12.0",
"cookie-parser": "~1.3.3",
"morgan": "~1.3.0",
"serve-favicon": "~2.1.3",
"debug": "~2.0.0",
"jade": "~1.6.0",
"gm": "~1.16.0"
"debug": "^0.7.0",
"express": "~4.12.2",
"gm": "^1.17.0",
"jade": "^1.9.2",
"morgan": "^1.5.1",
"serve-favicon": "^2.2.0",
"socket.io": "^1.3.5"
}
}
var socket = io.connect();
$(document).ready(function() {
$('body').height($(window).height());
centerImage();
getLatest();
setInterval(function() {
getLatest();
}, 1000);
$(window).resize(function () {
centerImage();
});
......@@ -22,18 +20,15 @@ $(document).ready(function() {
centerImage();
$(this).animate({opacity: 1}, 400);
});
});
function getLatest() {
$.getJSON('/latest', function(data) {
if('/previews/'+data.name != $('#latest').attr('src')) {
$('#latest').animate({opacity: 0}, 400, function() {
$(this).attr('src', '/previews/'+data.name);
});
}
socket.on('photo', function (data) {
$('#latest').animate({opacity: 0}, 400, function() {
$(this).attr('src', '/previews/'+data.path);
socket.emit('display', {status: 'success'});
});
});
}
});
function centerImage() {
$('#latest').css({
......@@ -41,4 +36,4 @@ function centerImage() {
left: ($(window).width() - $('#latest').outerWidth()) / 2,
top: ($(window).height() - $('#latest').outerHeight()) / 2,
});
}
\ No newline at end of file
}
var config = require('../config.json');
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res) {
res.render('index', { title: 'WiPho' });
res.render('index', {
title: 'WiPho'
});
});
module.exports = router;
......@@ -2,8 +2,9 @@ doctype html
html
head
title= title
script(src='/socket.io/socket.io.js')
script(src='/javascripts/jquery-1.11.1.min.js')
script(src='/javascripts/wipho.js')
link(rel='stylesheet', href='/stylesheets/wipho.css')
body
block content
\ No newline at end of file
block content