diff --git a/app.js b/app.js index 783a4b04e008334e225bdadbf57018f051e3d444..1b16fd42300f0e14d4239341c87f3dc53d11bdd1 100644 --- a/app.js +++ b/app.js @@ -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 diff --git a/bin/www b/bin/www deleted file mode 100644 index 8a267d266f2812c7d8c92a2c494d855811714dae..0000000000000000000000000000000000000000 --- a/bin/www +++ /dev/null @@ -1,12 +0,0 @@ -#!/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')); -}); diff --git a/package.json b/package.json index 7962b6e68cc6ec7040888b4c2e545015df827db1..392186c49b52d0b014acd3dc7778b3a6034e9fc2 100644 --- a/package.json +++ b/package.json @@ -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" } } diff --git a/public/javascripts/wipho.js b/public/javascripts/wipho.js index c102f31e28d748fda0a5bbc8d46abfcd600759d8..7f58ef4af63af57a6e26e3408025f57cf0bc9bc2 100644 --- a/public/javascripts/wipho.js +++ b/public/javascripts/wipho.js @@ -1,13 +1,11 @@ + +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 +} diff --git a/routes/index.js b/routes/index.js index 823aaa54cb4ddd9c5cff3aeda096271f75c44727..78527924cde621ce2967ee7fc6fc650f0c31414b 100644 --- a/routes/index.js +++ b/routes/index.js @@ -1,9 +1,13 @@ +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; diff --git a/views/layout.jade b/views/layout.jade index 5c80b5896751dfbef618219b74034eb5b40c358a..60091bbd3bc1ef02191022eeba03e655d434c2cf 100644 --- a/views/layout.jade +++ b/views/layout.jade @@ -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