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 import logging
from sqlalchemy.ext.declarative import declarative_base 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.orm import relationship
from sqlalchemy.sql.schema import ForeignKey, Sequence from sqlalchemy.sql.schema import ForeignKey, Sequence
from sqlalchemy.engine import create_engine from sqlalchemy.engine import create_engine
@ -55,6 +55,7 @@ class HIT(Base):
turk_screen_width = Column(Integer, default = None) turk_screen_width = Column(Integer, default = None)
turk_screen_height = Column(Integer, default = None) turk_screen_height = Column(Integer, default = None)
scanned_at = Column(DateTime, default=None) scanned_at = Column(DateTime, default=None)
fee = Column(Float(precision=2), default=None)
def getImagePath(self): def getImagePath(self):
@ -149,6 +150,11 @@ class Store:
return int(2.5*60) return int(2.5*60)
return int(sum(durations) / len(durations)) 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): # def rmSource(self, id: int):
# with self.getSession() as session: # with self.getSession() as session:
# source = session.query(Source).get(id) # source = session.query(Source).get(id)

View file

@ -226,6 +226,7 @@ class CentralManagement():
estimatedHitDuration = self.store.getAvgDurationOfPreviousNHits(5) estimatedHitDuration = self.store.getAvgDurationOfPreviousNHits(5)
fee = (self.config['hour_rate_aim']/3600.) * estimatedHitDuration 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']}") 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( new_hit = self.mturk.create_hit(
Title = 'Trace the drawn line', Title = 'Trace the drawn line',

View file

@ -274,6 +274,40 @@ class DrawPageHandler(tornado.web.RequestHandler):
.replace("{LEFT_PADDING}", str(self.top_padding)) .replace("{LEFT_PADDING}", str(self.top_padding))
self.write(contents) 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(): class StatusPage():
""" """
Properties for on the status page, which are send over websockets the moment 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'], top_padding=self.config['scanner']['top_padding'],
left_padding=self.config['scanner']['left_padding'] left_padding=self.config['scanner']['left_padding']
)), )),
(r"/backend", BackendHandler,
dict(
store = self.store,
path=self.web_root,
)),
(r"/(.*)", StaticFileWithHeaderHandler, (r"/(.*)", StaticFileWithHeaderHandler,
{"path": self.web_root}), {"path": self.web_root}),
], debug=True, autoreload=False) ], 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>