This commit is contained in:
Ruben van de Ven 2019-10-31 14:35:24 +01:00
parent cd2f4d3d1d
commit f87c959f22
6 changed files with 215 additions and 1 deletions

View file

@ -1,6 +1,6 @@
import logging
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, DateTime
from sqlalchemy import Column, Integer, String, DateTime, Float
from sqlalchemy.orm import relationship
from sqlalchemy.sql.schema import ForeignKey, Sequence
from sqlalchemy.engine import create_engine
@ -55,6 +55,7 @@ class HIT(Base):
turk_screen_width = Column(Integer, default = None)
turk_screen_height = Column(Integer, default = None)
scanned_at = Column(DateTime, default=None)
fee = Column(Float(precision=2), default=None)
def getImagePath(self):
@ -149,6 +150,11 @@ class Store:
return int(2.5*60)
return int(sum(durations) / len(durations))
def getHITs(self, n = 100):
return self.session.query(HIT).\
filter(HIT.submit_hit_at != None).\
order_by(HIT.submit_hit_at.desc()).limit(n)
# def rmSource(self, id: int):
# with self.getSession() as session:
# source = session.query(Source).get(id)

View file

@ -226,6 +226,7 @@ class CentralManagement():
estimatedHitDuration = self.store.getAvgDurationOfPreviousNHits(5)
fee = (self.config['hour_rate_aim']/3600.) * estimatedHitDuration
self.currentHit.fee = fee
self.logger.debug(f"Based on average duration of {estimatedHitDuration} fee should be {fee}/hit to get hourly rate of {self.config['hour_rate_aim']}")
new_hit = self.mturk.create_hit(
Title = 'Trace the drawn line',

View file

@ -274,6 +274,40 @@ class DrawPageHandler(tornado.web.RequestHandler):
.replace("{LEFT_PADDING}", str(self.top_padding))
self.write(contents)
class BackendHandler(tornado.web.RequestHandler):
def initialize(self, store: HITStore, path: str):
self.store = store
self.path = path
def get(self):
rows = []
for hit in self.store.getHITs(100):
if hit.submit_hit_at and hit.accept_time:
seconds = (hit.submit_hit_at - hit.accept_time).total_seconds()
duration_m = int(seconds/60)
duration_s = max(int(seconds%60), 0)
print(duration_m, duration_s)
duration = (f"{duration_m}m" if duration_m else "") + f"{duration_s:02d}s"
else:
duration = "-"
fee = f"${hit.fee:.2}" if hit.fee else "-"
rows.append(
f"""
<tr><td></td><td>{hit.worker_id}</th>
<td>{hit.turk_ip}</td>
<td>{hit.turk_country}</td>
<td>{fee}</td>
<td>{hit.accept_time}</td>
<td>{duration}</td><td></td>
"""
)
contents = open(os.path.join(self.path, 'backend.html'), 'r').read()
contents = contents.replace("{{TBODY}}", "".join(rows))
self.write(contents)
class StatusPage():
"""
Properties for on the status page, which are send over websockets the moment
@ -365,6 +399,11 @@ class Server:
top_padding=self.config['scanner']['top_padding'],
left_padding=self.config['scanner']['left_padding']
)),
(r"/backend", BackendHandler,
dict(
store = self.store,
path=self.web_root,
)),
(r"/(.*)", StaticFileWithHeaderHandler,
{"path": self.web_root}),
], debug=True, autoreload=False)

26
www/amazon.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 21 KiB

110
www/backend.css Normal file
View file

@ -0,0 +1,110 @@
@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: 12px;
--spec_name-font-size: 120%;
--spec_value-font-size: 250%;
--base-color: #271601; /* tekst */
--alt-color: #FFF5DF; /* achtergrond */
--amazon-color: #F0C14C;
/* ////// GAT ACHTERKANT PLEK & POSITIE /////// */
/* */ /* */
/* */ --pos-x: 20px; /* */
/* */ --pos-y: 20px; /* */
/* */ --width: 90%; /* 115mm */
/* */ --height: 100%; /* 500mm */
/* */ /* */
/* //////////////////////////////////////////// */
}
html, body{
margin: 0;
padding: 0;
border: 0;
text-decoration: none;
font-family: 'freesans';
font-size: var(--base-font-size);
line-height: 1.1;
background: #555;
overflow: hidden;
}
#logo{
background: #555;
width: 100%;
padding: 2% 0% 1% 0%;
text-align: right;
}
#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%; */
}
table{
display: grid;
border-collapse: collapse;
min-width: 100%;
grid-template-columns: repeat(6, 1fr);
}
thead, tbody, tr{
display: contents;
}
th,
td {
padding: 2%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
th {
position: -webkit-sticky;
position: sticky;
background-image: linear-gradient(var(--alt-color), var(--amazon-color)) ;
top: 0;
text-align: left;
font-weight: normal;
font-size: 1.1rem;
color: var(--base-color);
}
th:last-child {
border: 0;
}
td {
padding-top: 2%;
padding-bottom: 2%;
color: #808080;
}
tr:nth-child(even) td {
background: #f8f6f9;
}

32
www/backend.html Normal file
View file

@ -0,0 +1,32 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="stylesheet" type="text/css" href="backend.css" />
<meta http-equiv="refresh" content="20">
</head>
<body>
<div id="wrapper">
<div id="logo"> <img src="amazon.svg" /> </div>
<table>
<thead>
<tr>
<th></th>
<th>worker id</th>
<th>ip address</th>
<th>country</th>
<th>fee</th>
<th>task start time</th>
<th>task completion time</th>
<th></th>
</tr>
</thead>
<tbody>
{{TBODY}}
</tbody>
</table>
</div>
</body>
</html>