src/server/server.py
def pass_record_callback(node, lap_timestamp_absolute, source):
    '''Handles pass records from the nodes.'''

    logger.debug('Raw pass record: Node: {0}, MS Since Lap: {1}'.format(node.index+1, lap_timestamp_absolute))
    node.pass_crossing_flag = False  # clear the "synchronized" version of the crossing flag
    node.debug_pass_count += 1
    emit_node_data() # For updated triggers and peaks

    global RACE
    profile_freqs = json.loads(getCurrentProfile().frequencies)
    if profile_freqs["f"][node.index] != RHUtils.FREQUENCY_ID_NONE:
        # always count laps if race is running, otherwise test if lap should have counted before race end (RACE.duration_ms is invalid while race is in progress)
        if RACE.race_status is RaceStatus.RACING \
            or (RACE.race_status is RaceStatus.DONE and \
                lap_timestamp_absolute < RACE.end_time):

            # Get the current pilot id on the node
            pilot_id = Database.HeatNode.query.filter_by( \
                heat_id=RACE.current_heat, node_index=node.index).one().pilot_id

            # reject passes before race start and with disabled (no-pilot) nodes
            if pilot_id != Database.PILOT_ID_NONE:
                if lap_timestamp_absolute >= RACE.start_time_monotonic:

                    lap_time_stamp = (lap_timestamp_absolute - RACE.start_time_monotonic)
                    lap_time_stamp *= 1000 # store as milliseconds

                    lap_number = len(RACE.get_active_laps()[node.index])

                    if lap_number: # This is a normal completed lap
                        # Find the time stamp of the last lap completed
                        last_lap_time_stamp = RACE.get_active_laps()[node.index][-1]['lap_time_stamp']

                        # New lap time is the difference between the current time stamp and the last
                        lap_time = lap_time_stamp - last_lap_time_stamp

                    else: # No previous laps, this is the first pass
                        # Lap zero represents the time from the launch pad to flying through the gate
                        lap_time = lap_time_stamp
                        node.first_cross_flag = True  # indicate first crossing completed

                    race_format = getCurrentRaceFormat()
                    min_lap = int(Options.get("MinLapSec"))
                    min_lap_behavior = int(Options.get("MinLapBehavior"))

                    lap_ok_flag = True
                    if lap_number != 0:  # if initial lap then always accept and don't check lap time; else:
                        if lap_time < (min_lap * 1000):  # if lap time less than minimum
                            node.under_min_lap_count += 1
                            logger.info('Pass record under lap minimum ({3}): Node={0}, Lap={1}, LapTime={2}, Count={4}' \
                                       .format(node.index+1, lap_number, RHUtils.time_format(lap_time), min_lap, node.under_min_lap_count))
                            if min_lap_behavior != 0:  # if behavior is 'Discard New Short Laps'
                                lap_ok_flag = False

                    if lap_ok_flag:
                        SOCKET_IO.emit('pass_record', {
                            'node': node.index,
                            'frequency': node.frequency,
                            'timestamp': lap_time_stamp + monotonic_to_milliseconds(RACE.start_time_monotonic)
                        })
                        # Add the new lap to the database
                        RACE.node_laps[node.index].append({
                            'lap_number': lap_number,
                            'lap_time_stamp': lap_time_stamp,
                            'lap_time': lap_time,
                            'lap_time_formatted': RHUtils.time_format(lap_time),
                            'source': source,
                            'deleted': False
                        })

                        RACE.results = Results.calc_leaderboard(DB, current_race=RACE, current_profile=getCurrentProfile())
                        RACE.cacheStatus = Results.CacheStatus.VALID

                        Events.trigger(Evt.RACE_LAP_RECORDED, {
                            'race': RACE,
                            'node_index': node.index,
                            })

                        #logger.info('Pass record: Node: {0}, Lap: {1}, Lap time: {2}' \
                        #    .format(node.index+1, lap_number, RHUtils.time_format(lap_time)))
                        emit_current_laps() # update all laps on the race page
                        emit_current_leaderboard() # update leaderboard

                        if race_format.team_racing_mode: # team racing mode enabled

                            # if win condition is first-to-x-laps and x is valid
                            #  then check if a team has enough laps to win
                            if race_format.win_condition == WinCondition.FIRST_TO_LAP_X and race_format.number_laps_win > 0:
                                t_laps_dict, team_name, pilot_team_dict = \
                                    get_team_laps_info(pilot_id, race_format.number_laps_win)
                                team_laps = t_laps_dict[team_name][0]
                                check_team_laps_win(t_laps_dict, race_format.number_laps_win, pilot_team_dict, node.index)
                            else:
                                t_laps_dict, team_name, pilot_team_dict = get_team_laps_info(pilot_id, RACE.winning_lap_id)
                                team_laps = t_laps_dict[team_name][0]
                            check_emit_team_racing_status(t_laps_dict)

                            if lap_number > 0:   # send phonetic data to be spoken
                                emit_phonetic_data(pilot_id, lap_number, lap_time, team_name, team_laps)

                                # if Most Laps Wins race is tied then check for winner
                                if race_format.win_condition == WinCondition.MOST_LAPS:
                                    if RACE.laps_winner_name is RACE.status_tied_str or \
                                                RACE.laps_winner_name is RACE.status_crossing:
                                        check_most_laps_win(node.index, t_laps_dict, pilot_team_dict)

                                # if a team has won the race and this is the winning lap
                                elif RACE.laps_winner_name is not None and \
                                            team_name == RACE.laps_winner_name and \
                                            team_laps >= race_format.number_laps_win:
                                    emit_phonetic_text('Winner is team ' + RACE.laps_winner_name, 'race_winner')
                            elif lap_number == 0:
                                emit_first_pass_registered(node.index) # play first-pass sound

                        else:  # not team racing mode
                            if lap_number > 0:
                                                # send phonetic data to be spoken
                                if race_format.win_condition != WinCondition.FIRST_TO_LAP_X or race_format.number_laps_win <= 0:
                                    emit_phonetic_data(pilot_id, lap_number, lap_time, None, None)

                                                     # if Most Laps Wins race is tied then check for winner
                                    if race_format.win_condition == WinCondition.MOST_LAPS:
                                        if RACE.laps_winner_name is RACE.status_tied_str or \
                                                    RACE.laps_winner_name is RACE.status_crossing:
                                            check_most_laps_win(node.index)

                                else:           # need to check if any pilot has enough laps to win
                                    if race_format.win_condition == WinCondition.FIRST_TO_LAP_X:
                                        win_pilot_id = check_pilot_laps_win(node.index, race_format.number_laps_win)
                                        if win_pilot_id >= 0:  # a pilot has won the race
                                            win_callsign = Database.Pilot.query.get(win_pilot_id).callsign
                                            emit_team_racing_status('Winner is ' + win_callsign)
                                            emit_phonetic_data(pilot_id, lap_number, lap_time, None, None)

                                            if RACE.laps_winner_name is None:
                                                    # a pilot has won the race and has not yet been announced
                                                win_phon_name = Database.Pilot.query.get(win_pilot_id).phonetic
                                                if len(win_phon_name) <= 0:  # if no phonetic then use callsign
                                                    win_phon_name = win_callsign
                                                RACE.laps_winner_name = win_callsign  # call out winner (once)
                                                emit_phonetic_text('Winner is ' + win_phon_name, 'race_winner')

                                        else:  # no pilot has won the race; send phonetic data to be spoken
                                            emit_phonetic_data(pilot_id, lap_number, lap_time, None, None)
                                    else:  # other win conditions
                                            emit_phonetic_data(pilot_id, lap_number, lap_time, None, None)
                            elif lap_number == 0:
                                emit_first_pass_registered(node.index) # play first-pass sound
                    else:
                        RACE.node_laps[node.index].append({
                            'lap_number': lap_number,
                            'lap_time_stamp': lap_time_stamp,
                            'lap_time': lap_time,
                            'lap_time_formatted': RHUtils.time_format(lap_time),
                            'source': source,
                            'deleted': True
                        })
                else:
                    logger.debug('Pass record dismissed: Node: {0}, Race not started' \
                        .format(node.index+1))
            else:
                logger.debug('Pass record dismissed: Node: {0}, Pilot not defined' \
                    .format(node.index+1))
    else:
        logger.debug('Pass record dismissed: Node: {0}, Frequency not defined' \
            .format(node.index+1))
Handles pass records from the nodes.
Handles pass records from the nodes.
Handles pass records from the nodes .
def pass_record_callback(node, lap_timestamp_absolute, source):
    logger.debug('Raw pass record: Node: {0}, MS Since Lap: {1}'.format(node.index+1, lap_timestamp_absolute))
    node.pass_crossing_flag = False  
    node.debug_pass_count += 1
    emit_node_data() 
    global RACE
    profile_freqs = json.loads(getCurrentProfile().frequencies)
    if profile_freqs["f"][node.index] != RHUtils.FREQUENCY_ID_NONE:
        if RACE.race_status is RaceStatus.RACING \
            or (RACE.race_status is RaceStatus.DONE and \
                lap_timestamp_absolute < RACE.end_time):
            pilot_id = Database.HeatNode.query.filter_by( \
                heat_id=RACE.current_heat, node_index=node.index).one().pilot_id
            if pilot_id != Database.PILOT_ID_NONE:
                if lap_timestamp_absolute >= RACE.start_time_monotonic:
                    lap_time_stamp = (lap_timestamp_absolute - RACE.start_time_monotonic)
                    lap_time_stamp *= 1000 
                    lap_number = len(RACE.get_active_laps()[node.index])
                    if lap_number: 
                        last_lap_time_stamp = RACE.get_active_laps()[node.index][-1]['lap_time_stamp']
                        lap_time = lap_time_stamp - last_lap_time_stamp
                    else: 
                        lap_time = lap_time_stamp
                        node.first_cross_flag = True  
                    race_format = getCurrentRaceFormat()
                    min_lap = int(Options.get("MinLapSec"))
                    min_lap_behavior = int(Options.get("MinLapBehavior"))
                    lap_ok_flag = True
                    if lap_number != 0:  
                        if lap_time < (min_lap * 1000):  
                            node.under_min_lap_count += 1
                            logger.info('Pass record under lap minimum ({3}): Node={0}, Lap={1}, LapTime={2}, Count={4}' \
                                       .format(node.index+1, lap_number, RHUtils.time_format(lap_time), min_lap, node.under_min_lap_count))
                            if min_lap_behavior != 0:  
                                lap_ok_flag = False
                    if lap_ok_flag:
                        SOCKET_IO.emit('pass_record', {
                            'node': node.index,
                            'frequency': node.frequency,
                            'timestamp': lap_time_stamp + monotonic_to_milliseconds(RACE.start_time_monotonic)
                        })
                        RACE.node_laps[node.index].append({
                            'lap_number': lap_number,
                            'lap_time_stamp': lap_time_stamp,
                            'lap_time': lap_time,
                            'lap_time_formatted': RHUtils.time_format(lap_time),
                            'source': source,
                            'deleted': False
                        })
                        RACE.results = Results.calc_leaderboard(DB, current_race=RACE, current_profile=getCurrentProfile())
                        RACE.cacheStatus = Results.CacheStatus.VALID
                        Events.trigger(Evt.RACE_LAP_RECORDED, {
                            'race': RACE,
                            'node_index': node.index,
                            })
                        emit_current_laps() 
                        emit_current_leaderboard() 
                        if race_format.team_racing_mode: 
                            if race_format.win_condition == WinCondition.FIRST_TO_LAP_X and race_format.number_laps_win > 0:
                                t_laps_dict, team_name, pilot_team_dict = \
                                    get_team_laps_info(pilot_id, race_format.number_laps_win)
                                team_laps = t_laps_dict[team_name][0]
                                check_team_laps_win(t_laps_dict, race_format.number_laps_win, pilot_team_dict, node.index)
                            else:
                                t_laps_dict, team_name, pilot_team_dict = get_team_laps_info(pilot_id, RACE.winning_lap_id)
                                team_laps = t_laps_dict[team_name][0]
                            check_emit_team_racing_status(t_laps_dict)
                            if lap_number > 0:   
                                emit_phonetic_data(pilot_id, lap_number, lap_time, team_name, team_laps)
                                if race_format.win_condition == WinCondition.MOST_LAPS:
                                    if RACE.laps_winner_name is RACE.status_tied_str or \
                                                RACE.laps_winner_name is RACE.status_crossing:
                                        check_most_laps_win(node.index, t_laps_dict, pilot_team_dict)
                                elif RACE.laps_winner_name is not None and \
                                            team_name == RACE.laps_winner_name and \
                                            team_laps >= race_format.number_laps_win:
                                    emit_phonetic_text('Winner is team ' + RACE.laps_winner_name, 'race_winner')
                            elif lap_number == 0:
                                emit_first_pass_registered(node.index) 
                        else:  
                            if lap_number > 0:
                                if race_format.win_condition != WinCondition.FIRST_TO_LAP_X or race_format.number_laps_win <= 0:
                                    emit_phonetic_data(pilot_id, lap_number, lap_time, None, None)
                                    if race_format.win_condition == WinCondition.MOST_LAPS:
                                        if RACE.laps_winner_name is RACE.status_tied_str or \
                                                    RACE.laps_winner_name is RACE.status_crossing:
                                            check_most_laps_win(node.index)
                                else:           
                                    if race_format.win_condition == WinCondition.FIRST_TO_LAP_X:
                                        win_pilot_id = check_pilot_laps_win(node.index, race_format.number_laps_win)
                                        if win_pilot_id >= 0:  
                                            win_callsign = Database.Pilot.query.get(win_pilot_id).callsign
                                            emit_team_racing_status('Winner is ' + win_callsign)
                                            emit_phonetic_data(pilot_id, lap_number, lap_time, None, None)
                                            if RACE.laps_winner_name is None:
                                                     and has not yet been announced
                                                win_phon_name = Database.Pilot.query.get(win_pilot_id).phonetic
                                                if len(win_phon_name) <= 0:  
                                                    win_phon_name = win_callsign
                                                RACE.laps_winner_name = win_callsign  
                                                emit_phonetic_text('Winner is ' + win_phon_name, 'race_winner')
                                        else:  
                                            emit_phonetic_data(pilot_id, lap_number, lap_time, None, None)
                                    else:  
                                            emit_phonetic_data(pilot_id, lap_number, lap_time, None, None)
                            elif lap_number == 0:
                                emit_first_pass_registered(node.index) 
                    else:
                        RACE.node_laps[node.index].append({
                            'lap_number': lap_number,
                            'lap_time_stamp': lap_time_stamp,
                            'lap_time': lap_time,
                            'lap_time_formatted': RHUtils.time_format(lap_time),
                            'source': source,
                            'deleted': True
                        })
                else:
                    logger.debug('Pass record dismissed: Node: {0}, Race not started' \
                        .format(node.index+1))
            else:
                logger.debug('Pass record dismissed: Node: {0}, Pilot not defined' \
                    .format(node.index+1))
    else:
        logger.debug('Pass record dismissed: Node: {0}, Frequency not defined' \
            .format(node.index+1))
def pass_record_callback ( node , lap_timestamp_absolute , source ) : logger . debug ( 'Raw pass record: Node: {0}, MS Since Lap: {1}' . format ( node . index + 1 , lap_timestamp_absolute ) ) node . pass_crossing_flag = False node . debug_pass_count += 1 emit_node_data ( ) global RACE profile_freqs = json . loads ( getCurrentProfile ( ) . frequencies ) if profile_freqs [ "f" ] [ node . index ] != RHUtils . FREQUENCY_ID_NONE : if RACE . race_status is RaceStatus . RACING or ( RACE . race_status is RaceStatus . DONE and lap_timestamp_absolute < RACE . end_time ) : pilot_id = Database . HeatNode . query . filter_by ( heat_id = RACE . current_heat , node_index = node . index ) . one ( ) . pilot_id if pilot_id != Database . PILOT_ID_NONE : if lap_timestamp_absolute >= RACE . start_time_monotonic : lap_time_stamp = ( lap_timestamp_absolute - RACE . start_time_monotonic ) lap_time_stamp *= 1000 lap_number = len ( RACE . get_active_laps ( ) [ node . index ] ) if lap_number : last_lap_time_stamp = RACE . get_active_laps ( ) [ node . index ] [ - 1 ] [ 'lap_time_stamp' ] lap_time = lap_time_stamp - last_lap_time_stamp else : lap_time = lap_time_stamp node . first_cross_flag = True race_format = getCurrentRaceFormat ( ) min_lap = int ( Options . get ( "MinLapSec" ) ) min_lap_behavior = int ( Options . get ( "MinLapBehavior" ) ) lap_ok_flag = True if lap_number != 0 : if lap_time < ( min_lap * 1000 ) : node . under_min_lap_count += 1 logger . info ( 'Pass record under lap minimum ({3}): Node={0}, Lap={1}, LapTime={2}, Count={4}' . format ( node . index + 1 , lap_number , RHUtils . time_format ( lap_time ) , min_lap , node . under_min_lap_count ) ) if min_lap_behavior != 0 : lap_ok_flag = False if lap_ok_flag : SOCKET_IO . emit ( 'pass_record' , { 'node' : node . index , 'frequency' : node . frequency , 'timestamp' : lap_time_stamp + monotonic_to_milliseconds ( RACE . start_time_monotonic ) } ) RACE . node_laps [ node . index ] . append ( { 'lap_number' : lap_number , 'lap_time_stamp' : lap_time_stamp , 'lap_time' : lap_time , 'lap_time_formatted' : RHUtils . time_format ( lap_time ) , 'source' : source , 'deleted' : False } ) RACE . results = Results . calc_leaderboard ( DB , current_race = RACE , current_profile = getCurrentProfile ( ) ) RACE . cacheStatus = Results . CacheStatus . VALID Events . trigger ( Evt . RACE_LAP_RECORDED , { 'race' : RACE , 'node_index' : node . index , } ) emit_current_laps ( ) emit_current_leaderboard ( ) if race_format . team_racing_mode : if race_format . win_condition == WinCondition . FIRST_TO_LAP_X and race_format . number_laps_win > 0 : t_laps_dict , team_name , pilot_team_dict = get_team_laps_info ( pilot_id , race_format . number_laps_win ) team_laps = t_laps_dict [ team_name ] [ 0 ] check_team_laps_win ( t_laps_dict , race_format . number_laps_win , pilot_team_dict , node . index ) else : t_laps_dict , team_name , pilot_team_dict = get_team_laps_info ( pilot_id , RACE . winning_lap_id ) team_laps = t_laps_dict [ team_name ] [ 0 ] check_emit_team_racing_status ( t_laps_dict ) if lap_number > 0 : emit_phonetic_data ( pilot_id , lap_number , lap_time , team_name , team_laps ) if race_format . win_condition == WinCondition . MOST_LAPS : if RACE . laps_winner_name is RACE . status_tied_str or RACE . laps_winner_name is RACE . status_crossing : check_most_laps_win ( node . index , t_laps_dict , pilot_team_dict ) elif RACE . laps_winner_name is not None and team_name == RACE . laps_winner_name and team_laps >= race_format . number_laps_win : emit_phonetic_text ( 'Winner is team ' + RACE . laps_winner_name , 'race_winner' ) elif lap_number == 0 : emit_first_pass_registered ( node . index ) else : if lap_number > 0 : if race_format . win_condition != WinCondition . FIRST_TO_LAP_X or race_format . number_laps_win <= 0 : emit_phonetic_data ( pilot_id , lap_number , lap_time , None , None ) if race_format . win_condition == WinCondition . MOST_LAPS : if RACE . laps_winner_name is RACE . status_tied_str or RACE . laps_winner_name is RACE . status_crossing : check_most_laps_win ( node . index ) else : if race_format . win_condition == WinCondition . FIRST_TO_LAP_X : win_pilot_id = check_pilot_laps_win ( node . index , race_format . number_laps_win ) if win_pilot_id >= 0 : win_callsign = Database . Pilot . query . get ( win_pilot_id ) . callsign emit_team_racing_status ( 'Winner is ' + win_callsign ) emit_phonetic_data ( pilot_id , lap_number , lap_time , None , None ) if RACE . laps_winner_name is None : win_phon_name = Database . Pilot . query . get ( win_pilot_id ) . phonetic if len ( win_phon_name ) <= 0 : win_phon_name = win_callsign RACE . laps_winner_name = win_callsign emit_phonetic_text ( 'Winner is ' + win_phon_name , 'race_winner' ) else : emit_phonetic_data ( pilot_id , lap_number , lap_time , None , None ) else : emit_phonetic_data ( pilot_id , lap_number , lap_time , None , None ) elif lap_number == 0 : emit_first_pass_registered ( node . index ) else : RACE . node_laps [ node . index ] . append ( { 'lap_number' : lap_number , 'lap_time_stamp' : lap_time_stamp , 'lap_time' : lap_time , 'lap_time_formatted' : RHUtils . time_format ( lap_time ) , 'source' : source , 'deleted' : True } ) else : logger . debug ( 'Pass record dismissed: Node: {0}, Race not started' . format ( node . index + 1 ) ) else : logger . debug ( 'Pass record dismissed: Node: {0}, Pilot not defined' . format ( node . index + 1 ) ) else : logger . debug ( 'Pass record dismissed: Node: {0}, Frequency not defined' . format ( node . index + 1 ) )
Handles pass records from the nodes.
Handles pass records from the nodes .
'''Handles pass records from the nodes.''' # clear the "synchronized" version of the crossing flag # For updated triggers and peaks # always count laps if race is running, otherwise test if lap should have counted before race end (RACE.duration_ms is invalid while race is in progress) # Get the current pilot id on the node # reject passes before race start and with disabled (no-pilot) nodes # store as milliseconds # This is a normal completed lap # Find the time stamp of the last lap completed # New lap time is the difference between the current time stamp and the last # No previous laps, this is the first pass # Lap zero represents the time from the launch pad to flying through the gate # indicate first crossing completed # if initial lap then always accept and don't check lap time; else: # if lap time less than minimum # if behavior is 'Discard New Short Laps' # Add the new lap to the database #logger.info('Pass record: Node: {0}, Lap: {1}, Lap time: {2}' \ #    .format(node.index+1, lap_number, RHUtils.time_format(lap_time))) # update all laps on the race page # update leaderboard # team racing mode enabled # if win condition is first-to-x-laps and x is valid #  then check if a team has enough laps to win # send phonetic data to be spoken # if Most Laps Wins race is tied then check for winner # if a team has won the race and this is the winning lap # play first-pass sound # not team racing mode # send phonetic data to be spoken # if Most Laps Wins race is tied then check for winner # need to check if any pilot has enough laps to win # a pilot has won the race # a pilot has won the race and has not yet been announced # if no phonetic then use callsign # call out winner (once) # no pilot has won the race; send phonetic data to be spoken # other win conditions # play first-pass sound
node
lap_timestamp_absolute
source