From b2626244a45c94ba28afce307cfcce930c935e55 Mon Sep 17 00:00:00 2001 From: Ruben van de Ven Date: Mon, 13 Jan 2020 16:13:42 +0100 Subject: [PATCH] New HIT status page --- sorteerhoed/HITStore.py | 5 +- sorteerhoed/central_management.py | 2 + sorteerhoed/webserver.py | 1 + www/worker_specs/index.html | 72 +++++++++++++++-- www/worker_specs/script.js | 123 ++++++++---------------------- www/worker_specs/style.css | 56 +++++++++++++- 6 files changed, 155 insertions(+), 104 deletions(-) diff --git a/sorteerhoed/HITStore.py b/sorteerhoed/HITStore.py index 3fc48e4..23a08c2 100644 --- a/sorteerhoed/HITStore.py +++ b/sorteerhoed/HITStore.py @@ -56,10 +56,11 @@ class HIT(Base): return os.path.join('/frames', f"{self.id:06d}.jpg") def getSvgImageUrl(self): - return f"scans/{self.id:06d}.svg" + return f"/scans/{self.id:06d}.svg" def getSvgImagePath(self): - return os.path.join('www', self.getSvgImageUrl()) + # os.path.join on svgImageUrl leads to invalid absolute url + return os.path.join(f'www/scans/{self.id:06d}.svg') def getLastAssignment(self): if not len(self.assignments): diff --git a/sorteerhoed/central_management.py b/sorteerhoed/central_management.py index 81c5c85..5cbb425 100644 --- a/sorteerhoed/central_management.py +++ b/sorteerhoed/central_management.py @@ -238,6 +238,8 @@ class CentralManagement(): continue self.currentHit.scanned_at = datetime.datetime.utcnow() + self.store.saveHIT(self.currentHit) + time_diff = datetime.datetime.now() - self.lastHitTime to_wait = 10 - time_diff.total_seconds() # self.statusPageQueue.add(dict(hit_id=self.currentHit.id, state='scan')) diff --git a/sorteerhoed/webserver.py b/sorteerhoed/webserver.py index bbd2b9f..de1f9cc 100644 --- a/sorteerhoed/webserver.py +++ b/sorteerhoed/webserver.py @@ -165,6 +165,7 @@ class WebSocketHandler(tornado.websocket.WebSocketHandler): def on_close(self): self.__class__.rmConnection(self) logger.info(f"Client disconnected: {self.request.remote_ip}") + # TODO: abandon assignment?? def submit_strokes(self): if len(self.strokes) < 1: diff --git a/www/worker_specs/index.html b/www/worker_specs/index.html index 30abb21..c7df4b5 100644 --- a/www/worker_specs/index.html +++ b/www/worker_specs/index.html @@ -5,11 +5,70 @@ +
- +
+ +
+

Created HIT at {{hit.created_at}}

+

Creating HIT

+
+ + + +
+

Human intelligence task

+

{{hit.hit_id}}

+

Description

+
+ +
+

Wait for human

+ +
+ + + + - + +
+ diff --git a/www/worker_specs/script.js b/www/worker_specs/script.js index 70da85d..1af1efb 100644 --- a/www/worker_specs/script.js +++ b/www/worker_specs/script.js @@ -1,38 +1,22 @@ // DOM STUFF /////////////////////////////////////////////////////////////////// -let divs = {}, - spec_names = [ - 'worker_id', - 'ip', - 'location', - 'browser', - 'os', - 'state', - 'fee', - 'hit_created', - 'hit_opened', - 'hit_submitted', - 'elapsed_time', - 'hit_id' - ] - -divs.linkDOM = function(name){ - divs[name] = document.getElementById(`${name}`) -} - -spec_names.forEach(function(name){ - divs.linkDOM(name) +var app = new Vue({ + el: '#wrapper', + data: { + message: 'Hello Vue!', + hits: { + + } + }, +// watch: { +// hits: { +// deep: true +// } +// } }) - -let request_time = timeStamp(), - hit_started = false, - elapsed_time, - hit_finished = false - - // SOCKET STUFF //////////////////////////////////////////////////////////////// @@ -43,76 +27,29 @@ 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') { - if(data.value != null){ - hit_started = true - hit_finished = false - request_time = new Date() - divs[data.property].innerHTML = `${request_time.format('dd mmm HH:MM:ss')}` - }else{ - divs[data.property].innerHTML = `—` - hit_started = false - } + let hits = JSON.parse(event.data) + let a = {}; + for(let hitid in app.hits) { + a[hitid] = app.hits[hitid]; } - else if(data.property === 'hit_submitted'){ - hit_finished = true; - } - else if(divs[data.property]){ - data.value === null ? divs[data.property].innerHTML = `—` : divs[data.property].innerHTML = `${data.value}` + for(let hit of hits){ + a[hit.id] = hit; } + app.hits = a; }) - - - - - - - // 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"')}` - if(hit_started){ - divs['elapsed_time'].innerHTML = elapsed_time - }else{ - divs['elapsed_time'].innerHTML = `—` - } -} - - -makeAnimation() - - -function timeStamp(){return window.performance && window.performance.now ? window.performance.now() : new Date().getTime()} +// +//function update(step){ +// +// if(!hit_finished) elapsed_time = `${new Date((Date.now() - request_time)).format('MM"m "ss"s"')}` +// if(hit_started){ +// divs['elapsed_time'].innerHTML = elapsed_time +// }else{ +// divs['elapsed_time'].innerHTML = `—` +// } +//} diff --git a/www/worker_specs/style.css b/www/worker_specs/style.css index 9ca0c3e..bb48dcf 100644 --- a/www/worker_specs/style.css +++ b/www/worker_specs/style.css @@ -47,9 +47,9 @@ html, body{ position: absolute; left: var(--pos-x); - top: var(--pos-y); + bottom: calc(100vh - (var(--pos-y) + var(--height))); width: var(--width); - height: var(--height); + height: auto; background: var(--alt-color); box-sizing: border-box; @@ -57,6 +57,57 @@ html, body{ } + +#wrapper .hit{ + display:block; +} + + +.transition{ + overflow:hidden; + position:relative; + padding-left: calc(50%); + font-size: 12px; + height: 40px; + animation-duration: 3s; + animation-name: slidein; +} +.transition::before{ + content:'⇩'; /*'⇓';*/ + display:block; + position:absolute; + font-family:monospace; + font-size: 100px; + top:0; + left:calc(50% - 30px); + line-height:0; +} + +.state{ + overflow:hidden; + border:solid 1px black; + animation-duration: 3s; + animation-name: slidein; + transition: max-height 1s; + max-height: 200px; +} + +.state.assignment-hidden { + /*On abandon etc.*/ + max-height: 0px; +} + +@keyframes slidein { + from { + max-height:0; + } + + to { + max-height: 200px; + } +} + +/* #worker_specs{ display:grid; grid-template-columns: 1fr ; @@ -97,3 +148,4 @@ html, body{ position: relative; top: 5px; } +*/ \ No newline at end of file