Add passing users not annotated utterances (by them)

Switch to secrets module for cookie tokens.
Add console, exec mode to annotation_stats.py (todo rename script)
Add some more info in index.html helper modal.
This commit is contained in:
siulkilulki 2018-05-25 12:39:06 +02:00
parent fbcf3bad4e
commit 6a3819eb0a
3 changed files with 37 additions and 13 deletions

View File

@ -84,6 +84,11 @@ def main():
investigate_by_cookie(sys.argv[2]) investigate_by_cookie(sys.argv[2])
elif sys.argv[1] == 'index': elif sys.argv[1] == 'index':
pprint_utterance(int(sys.argv[2])) pprint_utterance(int(sys.argv[2]))
elif sys.argv[1] == 'console':
import ipdb
ipdb.set_trace()
elif sys.argv[1] == 'exec':
exec('print(r.{})'.format(sys.argv[2]), {'print': print, 'r': r})
if __name__ == '__main__': if __name__ == '__main__':

View File

@ -1,6 +1,6 @@
from flask import Flask, render_template, request, make_response, jsonify from flask import Flask, render_template, request, make_response, jsonify
import secrets
import time import time
import os
from get_utterances import Utterance from get_utterances import Utterance
import redis import redis
import pickle import pickle
@ -46,19 +46,37 @@ if status != 'filled':
status = 'filled' status = 'filled'
def get_next(): def get_utterance_for_web(index):
index = int(r.zrangebyscore(UTT_SCORES, '-inf', 'inf')[1])
left_context = utterances[index]['prefix'].replace('\n', '<br>') left_context = utterances[index]['prefix'].replace('\n', '<br>')
hour = utterances[index]['hour'].replace('\n', '<br>') hour = utterances[index]['hour'].replace('\n', '<br>')
right_context = ' '.join( right_context = ' '.join(
utterances[index]['suffix'].split(' ')[:10]).replace('\n', '<br>') utterances[index]['suffix'].split(' ')[:10]).replace('\n', '<br>')
return left_context, hour, right_context
def find_not_annotated(cookie_hash):
# XXX: should be effecient enough even though it's O(n)
for index in range(len(utterances)):
if not r.exists(f'{cookie_hash}:{index}'):
return index
def get_next(cookie_hash):
"""returns utterance with minmum annotations if that utterance
wasn't annotated by cookie_hash user
or not yet annotated utterance by cookie_hash user"""
index = int(r.zrangebyscore(UTT_SCORES, '-inf', 'inf')[1])
if r.exists(f'{cookie_hash}:{index}'):
index = find_not_annotated(cookie_hash)
log('found unannotated index: {}'.format(index))
left_context, hour, right_context = get_utterance_for_web(index)
# log('get_next index: {}, score: {}'.format(index, # log('get_next index: {}, score: {}'.format(index,
# r.zscore(UTT_SCORES, index))) # r.zscore(UTT_SCORES, index)))
return index, left_context, hour, right_context return index, left_context, hour, right_context
def get_next_response(cookie_hash): def get_next_response(cookie_hash):
index, left_context, hour, right_context = get_next() index, left_context, hour, right_context = get_next(cookie_hash)
resp = jsonify( resp = jsonify(
index=index, index=index,
left_context=left_context, left_context=left_context,
@ -70,10 +88,7 @@ def get_next_response(cookie_hash):
def get_by_index(index): def get_by_index(index):
left_context = utterances[index]['prefix'].replace('\n', '<br>') left_context, hour, right_context = get_utterance_for_web(index)
hour = utterances[index]['hour'].replace('\n', '<br>')
right_context = ' '.join(
utterances[index]['suffix'].split(' ')[:10]).replace('\n', '<br>')
# log('get_next index: {}, score: {}'.format(index, # log('get_next index: {}, score: {}'.format(index,
# r.zscore(UTT_SCORES, index))) # r.zscore(UTT_SCORES, index)))
return index, left_context, hour, right_context return index, left_context, hour, right_context
@ -124,13 +139,13 @@ def annotate_redis(yesno, index, ip_addr, cookie_hash):
def set_cookie(js_hash): def set_cookie(js_hash):
## TODO: dodawać nowe js_hash do listy z key bedacym cookie_hash | czy trzeba? ## TODO: dodawać nowe js_hash do listy z key bedacym cookie_hash | czy trzeba?
old_cookie_hash = None old_cookie_hash = None
js_hash_key = 'jshash:' + js_hash
cookie_hash = request.cookies.get(COOKIE_NAME) cookie_hash = request.cookies.get(COOKIE_NAME)
if not cookie_hash: if not cookie_hash:
old_cookie_hash = r.get(js_hash) old_cookie_hash = r.get(js_hash_key)
if not old_cookie_hash: if not old_cookie_hash:
cookie_hash = str( cookie_hash = secrets.token_urlsafe(16)
int.from_bytes(os.urandom(4), byteorder='little')) r.set(js_hash_key, cookie_hash)
r.set(js_hash, cookie_hash)
log('Cookie not on client side. Creating new cookie.') log('Cookie not on client side. Creating new cookie.')
else: else:
log('Cookie not on client side. Getting cookie from fingerprint.') log('Cookie not on client side. Getting cookie from fingerprint.')
@ -159,11 +174,12 @@ def undo(cookie_hash):
r.rpush('undo:' + cookie_hash, last_action) r.rpush('undo:' + cookie_hash, last_action)
index = int(last_action.split(':')[1]) index = int(last_action.split(':')[1])
return get_response_by_index(index, cookie_hash) return get_response_by_index(index, cookie_hash)
log('No last action returning None')
# if no cookie-hash or action list is empty resp = None # if no cookie-hash or action list is empty resp = None
def handle_ip_cookies(ip_key, cookie_hash): def handle_ip_cookies(ip_key, cookie_hash):
"""mechanism for forcing users to use X cookies per ip but no more than X""" """mechanism for forcing users to use maximum X cookies per ip but no more than X"""
r.sadd(ip_key, cookie_hash) r.sadd(ip_key, cookie_hash)
if int(r.ttl(ip_key)) == -1: if int(r.ttl(ip_key)) == -1:
r.expire(ip_key, 60 * 60 * 3) r.expire(ip_key, 60 * 60 * 3)
@ -197,6 +213,7 @@ def http_post():
else: else:
cookie_hash = request.cookies.get(COOKIE_NAME) cookie_hash = request.cookies.get(COOKIE_NAME)
if not cookie_hash: if not cookie_hash:
log('No cookie hash given by client')
return None return None
if action == 'undo': if action == 'undo':
resp = undo(cookie_hash) resp = undo(cookie_hash)

View File

@ -64,11 +64,13 @@
<h5> Kiedy nacisnąć "Tak"</h5> <h5> Kiedy nacisnąć "Tak"</h5>
<ul> <ul>
<li>jak jesteś pewien lub prawie pewien, że na żółto podświetlono godzinę mszy</li> <li>jak jesteś pewien lub prawie pewien, że na żółto podświetlono godzinę mszy</li>
<li>kiedy na żółto podświetlono godzinę mszy świętej której nie ma np. "dzisiaj nie ma mszy świętej o godzinie <strong class="bg-warning">6.30</strong>"</li>
</ul> </ul>
<h5> Kiedy nacisnąć "Nie"</h5> <h5> Kiedy nacisnąć "Nie"</h5>
<ul> <ul>
<li>jeśli nie jesteś pewien czy zaznaczono godzinę rozpoczęcia mszy</li> <li>jeśli nie jesteś pewien czy zaznaczono godzinę rozpoczęcia mszy</li>
<li> jeśli zupełnie nie wiesz czy zazanaczono godzinę rozpoczęcia mszy</li> <li> jeśli zupełnie nie wiesz czy zazanaczono godzinę rozpoczęcia mszy</li>
<li> jeśli zaznaczono tylko kawałek godziny mszy świętej np. "msza święta o godz. <strong class="bg-warning">6</strong>: 30"</li>
</ul> </ul>
<h5> Co jeśli się pomyliłem</h5> <h5> Co jeśli się pomyliłem</h5>
<p> Jeśli się pomyliłeś nacisńij przycisk <a href="#" role="button" class="btn btn-warning" title="Cofnij" data-content="">Cofnij</a> znajdujący się w lewym górnym rogu. Możesz cofać tak długo, aż znajdziesz swoją pomyłkę. Najbliżej znajdują się Twoje ostatnio oznaczone kawałki.</p> <p> Jeśli się pomyliłeś nacisńij przycisk <a href="#" role="button" class="btn btn-warning" title="Cofnij" data-content="">Cofnij</a> znajdujący się w lewym górnym rogu. Możesz cofać tak długo, aż znajdziesz swoją pomyłkę. Najbliżej znajdują się Twoje ostatnio oznaczone kawałki.</p>