Merge branch 'master' of gitlab.com:rubenvandeven/sorteerhoed

This commit is contained in:
Ruben van de Ven 2019-11-01 18:53:53 +01:00
commit 34199c394c
14 changed files with 644 additions and 0 deletions

View file

@ -0,0 +1,125 @@
/*
* Date Format 1.2.3
* (c) 2007-2009 Steven Levithan <stevenlevithan.com>
* MIT license
*
* Includes enhancements by Scott Trenda <scott.trenda.net>
* and Kris Kowal <cixar.com/~kris.kowal/>
*
* Accepts a date, a mask, or a date and a mask.
* Returns a formatted version of the given date.
* The date defaults to the current date/time.
* The mask defaults to dateFormat.masks.default.
*/
var dateFormat = function () {
var token = /d{1,4}|m{1,4}|yy(?:yy)?|([HhMsTt])\1?|[LloSZ]|"[^"]*"|'[^']*'/g,
timezone = /\b(?:[PMCEA][SDP]T|(?:Pacific|Mountain|Central|Eastern|Atlantic) (?:Standard|Daylight|Prevailing) Time|(?:GMT|UTC)(?:[-+]\d{4})?)\b/g,
timezoneClip = /[^-+\dA-Z]/g,
pad = function (val, len) {
val = String(val);
len = len || 2;
while (val.length < len) val = "0" + val;
return val;
};
// Regexes and supporting functions are cached through closure
return function (date, mask, utc) {
var dF = dateFormat;
// You can't provide utc if you skip other args (use the "UTC:" mask prefix)
if (arguments.length == 1 && Object.prototype.toString.call(date) == "[object String]" && !/\d/.test(date)) {
mask = date;
date = undefined;
}
// Passing date through Date applies Date.parse, if necessary
date = date ? new Date(date) : new Date;
if (isNaN(date)) throw SyntaxError("invalid date");
mask = String(dF.masks[mask] || mask || dF.masks["default"]);
// Allow setting the utc argument via the mask
if (mask.slice(0, 4) == "UTC:") {
mask = mask.slice(4);
utc = true;
}
var _ = utc ? "getUTC" : "get",
d = date[_ + "Date"](),
D = date[_ + "Day"](),
m = date[_ + "Month"](),
y = date[_ + "FullYear"](),
H = date[_ + "Hours"](),
M = date[_ + "Minutes"](),
s = date[_ + "Seconds"](),
L = date[_ + "Milliseconds"](),
o = utc ? 0 : date.getTimezoneOffset(),
flags = {
d: d,
dd: pad(d),
ddd: dF.i18n.dayNames[D],
dddd: dF.i18n.dayNames[D + 7],
m: m + 1,
mm: pad(m + 1),
mmm: dF.i18n.monthNames[m],
mmmm: dF.i18n.monthNames[m + 12],
yy: String(y).slice(2),
yyyy: y,
h: H % 12 || 12,
hh: pad(H % 12 || 12),
H: H,
HH: pad(H),
M: M,
MM: pad(M),
s: s,
ss: pad(s),
l: pad(L, 3),
L: pad(L > 99 ? Math.round(L / 10) : L),
t: H < 12 ? "a" : "p",
tt: H < 12 ? "am" : "pm",
T: H < 12 ? "A" : "P",
TT: H < 12 ? "AM" : "PM",
Z: utc ? "UTC" : (String(date).match(timezone) || [""]).pop().replace(timezoneClip, ""),
o: (o > 0 ? "-" : "+") + pad(Math.floor(Math.abs(o) / 60) * 100 + Math.abs(o) % 60, 4),
S: ["th", "st", "nd", "rd"][d % 10 > 3 ? 0 : (d % 100 - d % 10 != 10) * d % 10]
};
return mask.replace(token, function ($0) {
return $0 in flags ? flags[$0] : $0.slice(1, $0.length - 1);
});
};
}();
// Some common format strings
dateFormat.masks = {
"default": "ddd mmm dd yyyy HH:MM:ss",
shortDate: "m/d/yy",
mediumDate: "mmm d, yyyy",
longDate: "mmmm d, yyyy",
fullDate: "dddd, mmmm d, yyyy",
shortTime: "h:MM TT",
mediumTime: "h:MM:ss TT",
longTime: "h:MM:ss TT Z",
isoDate: "yyyy-mm-dd",
isoTime: "HH:MM:ss",
isoDateTime: "yyyy-mm-dd'T'HH:MM:ss",
isoUtcDateTime: "UTC:yyyy-mm-dd'T'HH:MM:ss'Z'"
};
// Internationalization strings
dateFormat.i18n = {
dayNames: [
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat",
"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
],
monthNames: [
"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
]
};
// For convenience...
Date.prototype.format = function (mask, utc) {
return dateFormat(this, mask, utc);
};

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,55 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="stylesheet" type="text/css" href="style.css" />
<script src='dateformat.js'></script>
<script src='reconnecting-websocket.min.js'></script>
</head>
<body>
<div id="wrapper">
<!-- <div class="phase" id="waiting_for_human">
<span class="narrative_phase_text">waiting for human worker to accept task</span>
</div>
<div class="phase" id="human_accepted_task">
<span class="narrative_phase_text">task accepted by human worker</span>
</div> -->
<div class="phase" id="worker_specs">
<span class="grid-item spec_name" id="worker_id_descriptor">human worker id</span>
<span class="grid-item spec_value" id="worker_id">&nbsp;</span>
<span class="grid-item spec_name" id="ip_descriptor">ip address</span>
<span class="grid-item spec_value" id="ip">&nbsp;</span>
<span class="grid-item spec_name" id="location_descriptor">location</span>
<span class="grid-item spec_value" id="location">&nbsp;</span>
<span class="grid-item spec_name" id="browser_descriptor">browser</span>
<span class="grid-item spec_value" id="browser">&nbsp;</span>
<span class="grid-item spec_name" id="os_descriptor">os</span>
<span class="grid-item spec_value" id="os">&nbsp;</span>
<span class="grid-item spec_name" id="hit_opened_descriptor">task started at</span>
<span class="grid-item spec_value" id="hit_opened">&nbsp;</span>
<span class="grid-item spec_name" id="state_descriptor">task status</span>
<span class="grid-item spec_value" id="state">&nbsp;</span>
<span class="grid-item spec_name" id="fee_descriptor">task fee</span>
<span class="grid-item spec_value" id="fee">&nbsp;</span>
<span class="grid-item spec_name" id="elapsed_time_descriptor">time elapsed</span>
<span class="grid-item spec_value" id="elapsed_time">&nbsp;</span>
</div>
</div>
<script src="script.js"></script>
</body>
</html>

View file

@ -0,0 +1 @@
!function(a,b){"function"==typeof define&&define.amd?define([],b):"undefined"!=typeof module&&module.exports?module.exports=b():a.ReconnectingWebSocket=b()}(this,function(){function a(b,c,d){function l(a,b){var c=document.createEvent("CustomEvent");return c.initCustomEvent(a,!1,!1,b),c}var e={debug:!1,automaticOpen:!0,reconnectInterval:1e3,maxReconnectInterval:3e4,reconnectDecay:1.5,timeoutInterval:2e3};d||(d={});for(var f in e)this[f]="undefined"!=typeof d[f]?d[f]:e[f];this.url=b,this.reconnectAttempts=0,this.readyState=WebSocket.CONNECTING,this.protocol=null;var h,g=this,i=!1,j=!1,k=document.createElement("div");k.addEventListener("open",function(a){g.onopen(a)}),k.addEventListener("close",function(a){g.onclose(a)}),k.addEventListener("connecting",function(a){g.onconnecting(a)}),k.addEventListener("message",function(a){g.onmessage(a)}),k.addEventListener("error",function(a){g.onerror(a)}),this.addEventListener=k.addEventListener.bind(k),this.removeEventListener=k.removeEventListener.bind(k),this.dispatchEvent=k.dispatchEvent.bind(k),this.open=function(b){h=new WebSocket(g.url,c||[]),b||k.dispatchEvent(l("connecting")),(g.debug||a.debugAll)&&console.debug("ReconnectingWebSocket","attempt-connect",g.url);var d=h,e=setTimeout(function(){(g.debug||a.debugAll)&&console.debug("ReconnectingWebSocket","connection-timeout",g.url),j=!0,d.close(),j=!1},g.timeoutInterval);h.onopen=function(){clearTimeout(e),(g.debug||a.debugAll)&&console.debug("ReconnectingWebSocket","onopen",g.url),g.protocol=h.protocol,g.readyState=WebSocket.OPEN,g.reconnectAttempts=0;var d=l("open");d.isReconnect=b,b=!1,k.dispatchEvent(d)},h.onclose=function(c){if(clearTimeout(e),h=null,i)g.readyState=WebSocket.CLOSED,k.dispatchEvent(l("close"));else{g.readyState=WebSocket.CONNECTING;var d=l("connecting");d.code=c.code,d.reason=c.reason,d.wasClean=c.wasClean,k.dispatchEvent(d),b||j||((g.debug||a.debugAll)&&console.debug("ReconnectingWebSocket","onclose",g.url),k.dispatchEvent(l("close")));var e=g.reconnectInterval*Math.pow(g.reconnectDecay,g.reconnectAttempts);setTimeout(function(){g.reconnectAttempts++,g.open(!0)},e>g.maxReconnectInterval?g.maxReconnectInterval:e)}},h.onmessage=function(b){(g.debug||a.debugAll)&&console.debug("ReconnectingWebSocket","onmessage",g.url,b.data);var c=l("message");c.data=b.data,k.dispatchEvent(c)},h.onerror=function(b){(g.debug||a.debugAll)&&console.debug("ReconnectingWebSocket","onerror",g.url,b),k.dispatchEvent(l("error"))}},1==this.automaticOpen&&this.open(!1),this.send=function(b){if(h)return(g.debug||a.debugAll)&&console.debug("ReconnectingWebSocket","send",g.url,b),h.send(b);throw"INVALID_STATE_ERR : Pausing to reconnect websocket"},this.close=function(a,b){"undefined"==typeof a&&(a=1e3),i=!0,h&&h.close(a,b)},this.refresh=function(){h&&h.close()}}return a.prototype.onopen=function(){},a.prototype.onclose=function(){},a.prototype.onconnecting=function(){},a.prototype.onmessage=function(){},a.prototype.onerror=function(){},a.debugAll=!1,a.CONNECTING=WebSocket.CONNECTING,a.OPEN=WebSocket.OPEN,a.CLOSING=WebSocket.CLOSING,a.CLOSED=WebSocket.CLOSED,a});

114
www/worker_specs/script.js Normal file
View file

@ -0,0 +1,114 @@
// DOM STUFF ///////////////////////////////////////////////////////////////////
let divs = {},
spec_names = [
'worker_id',
'ip',
'location',
'browser',
'os',
'state',
'fee',
'hit_created',
'hit_opened',
'hit_submitted',
'elapsed_time'
]
divs.linkDOM = function(name){
divs[name] = document.getElementById(`${name}`)
}
spec_names.forEach(function(name){
divs.linkDOM(name)
})
let request_time = timeStamp(),
elapsed_time,
hit_finished = false
// SOCKET STUFF ////////////////////////////////////////////////////////////////
let ws = new ReconnectingWebSocket('ws://localhost:8888/status/ws')
let test = `{"property": "os", "value": "213.127.20.197"}`
// fakeWs(test)
//
// function fakeWs(json){
//
//
// }
ws.addEventListener('open', () => {
// ws.send('hi server')
})
ws.addEventListener('message', (event) => {
console.log('message: ' + event.data)
let data = JSON.parse(event.data)
if(data.property === 'hit_opened') {
hit_finished = false
request_time = timeStamp()
divs[data.property].innerHTML = `${request_time.format('dd mmm HH:MM:ss')}`
}
else if(data.property === 'hit_submitted'){
hit_finished = true;
}
else if(divs[data.property]) divs[data.property].innerHTML = `${data.value}`
})
// ANIMATION STUFF /////////////////////////////////////////////////////////////
let frames,
frames_per_sec = 10,
current_frame = 0
function makeAnimation(){
let now,
delta = 0,
last = timeStamp(),
step = 1/frames_per_sec
function frame() {
now = timeStamp()
delta += Math.min(1, (now - last) / 1000)
while(delta > step){
delta -= step
update(step)
}
last = now
requestAnimationFrame(frame)
}
requestAnimationFrame(frame)
}
function update(step){
if(!hit_finished) elapsed_time = `${new Date((Date.now() - request_time)).format('MM"m "ss"s"')}`
divs['elapsed_time'].innerHTML = elapsed_time
}
makeAnimation()
function timeStamp(){return window.performance && window.performance.now ? window.performance.now() : new Date().getTime()}

View file

@ -0,0 +1,114 @@
let spec = {
worker_id: '-',
ip_address: '-',
country: '-',
start_time: '-',
time: '-',
assign_status: '-',
approval_status: '-'
}
let worker_specs = Object.create(spec),
prev_specs = Object.create(spec)
let divs = {
worker_id: document.getElementById('worker_id'),
ip_address: document.getElementById('ip_address'),
country: document.getElementById('country'),
time: document.getElementById('time'),
assign_status: document.getElementById('assign_status'),
approval_status: document.getElementById('approval_status')
}
let socket = io.connect('/')
socket.on('connection', function(){
console.log('connected to node server')
})
let opacity = 0.1
socket.on('workerSpecs', function(data){
Object.assign(prev_specs, worker_specs)
worker_specs = data
opacity = 0
})
let display_specs = function(){
Object.keys(worker_specs).forEach(function(key){
if(divs[key]){
divs[key].innerText = worker_specs[key]
divs[key].style = `opacity: ${opacity}`
}
})
opacity == 1 ? opacity = 0 : opacity += 0.1
}
// ANIMATION ///////////////////////////////////////////////////////////////////
let frames,
frames_per_sec = 10,
current_frame = 0
function makeAnimation(){
let now,
delta = 0,
last = timeStamp(),
step = 1/frames_per_sec
function frame() {
now = timeStamp()
delta += Math.min(1, (now - last) / 1000)
while(delta > step){
delta -= step
update(step)
}
// render(delta)
last = now
requestAnimationFrame(frame)
}
requestAnimationFrame(frame)
}
//// update state according to framerate
function update(step){
display_specs()
}
//// render as fast as possible
// function render(delta){
// }
//
// let time = (new Date().getTime() - worker_specs.start_time) / 1000
// worker_specs.time = time.toString()
// Object.keys(worker_specs).forEach( function(key){
// if(divs[key]) while(divs[key].firstChild){divs[key].removeChild(divs[key].firstChild)}
// for(let i = 0; i < worker_specs[key].length; i++){
// let span = document.createElement('span')
// worker_specs[key][i] == prev_specs[key][i] ? span.className = 'char_normal' : span.className = 'char_big'
// span.innerText = worker_specs[key][i]
// if(divs[key]) divs[key].append(span)
// }
// })
// Object.assign(prev_specs, worker_specs)
makeAnimation()
function timeStamp(){return window.performance && window.performance.now ? window.performance.now() : new Date().getTime()}

View file

@ -0,0 +1,93 @@
@font-face {
font-family: 'bebas';
src: url('font/BebasNeue-Regular.ttf');
}
@font-face {
font-family: 'freesans';
src: url('font/FreeSans.ttf')
}
:root{
--base-font-size: 25px;
--spec_name-font-size: 120%;
--spec_value-font-size: 250%;
--base-color: #271601; /* tekst */
--alt-color: #FFF5DF; /* achtergrond */
/* /////// GAT VOORKANT PLEK & POSITIE //////// */
/* */ /* */
/* */ --pos-x: calc(50% - (var(--width)/2)); /* */
/* */ --pos-y: 200px; /* */
/* */ --width: 560px; /* 115mm */
/* */ --height: 1250px; /* 260mm */
/* */ /* */
/* //////////////////////////////////////////// */
}
html, body{
margin: 0;
padding: 0;
border: 0;
text-decoration: none;
font-family: 'bebas';
font-size: var(--base-font-size);
line-height: 1.1;
background: #000;
overflow: hidden;
}
#wrapper{
position: absolute;
left: var(--pos-x);
top: var(--pos-y);
width: var(--width);
height: var(--height);
background: var(--alt-color);
box-sizing: border-box;
padding: 2%;
}
#worker_specs{
display:grid;
grid-template-columns: 1fr ;
grid-template-rows: repeat(50, 1fr 2fr);
}
.grid-item{
color: var(--base-color);
}
.spec_name{
font-size: var(--spec_name-font-size);
font-family: 'freesans';
}
.spec_value{
font-size: var(--spec_value-font-size);
padding-bottom: 2%;
}
.phase{
display:none;
}
.phase:not(#worker_specs){
padding-top: 100%;
text-align: center;
}
.narrative_phase_text{
font-size: var(--spec_value-font-size);
}

View file

@ -0,0 +1,142 @@
@font-face {
font-family: 'bebas';
src: url('font/BebasNeue-Regular.ttf');
}
:root{
--base-font-size: 20px;
--desc-font-size: 24px;
--val-font-size: 48px;
}
html, body{
margin: 0;
padding: 0;
border: 0;
text-decoration: none;
font-family: bebas;
font-size: var(--base-font-size);
background: #000;
text-align: center;
}
.grid-item{
vertical-align: middle;
}
.char_normal{
height: inherit; display: inherit; text-align: inherit; vertical-align: inherit;
/* font-size: 40px; */
/* color: #222; */
}
.char_big{
height: inherit; display: inherit; text-align: inherit; vertical-align: inherit;
/* font-size: 48px; */
color:#000;
}
/* GRID //////////////////////////////////////////////////////////////////////*/
.grid-wrap{
display:grid;
grid-template-columns: 1fr 2fr 1fr 1fr 2fr 1fr 1fr 2fr;
grid-template-rows: repeat(14, 20px);
/* line-height: 0.7; */
position: absolute;
width: 1610px;
height: 200px;
top: 200px;
left: 10px;
background: #fff;
padding: 40px 20px 0px 20px;
justify-items: end;
align-items: end;
}
.grid-item *{
display: inline;
height: 60px;
}
.desc{
justify-self: start;
font-size: var(--desc-font-size);
}
.val{
font-size: var(--val-font-size);
}
/* row start / col start / row end / col end */
#worker_id_desc{
grid-area: 1 / 1 / span 1 / span 1;
}
#worker_id{
grid-area: 1 / 2 / span 2 / span 1;
}
#ip_address_desc{
grid-area: 4 / 1 / span 1 / span 1;
}
#ip_address{
grid-area: 4 / 2 / span 2 / span 1;
}
#country_desc{
grid-area: 7 / 1 / span 1 / span 1;
}
#country{
grid-area: 7 / 2 / span 2 / span 1;
}
#time_desc{
grid-area: 1 / 4 / span 1 /span 1;
}
#time{
grid-area: 1 / 5 / span 2 / span 1;
}
#assign_status_desc{
grid-area: 4 / 4 / span 1 / span 1;
}
#assign_status{
grid-area: 4 / 5 / span 2 / span 1;
}
#approval_status_desc{
grid-area: 7 / 4 / span 1 / span 1;
}
#approval_status{
grid-area: 7 / 5 / span 2 / span 1;
}