Move everything into the root directory
The separate vote-apps directory was because networking didn't used to support aliases to remove the project name. Signed-off-by: Ben Firshman <ben@firshman.co.uk>
This commit is contained in:
15
result-app/Dockerfile
Normal file
15
result-app/Dockerfile
Normal file
@ -0,0 +1,15 @@
|
||||
FROM node:0.10
|
||||
|
||||
RUN mkdir /app
|
||||
WORKDIR /app
|
||||
|
||||
ADD package.json /app/package.json
|
||||
RUN npm install && npm ls
|
||||
RUN mv /app/node_modules /node_modules
|
||||
|
||||
ADD . /app
|
||||
|
||||
ENV PORT 80
|
||||
EXPOSE 80
|
||||
|
||||
CMD ["node", "server.js"]
|
20
result-app/package.json
Normal file
20
result-app/package.json
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"name": "result-app",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "server.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"body-parser": "^1.14.1",
|
||||
"cookie-parser": "^1.4.0",
|
||||
"express": "^4.13.3",
|
||||
"method-override": "^2.3.5",
|
||||
"async": "^1.5.0",
|
||||
"pg": "^4.4.3",
|
||||
"socket.io": "^1.3.7"
|
||||
}
|
||||
}
|
78
result-app/server.js
Normal file
78
result-app/server.js
Normal file
@ -0,0 +1,78 @@
|
||||
var express = require('express'),
|
||||
async = require('async'),
|
||||
pg = require("pg"),
|
||||
cookieParser = require('cookie-parser'),
|
||||
bodyParser = require('body-parser'),
|
||||
methodOverride = require('method-override'),
|
||||
app = express(),
|
||||
server = require('http').Server(app),
|
||||
io = require('socket.io')(server);
|
||||
|
||||
io.set('transports', ['polling']);
|
||||
|
||||
var port = process.env.PORT || 4000;
|
||||
|
||||
io.sockets.on('connection', function (socket) {
|
||||
|
||||
socket.emit('message', { text : 'Welcome!' });
|
||||
|
||||
socket.on('subscribe', function (data) {
|
||||
socket.join(data.channel);
|
||||
});
|
||||
});
|
||||
|
||||
async.retry(
|
||||
{times: 1000, interval: 1000},
|
||||
function(callback) {
|
||||
pg.connect('postgres://postgres@db/postgres', function(err, client, done) {
|
||||
if (err) {
|
||||
console.error("Failed to connect to db");
|
||||
}
|
||||
callback(err, client);
|
||||
});
|
||||
},
|
||||
function(err, client) {
|
||||
if (err) {
|
||||
return console.err("Giving up");
|
||||
}
|
||||
console.log("Connected to db");
|
||||
getVotes(client);
|
||||
}
|
||||
);
|
||||
|
||||
function getVotes(client) {
|
||||
client.query('SELECT vote, COUNT(id) AS count FROM votes GROUP BY vote', [], function(err, result) {
|
||||
if (err) {
|
||||
console.error("Error performing query: " + err);
|
||||
} else {
|
||||
var data = result.rows.reduce(function(obj, row) {
|
||||
obj[row.vote] = row.count;
|
||||
return obj;
|
||||
}, {});
|
||||
io.sockets.emit("scores", JSON.stringify(data));
|
||||
}
|
||||
|
||||
setTimeout(function() {getVotes(client) }, 1000);
|
||||
});
|
||||
}
|
||||
|
||||
app.use(cookieParser());
|
||||
app.use(bodyParser());
|
||||
app.use(methodOverride('X-HTTP-Method-Override'));
|
||||
app.use(function(req, res, next) {
|
||||
res.header("Access-Control-Allow-Origin", "*");
|
||||
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
|
||||
res.header("Access-Control-Allow-Methods", "PUT, GET, POST, DELETE, OPTIONS");
|
||||
next();
|
||||
});
|
||||
|
||||
app.use(express.static(__dirname + '/views'));
|
||||
|
||||
app.get('/', function (req, res) {
|
||||
res.sendFile(path.resolve(__dirname + '/views/index.html'));
|
||||
});
|
||||
|
||||
server.listen(port, function () {
|
||||
var port = server.address().port;
|
||||
console.log('App running on port ' + port);
|
||||
});
|
45
result-app/views/app.js
Normal file
45
result-app/views/app.js
Normal file
@ -0,0 +1,45 @@
|
||||
var app = angular.module('catsvsdogs', []);
|
||||
var socket = io.connect({transports:['polling']});
|
||||
|
||||
var bg1 = document.getElementById('background-stats-1');
|
||||
var bg2 = document.getElementById('background-stats-2');
|
||||
|
||||
app.controller('statsCtrl', function($scope){
|
||||
var animateStats = function(a,b){
|
||||
if(a+b>0){
|
||||
var percentA = a/(a+b)*100;
|
||||
var percentB = 100-percentA;
|
||||
bg1.style.width= percentA+"%";
|
||||
bg2.style.width = percentB+"%";
|
||||
}
|
||||
};
|
||||
|
||||
$scope.aPercent = 50;
|
||||
$scope.bPercent = 50;
|
||||
|
||||
var updateScores = function(){
|
||||
socket.on('scores', function (json) {
|
||||
data = JSON.parse(json);
|
||||
var a = parseInt(data.a || 0);
|
||||
var b = parseInt(data.b || 0);
|
||||
|
||||
animateStats(a, b);
|
||||
|
||||
$scope.$apply(function() {
|
||||
if(a + b > 0){
|
||||
$scope.aPercent = a/(a+b) * 100;
|
||||
$scope.bPercent = b/(a+b) * 100;
|
||||
$scope.total = a + b
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
var init = function(){
|
||||
document.body.style.opacity=1;
|
||||
updateScores();
|
||||
};
|
||||
socket.on('message',function(data){
|
||||
init();
|
||||
});
|
||||
});
|
41
result-app/views/index.html
Normal file
41
result-app/views/index.html
Normal file
@ -0,0 +1,41 @@
|
||||
<!DOCTYPE html>
|
||||
<html ng-app="catsvsdogs">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Cats vs Dogs -- Result</title>
|
||||
<base href="/index.html">
|
||||
<meta name = "viewport" content = "width=device-width, initial-scale = 1.0">
|
||||
<meta name="keywords" content="docker-compose, docker, stack">
|
||||
<meta name="author" content="Tutum dev team">
|
||||
<link rel='stylesheet' href='/stylesheets/style.css' />
|
||||
</head>
|
||||
<body ng-controller="statsCtrl" >
|
||||
<div id="background-stats">
|
||||
<div id="background-stats-1">
|
||||
</div><!--
|
||||
--><div id="background-stats-2">
|
||||
</div>
|
||||
</div>
|
||||
<div id="content-container">
|
||||
<div id="content-container-center">
|
||||
<div id="choice">
|
||||
<div class="choice cats">
|
||||
<div class="label">Cats</div>
|
||||
<div class="stat">{{aPercent | number:1}}%</div>
|
||||
</div>
|
||||
<div class="divider"></div>
|
||||
<div class="choice dogs">
|
||||
<div class="label">Dogs</div>
|
||||
<div class="stat">{{bPercent | number:1}}%</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="result" ng-if="total > 100">
|
||||
{{total}} votes
|
||||
</div>
|
||||
<script src="socket.io.js"></script>
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js"></script>
|
||||
<script src="app.js"></script>
|
||||
</body>
|
||||
</html>
|
6988
result-app/views/socket.io.js
Normal file
6988
result-app/views/socket.io.js
Normal file
File diff suppressed because it is too large
Load Diff
111
result-app/views/stylesheets/style.css
Normal file
111
result-app/views/stylesheets/style.css
Normal file
@ -0,0 +1,111 @@
|
||||
@import url(//fonts.googleapis.com/css?family=Open+Sans:400,700,600);
|
||||
|
||||
*{
|
||||
box-sizing:border-box;
|
||||
}
|
||||
html,body{
|
||||
margin:0;
|
||||
padding:0;
|
||||
height:100%;
|
||||
font-family: 'Open Sans';
|
||||
}
|
||||
body{
|
||||
opacity:0;
|
||||
transition: all 1s linear;
|
||||
}
|
||||
|
||||
.divider{
|
||||
height: 150px;
|
||||
width:2px;
|
||||
background-color: #C0C9CE;
|
||||
position: relative;
|
||||
top: 50%;
|
||||
float: left;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
#background-stats-1{
|
||||
background-color: #2196f3;
|
||||
}
|
||||
|
||||
#background-stats-2{
|
||||
background-color: #00cbca;
|
||||
}
|
||||
|
||||
#content-container{
|
||||
z-index:2;
|
||||
position:relative;
|
||||
margin:0 auto;
|
||||
display:table;
|
||||
padding:10px;
|
||||
max-width:940px;
|
||||
height:100%;
|
||||
}
|
||||
#content-container-center{
|
||||
display:table-cell;
|
||||
text-align:center;
|
||||
vertical-align:middle;
|
||||
}
|
||||
#result{
|
||||
position: absolute;
|
||||
bottom: 40px;
|
||||
right: 20px;
|
||||
color: #fff;
|
||||
opacity: 0.5;
|
||||
font-size: 45px;
|
||||
font-weight: 600;
|
||||
}
|
||||
#choice{
|
||||
transition: all 300ms linear;
|
||||
line-height:1.3em;
|
||||
background:#fff;
|
||||
box-shadow: 10px 0 0 #fff, -10px 0 0 #fff;
|
||||
vertical-align:middle;
|
||||
font-size:40px;
|
||||
font-weight: 600;
|
||||
width: 450px;
|
||||
height: 200px;
|
||||
}
|
||||
#choice a{
|
||||
text-decoration:none;
|
||||
}
|
||||
#choice a:hover, #choice a:focus{
|
||||
outline:0;
|
||||
text-decoration:underline;
|
||||
}
|
||||
|
||||
#choice .choice{
|
||||
width: 49%;
|
||||
position: relative;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
text-align: left;
|
||||
padding-left: 50px;
|
||||
}
|
||||
|
||||
#choice .choice .label{
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
#choice .choice.dogs{
|
||||
color: #00cbca;
|
||||
float: right;
|
||||
}
|
||||
|
||||
#choice .choice.cats{
|
||||
color: #2196f3;
|
||||
float: left;
|
||||
}
|
||||
#background-stats{
|
||||
z-index:1;
|
||||
height:100%;
|
||||
width:100%;
|
||||
position:absolute;
|
||||
}
|
||||
#background-stats div{
|
||||
transition: width 400ms ease-in-out;
|
||||
display:inline-block;
|
||||
margin-bottom:-4px;
|
||||
width:50%;
|
||||
height:100%;
|
||||
}
|
Reference in New Issue
Block a user