Ejemplo n.º 1
0
def seat(message: dict):
    if authenticated:
        name = names[int(message['nameIndex'])]
        si = message['seatIndex']
        ip = request.remote_addr
        persister.seat_indexes_by_ip[ip] = si
        persister.save()

        logger.info(f'{ip} seat {name} to {si}')
        existing_different_index = [i for i, station in enumerate(stations) if station.get('name') == name and i != si]
        if existing_different_index:
            stations[existing_different_index[0]] = {}
        if len(stations[si]):
            name_at_new_station = stations[si].get('name')
            if name_at_new_station and name != name_at_new_station:
                emit('disconnect_station', si, broadcast=True, namespace=TEACHER_NS)
                msg = f'Someone at {ip} claiming to be {name} has moved to {station_name(si)}, ' \
                    f'displacing {name_at_new_station}'
                logger.warning(msg)
                relay_chat(RH3K_ID, msg)

        station = {'ip': ip, 'sid': request.sid, 'name': name, 'connected': True}
        stations[si] = station
        broadcast_seated(station, si)
        return OK
Ejemplo n.º 2
0
def relay_chat(sender: str, msg: str) -> None:
    r = request
    logger.info('Chat message from %s at %s: %s', sender, r.remote_addr, msg)
    html = markdown(strftime('%H:%M:%S') + ' ' + sender + ': ' + msg)
    for ns in ALL_NS:
        if settings['chatEnabled'] or ns == TEACHER_NS:
            emit('chat_msg', html, namespace=ns, broadcast=True)
Ejemplo n.º 3
0
def teacher():
    r = request
    logger.info('Teacher page requested from %s, %s', r.remote_addr,
                r.user_agent)
    return render_template('teacher.html',
                           settings=json.dumps(settings),
                           stationJson=json.dumps(stations))
Ejemplo n.º 4
0
def seat(message: dict):
    if authenticated:
        name = message['name']
        si = message['seatIndex']
        ip = request.remote_addr
        persister.seat_indexes_by_ip[ip] = si
        persister.save()

        logger.info('%s seat %s to %d', ip, name, si)
        existing_different_index = [
            i for i, station in enumerate(stations)
            if station.get('name') == name and i != si
        ]
        if existing_different_index:
            stations[existing_different_index[0]] = {}
        if len(stations[si]):
            name_at_new_station = stations[si].get('name')
            if name_at_new_station and name != name_at_new_station:
                msg = 'Someone at %s claiming to be %s has moved to %s, displacing %s' % (
                    ip, name, station_name(si), name_at_new_station)
                logger.warn(msg)
                relay_chat('RH3K', msg)

        station = {'ip': ip, 'sid': request.sid, 'name': name}
        stations[si] = station
        broadcast_seated(station, si)
Ejemplo n.º 5
0
def set_names(message: dict) -> None:
    if authenticated:
        r = request
        ip = r.remote_addr
        logger.info('set_names from %s, %s', ip, r.sid)
        emit('set_names', message, broadcast=True, namespace=STUDENT_NS)
        global names
        names = []
        assign_seats: bool = message['assignSeats']

        def skip_missing(start: int) -> int:
            while start in settings['missingSeatIndexes']:
                start += 1
            return start

        si = skip_missing(0)
        for line in message['names'].split('\n'):
            name = line.strip()
            if name:
                names.append(name)
                if assign_seats:
                    station = {'ip': ip, 'name': name}
                    stations[si] = station
                    broadcast_seated(station, si)
                    si = skip_missing(si + 1)
Ejemplo n.º 6
0
def index():
    r = request
    seat_index = persister.seat_indexes_by_ip.get(r.remote_addr, -1)
    logger.info('Student page requested from %s (last seat index: %d), %s',
                r.remote_addr, seat_index, r.user_agent)
    return render_template('student.html',
                           settings=json.dumps(settings),
                           names=names,
                           lastSeatIndex=seat_index)
Ejemplo n.º 7
0
def random_call(anyone: bool) -> int:
    if authenticated:
        eligible = [(k, v) for k, v in enumerate(stations) if v.get('callsLeft', 0) > 0
                    and (anyone or v.get('haveAnswer', False))]
        if eligible:
            chosen = choice(eligible)
            chosen[1]['callsLeft'] -= 1
            logger.info(f'{chosen[1]["name"]} called randomly')
            return chosen[0]
    return -1
Ejemplo n.º 8
0
def relay_shares(sender: str, possible_url: str, allow_any=False) -> None:
    r = request
    logger.info('Shares message from %s at %s: %s', sender, r.remote_addr,
                possible_url)
    parts = urlparse(possible_url)
    if allow_any or parts.hostname in settings['allowedSharesDomains']:
        html = '<p>%s %s: <a href="%s" target="_blank">%s</a></p>' % (
            strftime('%H:%M:%S'), sender, possible_url, possible_url)
        for ns in ALL_NS:
            if settings['sharesEnabled'] or ns == TEACHER_NS:
                emit('shares_msg', html, namespace=ns, broadcast=True)
Ejemplo n.º 9
0
def relay_chat(sender_id: int, raw_msg: str) -> None:
    'Relay chat message, escaping student messages and processing teacher messages with Markdown'
    r = request
    sender: str = sender_from_id(sender_id)
    logger.info(f'Chat message from {sender} at {r.remote_addr}: {raw_msg}')
    msg = raw_msg if sender_id == TEACHER_ID else escape(raw_msg) + '<br/>'
    prefixed_msg = strftime('%H:%M:%S') + f' {sender} : {msg}'
    html = markdown(prefixed_msg) if sender_id == TEACHER_ID else prefixed_msg
    for ns in ALL_NS:
        if settings['chatEnabled'] or ns == TEACHER_NS:
            emit('chat_msg', html, namespace=ns, broadcast=True)
Ejemplo n.º 10
0
def set_status(message: dict) -> None:
    if authenticated:
        si = message['seatIndex']
        station = stations[si]
        if station:
            logger.info('set_status: %s', message)
            now = time()
            for st in settings['statuses']:
                id = st[0]
                station[id] = now if message.get(id, False) else None
            ss_msg = {'seatIndex': si, 'station': station}
            emit('status_set', ss_msg, broadcast=True, namespace=TEACHER_NS)
Ejemplo n.º 11
0
def relay_shares(sender_id: str, possible_url: str, allow_any=False) -> None:
    r = request
    sender: str = sender_from_id(sender_id)
    logger.info(f'Shares message from {sender} at {r.remote_addr}: {possible_url}')
    parts = urlparse(possible_url)
    if allow_any or parts.hostname in settings['allowedSharesDomains']:
        escaped_url = escape(possible_url)
        html = f'<p>{strftime("%H:%M:%S")} {sender}: <a href="{escaped_url}" target="_blank">{escaped_url}</a></p>'
        settings['shares'].append(html)
        for ns in ALL_NS:
            if settings['sharesEnabled'] or ns == TEACHER_NS:
                emit('shares_msg', html, namespace=ns, broadcast=True)
Ejemplo n.º 12
0
def disconnect_request() -> None:
    r = request
    logger.info('Disconnected: %s, %s', r.remote_addr, r.sid)
    matches = [
        item for item in enumerate(stations) if r.sid == item[1].get('sid')
    ]
    if matches:
        station_index, station = matches[0]
        clear_station(station)
        emit('clear_station',
             station_index,
             broadcast=True,
             namespace=TEACHER_NS)
Ejemplo n.º 13
0
def set_status(message: dict) -> any:
    if authenticated:
        seat_index = message['seatIndex']
        station: Dict[str, Any] = stations[seat_index]
        student_name = station.get('name')
        if student_name:
            key, value = message['status']
            logger.info(f'{student_name} status: {key}: {value}')

            # Temporarily log haveAnswer toggles until reliability problem is solved
            if key == 'haveAnswer':
                chat_log_msg = student_name + ' ' + ('is' if value else 'is not') + ' ready'
                relay_chat(RH3K_ID, chat_log_msg)

            station[key] = time() if value else None
            emit('status_set', {'seatIndex': seat_index, 'key': key, 'value': station[key]}, broadcast=True, namespace=TEACHER_NS)
            return OK

        r = request
        logger.warning(f'set_status from disconnected user {r.remote_addr}, {seat_index}, {r.sid}')
        return DISCONNECTED
Ejemplo n.º 14
0
def set_names(message: dict) -> None:
    if authenticated:
        r = request
        ip = r.remote_addr
        logger.info(f'set_names from {ip}, {r.sid}')
        emit('set_names', message, broadcast=True, namespace=STUDENT_NS)
        global names
        names = []
        assign_seats: bool = message['assignSeats']

        def skip_missing(start: int) -> int:
            new_si = start
            while new_si in settings['missingSeatIndexes']:
                new_si += 1
            return new_si

        si = skip_missing(0)
        for name in message['names']:
            names.append(name)
            if assign_seats:
                station = {'ip': ip, 'name': name, 'connected': True}
                stations[si] = station
                broadcast_seated(station, si)
                si = skip_missing(si + 1)
Ejemplo n.º 15
0
def log_connection(r):
    logger.info(f'Connection from {r.remote_addr}, {r.sid}, {r.user_agent}')
Ejemplo n.º 16
0
def disconnect_request() -> None:
    r = request
    logger.info(f'Disconnected: {r.remote_addr}, {r.sid}')
    connect_or_disconnect(False, r)
Ejemplo n.º 17
0
def index():
    r = request
    seat_index = persister.seat_indexes_by_ip.get(r.remote_addr, -1)
    logger.info(f'Student page requested from {r.remote_addr} (last seat index: {seat_index})')
    return render_template('student.html', settings=json.dumps(settings), names=names, lastSeatIndex=seat_index)
Ejemplo n.º 18
0
def connect():
    r = request
    logger.info('Connection from %s, %s, %s', r.remote_addr, r.sid,
                r.user_agent)
Ejemplo n.º 19
0
def random_set(random_calls_limit: int) -> None:
    if authenticated:
        logger.info('Random calls limit set to %d', random_calls_limit)
        for station in stations:
            if station.get('name'):
                station['callsLeft'] = random_calls_limit
Ejemplo n.º 20
0
def relay_teacher_msg(msg: str) -> None:
    r = request
    logger.info(f'Teacher message from {r.remote_addr}: {msg}')
    html = markdown(msg)
    for ns in ALL_NS:
        emit('teacher_msg', html, namespace=ns, broadcast=True)