예제 #1
0
def get_download_status(task_id: int):
    from db.tables import TblParticipant as P, TblTaskResult as R, TblTask as T
    from calcUtils import sec_to_time
    valid = []
    missing = []
    with db_session() as db:
        results = db.query(P.ID, P.name, R.result_type, R.distance_flown, R.SSS_time, R.ESS_time, R.goal_time) \
                    .join(T, P.comp_id == T.comp_id) \
                    .outerjoin(R, (R.par_id == P.par_id) & (R.task_id == T.task_id)) \
                    .filter(T.task_id == task_id).all()
        pilots = len(results)
        valid_results = [p for p in results if p.result_type not in ('abs', 'dnf', 'mindist', None)]
        for pilot in results:
            data = {'ID': pilot.ID, 'name': pilot.name}
            if pilot in valid_results:
                if pilot.ESS_time:
                    time = sec_to_time(pilot.ESS_time - pilot.SSS_time)
                    if pilot.result_type == 'goal':
                        result = f'GOAL {time}'
                    else:
                        result = f"ESS {c_round(pilot.distance_flown / 1000, 2)} Km (~{time}~)"
                else:
                    result = f"LO {c_round(pilot.distance_flown / 1000, 2)} Km"
                data['result'] = result
                valid.append(data)
            elif not pilot.result_type:
                missing.append(data)
    return pilots, valid, missing
예제 #2
0
def process_igc(task_id: int, par_id: int, tracklog):
    from pilot.track import create_igc_filename, igc_parsing_config_from_yaml
    from calcUtils import epoch_to_date
    from airspace import AirspaceCheck
    from igc_lib import Flight
    from task import Task
    from pilot.flightresult import FlightResult, save_track

    pilot = FlightResult.read(par_id, task_id)
    if pilot.name:
        task = Task.read(task_id)
        fullname = create_igc_filename(task.file_path, task.date, pilot.name)
        tracklog.save(fullname)
        pilot.track_file = Path(fullname).name
    else:
        return None, None
    """import track"""
    # track = Track(track_file=fullname, par_id=pilot.par_id)
    FlightParsingConfig = igc_parsing_config_from_yaml(task.igc_config_file)
    flight = Flight.create_from_file(fullname,
                                     config_class=FlightParsingConfig)
    """check result"""
    if not flight:
        error = f"for {pilot.name} - Track is not a valid track file"
        return None, error
    elif not epoch_to_date(flight.date_timestamp) == task.date:
        error = f"for {pilot.name} - Track has a different date from task date"
        return None, error
    else:
        print(
            f"pilot {pilot.par_id} associated with track {pilot.track_file} \n"
        )
        """checking track against task"""
        if task.airspace_check:
            airspace = AirspaceCheck.from_task(task)
        else:
            airspace = None
        pilot.check_flight(flight, task, airspace_obj=airspace)
        print(f"track verified with task {task.task_id}\n")
        '''create map file'''
        pilot.save_tracklog_map_file(task, flight)
        """adding track to db"""
        # pilot.to_db()
        save_track(pilot, task.id)
        time = ''
        data = {'par_id': pilot.par_id, 'track_id': pilot.track_id}
        if pilot.goal_time:
            time = sec_to_time(pilot.ss_time)
        if pilot.result_type == 'goal':
            data['Result'] = f'Goal {time}'
        elif pilot.result_type == 'lo':
            data['Result'] = f"LO {round(pilot.distance / 1000, 2)}"
        if pilot.track_id:  # if there is a track, make the result a link to the map
            # trackid = data['track_id']
            parid = data['par_id']
            result = data['Result']
            data[
                'Result'] = f'<a href="/map/{parid}-{task.task_id}">{result}</a>'
    return data, None
예제 #3
0
def update_livetrack_file(result: FlightResult, flight: list, path: str):
    """ IGC Fix Format:
        B1132494613837N01248410EA0006900991
    """
    from calcUtils import sec_to_time, igc_coords
    file = Path(path, result.track_file)
    if file.is_file():
        '''create fixes lines'''
        lines = ''
        for fix in flight:
            fixtime = sec_to_time(fix.rawtime).strftime("%H%M%S")
            lat, lon = igc_coords(fix.lat, fix.lon)
            baro_alt = str(int(fix.press_alt)).zfill(5)
            gnss_alt = str(int(fix.gnss_alt)).zfill(5)
            lines += f"B{fixtime}{lat}{lon}A{baro_alt}{gnss_alt}\n"
        '''append lines'''
        f = open(file, "a+")
        f.write(lines)
        f.close()
예제 #4
0
def get_pilot_list_for_track_management(taskid: int):
    from db.tables import TblTaskResult as R, TblParticipant as P, TblTask as T
    with db_session() as db:
        results = db.query(R.goal_time, R.track_file, R.track_id,
                           R.result_type, R.distance_flown, R.ESS_time,
                           R.SSS_time,
                           R.par_id).filter(R.task_id == taskid).subquery()
        pilots = db.query(T.task_id, P.name, P.ID, P.par_id, results.c.track_id, results.c.SSS_time,
                          results.c.ESS_time,
                          results.c.distance_flown, results.c.track_file, results.c.result_type) \
            .outerjoin(P, T.comp_id == P.comp_id).filter(T.task_id == taskid) \
            .outerjoin(results, results.c.par_id == P.par_id).all()

        if pilots:
            pilots = [row._asdict() for row in pilots]

    all_data = []
    for pilot in pilots:
        data = {
            'ID': pilot['ID'],
            'name': pilot['name'],
            'par_id': pilot['par_id'],
            'track_id': pilot['track_id']
        }
        if pilot['track_file']:
            parid = data['par_id']
            if pilot['ESS_time']:
                time = sec_to_time(pilot['ESS_time'] - pilot['SSS_time'])
                if pilot['result_type'] == 'goal':
                    result = f'Goal {time}'
                else:
                    result = f"ESS {round(pilot['distance_flown'] / 1000, 2)} Km (<del>{time}</del>)"
            else:
                result = f"LO {round(pilot['distance_flown'] / 1000, 2)} Km"
            data['Result'] = f'<a href="/map/{parid}-{taskid}">{result}</a>'
        elif pilot['result_type'] == "mindist":
            data['Result'] = "Min Dist"
        else:
            data['Result'] = "Not Yet Processed" if not pilot[
                'track_id'] else pilot['result_type'].upper()
        all_data.append(data)
    return all_data
예제 #5
0
    def to_file(self):
        """ returns:
            - filename: STR
            - fsdb:     FSDB xml data, to be used in frontend."""

        formula = self.comp.formula
        pilots = self.comp.participants
        '''create dicts of attributes for each section'''
        comp_attr = {
            'id':
            '',  # still to do
            'name':
            self.comp.comp_name,
            'location':
            self.comp.comp_site,
            'from':
            self.comp.date_from,
            'to':
            self.comp.date_to,
            'utc_offset':
            self.comp.time_offset / 3600,
            'discipline':
            self.comp.comp_class.lower(),
            'ftv_factor':
            round(1 - formula.validity_param, 2),
            'fai_sanctioning': (1 if self.comp.sanction == 'FAI 1' else
                                2 if self.comp.sanction == 'FAI 2' else 0)
        }

        formula_attr = {
            'id':
            formula.formula_name,
            'min_dist':
            km(formula.min_dist, 1),
            'nom_dist':
            km(formula.nominal_dist, 1),
            'nom_time':
            formula.nominal_time / 3600,
            'nom_launch':
            formula.nominal_launch,
            'nom_goal':
            formula.nominal_goal,
            'day_quality_override':
            0,  # still to implement
            'bonus_gr':
            formula.glide_bonus,
            'jump_the_gun_factor': (0 if formula.max_JTG == 0 else round(
                1 / formula.JTG_penalty_per_sec, 1)),
            'jump_the_gun_max':
            formula.max_JTG,
            'normalize_1000_before_day_quality':
            0,  # still to implement
            'time_points_if_not_in_goal':
            round(1 - formula.no_goal_penalty, 1),
            'use_1000_points_for_max_day_quality':
            0,  # still to implement
            'use_arrival_position_points':
            1 if formula.formula_arrival == 'position' else 0,
            'use_arrival_time_points':
            1 if formula.formula_arrival == 'time' else 0,
            'use_departure_points':
            1 if formula.formula_departure == 'departure' else 0,
            'use_difficulty_for_distance_points':
            1 if formula.formula_distance == 'difficulty' else 0,
            'use_distance_points':
            1 if formula.formula_distance != 'off' else 0,
            'use_distance_squared_for_LC':
            1 if formula.comp_class == 'PG' else 0,  # still to implement
            'use_leading_points':
            1 if formula.formula_departure == 'leadout' else 0,
            'use_semi_circle_control_zone_for_goal_line':
            1,  # still to implement
            'use_time_points':
            1 if formula.formula_time == 'on' else 0,
            'scoring_altitude':
            'GPS' if formula.scoring_altitude == 'GPS' else 'QNH',
            'final_glide_decelerator':
            'none' if formula.arr_alt_bonus == 0 else 'aatb',
            'no_final_glide_decelerator_reason':
            '',
            'min_time_span_for_valid_task':
            60 if self.comp_class == 'PG' else 0,  # still to implement
            'score_back_time':
            formula.score_back_time / 60,
            'use_proportional_leading_weight_if_nobody_in_goal':
            '',  # still to implement
            'leading_weight_factor':
            (0 if formula.formula_departure != 'leadout' else round(
                formula.lead_factor, 3)),
            'turnpoint_radius_tolerance':
            formula.tolerance,
            'use_arrival_altitude_points':
            0 if formula.arr_alt_bonus == 0 else ''  # still to implement
        }
        if formula.arr_alt_bonus > 0:
            formula_attr['aatb_factor'] = round(formula.arr_alt_bonus, 3)
        '''create the file structure'''
        root = ET.Element('Fs')
        root.set('version', '3.5')
        root.set('comment', 'generated by AirScore')
        '''FsCompetition'''
        comp = ET.SubElement(root, 'FsCompetition')
        for k, v in comp_attr.items():
            comp.set(k, str(v))

        formula = ET.SubElement(comp, 'FsScoreFormula')
        for k, v in formula_attr.items():
            formula.set(k, str(v))

        notes = ET.SubElement(comp, 'FsCompetitionNotes')
        notes.text = CDATA('Generated by AirScore')
        # notes.text = '<![CDATA[Generated by AirScore]]>'
        '''FsParticipants'''
        participants = ET.SubElement(comp, 'FsParticipants')
        for p in pilots:
            pil = ET.SubElement(participants, 'FsParticipant')
            pilot_attr = {
                'id': p.ID or p.par_id,
                'name': p.name,
                'birthday': p.pilot_birthdate_str,
                'glider': p.glider,
                'glider_main_colors': '',
                'fai_licence': 1 if p.fai_id else 0,
                'female': p.female,
                'nat_code_3166_a3': p.nat,
                'sponsor': p.sponsor,
                'CIVLID': p.civl_id,
            }
            custom_attr = {
                'fai_n': p.fai_id,
                'class': p.glider_cert,
                'team': p.team,
                'LIVE': p.live_id
            }

            for k, v in pilot_attr.items():
                pil.set(k, str(v))
            cus = ET.SubElement(pil, 'FsCustomAttributes')
            for k, v in custom_attr.items():
                sub = ET.SubElement(cus, 'FsCustomAttribute')
                sub.set('name', k)
                sub.set('value', str(v))
        '''FsTasks'''
        tasks = ET.SubElement(comp, 'FsTasks')
        for idx, t in enumerate(self.tasks):
            task = ET.SubElement(tasks, 'FsTask')
            task.set('id', str(idx + 1))
            task.set('name', t.task_name)
            task.set('tracklog_folder', '')

            task_f = ET.SubElement(task, 'FsScoreFormula')
            task_d = ET.SubElement(task, 'FsTaskDefinition')
            task_s = ET.SubElement(task, 'FsTaskState')
            task_p = ET.SubElement(task, 'FsParticipants')
            task_sp = ET.SubElement(task, 'FsTaskScoreParams')

            # tf = dict(t.formula.to_dict(), **t.stats)
            '''FsTaskState'''
            task_s.set('task_state',
                       ('REGULAR' if not t.stopped_time else 'STOPPED'))  # ?
            task_s.set('score_back_time', str(t.formula.score_back_time / 60))
            task_s.set('cancel_reason', t.comment)
            '''FsScoreFormula'''
            # we permit just few changes in single tasks from comp formula, so we just update those
            tf_attr = formula_attr
            tf_attr.update({
                'jump_the_gun_factor':
                (0 if not t.formula.JTG_penalty_per_sec else round(
                    1 / t.formula.JTG_penalty_per_sec, 1)),
                'time_points_if_not_in_goal':
                1 - t.formula.no_goal_penalty,
                'use_arrival_position_points':
                1 if t.formula.arrival == 'position' else 0,
                'use_arrival_time_points':
                1 if t.formula.arrival == 'time' else 0,
                'use_departure_points':
                1 if t.formula.departure == 'departure' else 0,
                'use_difficulty_for_distance_points':
                1 if t.formula.distance == 'difficulty' else 0,
                'use_distance_points':
                0 if t.formula.distance == 'off' else 1,
                'use_leading_points':
                0 if t.formula.departure == 'off' else 1,
                'use_time_points':
                0 if t.formula.time == 'off' else 1,
                'scoring_altitude':
                'GPS' if t.formula.scoring_altitude == 'GPS' else 'QNH',
                'final_glide_decelerator':
                'none' if t.formula.arr_alt_bonus == 0 else 'aatb',
                'use_arrival_altitude_points':
                0 if t.formula.arr_alt_bonus == 0 else 1,
                'turnpoint_radius_tolerance':
                t.formula.tolerance,
            })

            for k, v in tf_attr.items():
                task_f.set(k, str(v))
            '''FsTaskDefinition'''
            tps = t.turnpoints
            td_attr = {
                'ss':
                [i + 1 for i, tp in enumerate(tps)
                 if tp.type == 'speed'].pop(0),
                'es':
                [i + 1 for i, tp in enumerate(tps)
                 if tp.type == 'endspeed'].pop(0),
                'goal':
                next(tp.shape for tp in tps if tp.type == 'goal').upper(),
                'groundstart':
                0,  # still to implement
                'qnh_setting':
                1013.25  # still to implement
            }

            for k, v in td_attr.items():
                task_d.set(k, str(v))

            t_open = get_isotime(t.date, t.window_open_time, t.time_offset)
            t_close = get_isotime(t.date, t.task_deadline, t.time_offset)
            ss_open = get_isotime(t.date, t.start_time, t.time_offset)
            if t.start_close_time:
                ss_close = get_isotime(t.date, t.start_close_time,
                                       t.time_offset)
            else:
                ss_close = t_close
            if t.window_close_time:
                w_close = get_isotime(t.date, t.window_close_time,
                                      t.time_offset)
            else:
                w_close = ss_close

            for i, tp in enumerate(tps):
                task_tp = ET.SubElement(task_d, 'FsTurnpoint')
                tp_attr = {
                    'id':
                    tp.name,
                    'lat':
                    round(tp.lat, 5),
                    'lon':
                    round(tp.lon, 5),
                    'altitude':
                    tp.altitude,
                    'radius':
                    tp.radius,
                    'open':
                    t_open if i < (td_attr['ss'] - 1) else ss_open,
                    'close':
                    w_close if i == 0 else ss_close if i == (td_attr['ss'] -
                                                             1) else t_close
                }
                for k, v in tp_attr.items():
                    task_tp.set(k, str(v))
                '''we add also FsTaskDistToTp during tp iteration'''
                sp_dist = ET.SubElement(task_sp, 'FsTaskDistToTp')
                sp_dist.set('tp_no', str(i + 1))
                sp_dist.set('distance', str(t.partial_distance[i]))
            '''add start gates'''
            gates = 1
            if t.SS_interval > 0:
                gates += t.start_iteration
            for i in range(gates):
                task_sg = ET.SubElement(task_d, 'FsStartGate')
                intv = 0 if not t.SS_interval else t.SS_interval * i
                i_time = get_isotime(t.date, (t.start_time + intv),
                                     t.time_offset)
                task_sg.set('open', str(i_time))
            '''FsTaskScoreParams'''
            launch_ess = [
                t.partial_distance[i] for i, tp in enumerate(t.turnpoints)
                if tp.type == 'endspeed'
            ].pop()
            sp_attr = {
                'ss_distance':
                km(t.SS_distance),
                'task_distance':
                km(t.opt_dist),
                'launch_to_ess_distance':
                km(launch_ess),
                'no_of_pilots_present':
                t.pilots_present,
                'no_of_pilots_flying':
                t.pilots_launched,
                'no_of_pilots_lo':
                t.pilots_launched - t.pilots_goal,
                'no_of_pilots_reaching_nom_dist':
                len([
                    x for x in t.valid_results
                    if x.distance_flown > t.formula.nominal_dist
                ]),
                'no_of_pilots_reaching_es':
                t.pilots_ess,
                'no_of_pilots_reaching_goal':
                t.pilots_goal,
                'sum_flown_distance':
                km(t.tot_distance_flown),
                'best_dist':
                km(t.max_distance or 0),
                'best_time':
                round((t.fastest or 0) / 3600, 14),
                'worst_time':
                round(
                    max((x.ESS_time or 0) - (x.SSS_time or 0)
                        for x in t.valid_results) / 3600, 14),
                'no_of_pilots_in_competition':
                len(self.comp.participants),
                'no_of_pilots_landed_before_stop':
                0 if not t.stopped_time else t.pilots_landed,
                'sum_dist_over_min':
                km(t.tot_dist_over_min),
                'sum_real_dist_over_min':
                km(t.tot_dist_over_min),  # not yet implemented
                'best_real_dist':
                km(t.max_distance),  # not yet implemented
                'last_start_time':
                get_isotime(
                    t.date,
                    max([
                        x.SSS_time for x in t.valid_results
                        if x.SSS_time is not None
                    ]), t.time_offset),
                'first_start_time':
                ('' if not t.min_dept_time else get_isotime(
                    t.date, t.min_dept_time, t.time_offset)),
                'first_finish_time':
                ('' if not t.min_ess_time else get_isotime(
                    t.date, t.min_ess_time, t.time_offset)),
                'max_time_to_get_time_points':
                round(0 / 3600, 14),  # not yet implemented
                'no_of_pilots_with_time_points':
                len([x for x in t.valid_results if x.time_score > 0]),
                'goal_ratio': (0 if t.pilots_launched == 0 else round(
                    t.pilots_goal / t.pilots_launched, 15)),
                'arrival_weight':
                0 if t.arrival == 0 else round(t.arr_weight, 3),
                'departure_weight':
                0 if t.departure != 'on' else round(t.dep_weight, 3),
                'leading_weight':
                0 if t.departure != 'leadout' else round(t.dep_weight, 3),
                'time_weight':
                0 if t.arrival == 'off' else round(t.time_weight, 3),
                'distance_weight':
                round(t.dist_weight, 3),  # not yet implemented
                'smallest_leading_coefficient':
                round(t.min_lead_coeff, 14),
                'available_points_distance':
                round(t.avail_dist_points, 14),
                'available_points_time':
                round(t.avail_time_points, 14),
                'available_points_departure':
                (0 if not t.formula.departure == 'departure' else round(
                    t.avail_dep_points, 14)),
                'available_points_leading':
                (0 if not t.formula.departure == 'leadout' else round(
                    t.avail_dep_points, 14)),
                'available_points_arrival':
                round(t.avail_arr_points, 14),
                'time_validity':
                round(t.time_validity, 3),
                'launch_validity':
                round(t.launch_validity, 3),
                'distance_validity':
                round(t.dist_validity, 3),
                'stop_validity':
                round(t.stop_validity, 3),
                'day_quality':
                round(t.day_quality, 3),
                'ftv_day_validity':
                t.ftv_validity,
                'time_points_stop_correction':
                0  # not yet implemented
            }
            for k, v in sp_attr.items():
                task_sp.set(k, str(v))
            '''FsParticipants'''
            for i, pil in enumerate(t.pilots):
                '''create pilot result for the task'''
                pil_p = ET.SubElement(task_p, 'FsParticipant')
                pil_p.set('id', str(pil.ID or pil.par_id))
                if not (pil.result_type in ('abs', 'dnf', 'nyp')):
                    '''only if pilot flew'''
                    pil_fd = ET.SubElement(pil_p, 'FsFlightData')
                    pil_r = ET.SubElement(pil_p, 'FsResult')
                    if not (pil.result_type in ['mindist', 'min_dist']):
                        fd_attr = {
                            'distance':
                            km(pil.distance_flown),
                            'bonus_distance':
                            km(pil.distance),
                            # ?? seems 0 for PG and more than dist for HG
                            'started_ss':
                            '' if not pil.real_start_time else get_isotime(
                                t.date, pil.real_start_time, t.time_offset),
                            'finished_ss':
                            '' if not pil.ESS_time else get_isotime(
                                t.date, pil.ESS_time, t.time_offset),
                            'altitude_at_ess':
                            pil.ESS_altitude,
                            'finished_task':
                            '' if not pil.goal_time else get_isotime(
                                t.date, pil.goal_time, t.time_offset),
                            'tracklog_filename':
                            pil.track_file,
                            'lc':
                            pil.lead_coeff,
                            'iv':
                            pil.fixed_LC or '',
                            'ts':
                            get_isotime(t.date, pil.first_time, t.time_offset),
                            'alt':
                            pil.last_altitude,  # ??
                            'bonus_alt':
                            '',  # ?? not implemented
                            'max_alt':
                            pil.max_altitude,
                            'last_tracklog_point_distance':
                            '',  # not implemented yet
                            'bonus_last_tracklog_point_distance':
                            '',  # ?? not implemented
                            'last_tracklog_point_time':
                            get_isotime(t.date, pil.landing_time,
                                        t.time_offset),
                            'last_tracklog_point_alt':
                            pil.landing_altitude,
                            'landed_before_deadline':
                            '1' if pil.landing_time <
                            (t.task_deadline if not t.stopped_time else
                             t.stopped_time) else '0',
                            'reachedGoal':
                            1 if pil.goal_time else 0
                            # only deadline?
                        }
                        for k, v in fd_attr.items():
                            pil_fd.set(k, str(v))

                    r_attr = {
                        'rank':
                        i + 1,  # not implemented, they should be ordered tho
                        # Rank IS NOT SAFE (I guess)
                        'points':
                        round(pil.score),
                        'distance':
                        km(pil.total_distance if pil.total_distance else pil.
                           distance_flown),
                        'ss_time':
                        '' if not pil.ss_time else sec_to_time(
                            pil.ss_time).strftime('%H:%M:%S'),
                        'finished_ss_rank':
                        ''
                        if not pil.ESS_time and pil.ESS_rank else pil.ESS_rank,
                        'distance_points':
                        0 if not pil.distance_score else round(
                            pil.distance_score, 1),
                        'time_points':
                        0 if not pil.time_score else round(pil.time_score, 1),
                        'arrival_points':
                        0 if not pil.arrival_score else round(
                            pil.arrival_score, 1),
                        'departure_points':
                        0 if not t.formula.departure == 'departure' else round(
                            pil.departure_score, 1),
                        'leading_points':
                        0 if not t.formula.departure == 'leadout' else round(
                            pil.departure_score, 1),
                        'penalty':
                        0 if not [
                            n for n in pil.notifications
                            if n.percentage_penalty > 0
                        ] else max(n.percentage_penalty
                                   for n in pil.notifications),
                        'penalty_points':
                        0 if not [
                            n for n in pil.notifications if n.flat_penalty > 0
                        ] else max(n.flat_penalty for n in pil.notifications),
                        'penalty_reason':
                        '; '.join([
                            n.comment for n in pil.notifications
                            if n.flat_penalty + n.percentage_penalty > 0
                            and not n.notification_type == 'jtg'
                        ]),
                        'penalty_points_auto':
                        sum(n.flat_penalty for n in pil.notifications
                            if n.notification_type == 'jtg'),
                        'penalty_reason_auto':
                        '' if not [
                            n for n in pil.notifications
                            if n.notification_type == 'jtg'
                        ] else next(
                            n for n in pil.notifications
                            if n.notification_type == 'jtg').flat_penalty,
                        'penalty_min_dist_points':
                        0,  # ??
                        'got_time_but_not_goal_penalty':
                        (pil.ESS_time or 0) > 0 and not pil.goal_time,
                        'started_ss':
                        '' if not pil.real_start_time else get_isotime(
                            t.date, pil.SSS_time, t.time_offset),
                        'finished_ss':
                        '' if not pil.ESS_time else get_isotime(
                            t.date, pil.ESS_time, t.time_offset),
                        'ss_time_dec_hours':
                        0 if not pil.ESS_time else round(
                            pil.ss_time / 3600, 14),
                        'ts':
                        get_isotime(t.date, pil.first_time,
                                    t.time_offset),  # flight origin time
                        'real_distance':
                        km(pil.distance_flown),
                        'last_distance':
                        '',  # ?? last fix distance?
                        'last_altitude_above_goal':
                        pil.last_altitude,
                        'altitude_bonus_seconds':
                        0,  # not implemented
                        'altitude_bonus_time':
                        sec_to_time(0).strftime('%H:%M:%S'),  # not implemented
                        'altitude_at_ess':
                        pil.ESS_altitude,
                        'scored_ss_time':
                        ('' if not pil.ss_time else sec_to_time(
                            pil.ss_time).strftime('%H:%M:%S')),
                        'landed_before_stop':
                        t.stopped_time and res.landing_time < t.stopped_time
                    }

                    for k, v in r_attr.items():
                        pil_r.set(k, str(v))
        '''creates the file to store'''
        fsdb = ET.tostring(root,
                           pretty_print=True,
                           xml_declaration=True,
                           encoding='UTF-8')

        return self.filename, fsdb
예제 #6
0
def process_igc_background(task_id: int, par_id: int, file: Path, user: str):
    from pilot.track import igc_parsing_config_from_yaml
    from calcUtils import epoch_to_date
    from pilot.flightresult import FlightResult, save_track
    from airspace import AirspaceCheck
    from igc_lib import Flight
    from task import Task
    import json
    pilot = FlightResult.read(par_id, task_id)
    task = Task.read(task_id)
    print = partial(print_to_sse, id=par_id, channel=user)
    """import track"""
    # pilot.track = Track(track_file=filename, par_id=pilot.par_id)
    FlightParsingConfig = igc_parsing_config_from_yaml(task.igc_config_file)
    flight = Flight.create_from_file(file, config_class=FlightParsingConfig)
    data = {
        'par_id': pilot.par_id,
        'track_id': pilot.track_id,
        'Result': 'Not Yet Processed'
    }
    """check result"""
    if not flight:
        print(f"for {pilot.name} - Track is not a valid track file")
        print(json.dumps(data) + '|result')
        return None
    if not flight.valid:
        print(
            f'IGC does not meet quality standard set by igc parsing config. Notes:{pilot.flight.notes}'
        )
        print(json.dumps(data) + '|result')
        return None
    elif not epoch_to_date(flight.date_timestamp) == task.date:
        print(f"for {pilot.name} - Track has a different date from task date")
        print(json.dumps(data) + '|result')
        return None
    else:
        print(f"pilot {pilot.par_id} associated with track {file.name} \n")
        pilot.track_file = file.name
        """checking track against task"""
        if task.airspace_check:
            airspace = AirspaceCheck.from_task(task)
        else:
            airspace = None
        pilot.check_flight(flight, task, airspace_obj=airspace, print=print)
        print(f"track verified with task {task.task_id}\n")
        '''create map file'''
        pilot.save_tracklog_map_file(task, flight)
        """adding track to db"""
        # pilot.to_db()
        save_track(pilot, task.id)
        data['track_id'] = pilot.track_id
        time = ''

        if pilot.goal_time:
            time = sec_to_time(pilot.ESS_time - pilot.SSS_time)
        if pilot.result_type == 'goal':
            data['Result'] = f'Goal {time}'
        elif pilot.result_type == 'lo':
            data['Result'] = f"LO {round(pilot.distance / 1000, 2)}"
        if pilot.track_id:  # if there is a track, make the result a link to the map
            # trackid = data['track_id']
            parid = data['par_id']
            result = data['Result']
            data[
                'Result'] = f'<a href="/map/{parid}-{task.task_id}">{result}</a>'
        print(data['Result'])
        print(json.dumps(data) + '|result')
        print('***************END****************')
    return None