def generate_competition_day(self, target_directory: str, download_progress=None, start_time_buffer: int=0, include_hc_competitors: bool = True) -> CompetitionDay: # get info from website competition_name, date, plane_class = self._get_competition_day_info() competitors_info = self._get_competitors_info(include_hc_competitors) self.set_igc_directory(target_directory, competition_name, plane_class, date) competitors = list() tasks = list() files_downloaded = 0 for competitor_info in competitors_info: competition_id = competitor_info['competition_id'] igc_url = competitor_info['igc_url'] ranking = competitor_info['ranking'] # download files. skip if not valid try: file_path = self.download_flight(igc_url, competition_id) except URLError: print('{} is skipped because of invalid URL'.format(competition_id)) continue files_downloaded += 1 if download_progress is not None: download_progress(files_downloaded, len(competitors_info)) try: try: # try utf-8 with open(file_path, 'r', encoding='utf-8') as f: parsed_igc_file = Reader().read(f) except UnicodeDecodeError: # if not utf-8 use latin1 with open(file_path, 'r', encoding='latin1') as f: parsed_igc_file = Reader().read(f) except Exception: print('{} is skipped because the file could not be parsed'.format(competition_id)) continue trace_errors, trace = parsed_igc_file['fix_records'] if len(trace_errors) != 0: print('{} is skipped because of invalid trace'.format(competition_id)) continue # get info from file task, contest_information, competitor_information = get_info_from_comment_lines(parsed_igc_file, start_time_buffer) plane_model = competitor_information.get('plane_model', None) pilot_name = competitor_information.get('pilot_name', None) competitor = Competitor(trace, competition_id, plane_model, ranking, pilot_name) competitors.append(competitor) tasks.append(task) # Select task from tasks list task = self._select_task(tasks) return CompetitionDay(competition_name, date, plane_class, competitors, task)
def get_trace(igc_path): with open(igc_path, 'r') as f: parsed_igc_file = Reader().read(f) _, trace = parsed_igc_file['fix_records'] return trace
def get_task(igc_path): with open(igc_path, 'r') as f: parsed_igc_file = Reader().read(f) task, contest_information, competitor_information = get_info_from_comment_lines( parsed_igc_file) return task
def generate_competition_day(self, target_directory: str, download_progress=None, start_time_buffer: int=0)\ -> CompetitionDay: """ :param target_directory: see super :param download_progress: see super :param start_time_buffer: see super :return: """ # get info from website competition_name, date, plane_class = self._get_competition_day_info() table_info = self._get_table_info() self.set_igc_directory(target_directory, competition_name, plane_class, date) competitors = list() tasks = list() files_downloaded = 0 for table_entry in table_info: competition_id = table_entry['competition_id'] igc_url = table_entry['igc_url'] plane_model = table_entry['ranking'] ranking = table_entry['plane_model'] # download files file_path = self.download_flight(igc_url, competition_id) files_downloaded += 1 if download_progress is not None: download_progress(files_downloaded, len(table_info)) with open(file_path, 'r', encoding='utf-8') as f: parsed_igc_file = Reader().read(f) trace_errors, trace = parsed_igc_file['fix_records'] # get info from file task, task_info, competitor_information = get_info_from_comment_lines( parsed_igc_file, start_time_buffer) pilot_name = competitor_information.get('pilot_name', None) competitor = Competitor(trace, competition_id, plane_model, ranking, pilot_name) competitors.append(competitor) tasks.append(task) # Select task from tasks list task = self._select_task(tasks) return CompetitionDay(competition_name, date, plane_class, competitors, task)
def generate_competition_day(self, target_directory: str, download_progress=None, start_time_buffer: int=0) -> CompetitionDay: """ Generate a CompetitionDay for the specified SoaringSpot daily result page. Information is pulled from the overview table and from the igc files, which are automatically downloaded. :param target_directory: see super :param download_progress: see super :param start_time_buffer: see super :return: """ # get info from website competition_name, date, plane_class = self._get_competition_day_info() competitors_info = self._get_competitors_info() self.set_igc_directory(target_directory, competition_name, plane_class, date) competitors = list() tasks = list() files_downloaded = 0 for competitor_info in competitors_info: competition_id = competitor_info['competition_id'] igc_url = competitor_info['igc_url'] ranking = competitor_info['ranking'] # download files file_path = self.download_flight(igc_url, competition_id) files_downloaded += 1 if download_progress is not None: download_progress(files_downloaded, len(competitors_info)) with open(file_path, 'r', encoding='utf-8') as f: parsed_igc_file = Reader().read(f) trace_errors, trace = parsed_igc_file['fix_records'] # get info from file task, contest_information, competitor_information = get_info_from_comment_lines(parsed_igc_file, start_time_buffer) plane_model = competitor_information.get('plane_model', None) pilot_name = competitor_information.get('pilot_name', None) competitor = Competitor(trace, competition_id, plane_model, ranking, pilot_name) competitors.append(competitor) tasks.append(task) # Select task from tasks list task = self._select_task(tasks) return CompetitionDay(competition_name, date, plane_class, competitors, task)
def test_aat_from_file(self): """ Test if aat is correctly recognised and waypoint are correct file from: https://www.strepla.de/scs/Public/scoreDay.aspx?cId=451&idDay=7912, competitor 1 CX """ file_path = os.path.join(os.path.dirname(__file__), '..', 'igc_files', 'aat_strepla.igc') with open(file_path, 'r', encoding='utf-8') as f: parsed_igc_file = Reader().read(f) trace_errors, trace = parsed_igc_file['fix_records'] self.assertEqual(len(trace_errors), 0) task, _, _ = get_info_from_comment_lines(parsed_igc_file) self.assertIsInstance(task, AAT) self.assertEqual(task.t_min, datetime.timedelta(hours=2, minutes=30)) expected_waypoints = [ ('AP3 Muellhalde', None), ('Loreley', 20000), ('Kusel', 40000), ('Loreley', 20000), ('ZP Anspach/Taunus', None), ] self.assertEqual(len(task.waypoints), len(expected_waypoints)) for i, waypoint in enumerate(task.waypoints): expected_name, expected_r_max = expected_waypoints[i] self.assertEqual(waypoint.name, expected_name) if 0 < i < len(expected_waypoints) - 1: self.assertEqual(waypoint.r_max, expected_r_max) competitor = Competitor(trace, 'CX', 'Discus2b', 1, 'Karsten Leucker') competitor.analyse(task, 'pysoar') time_diff = seconds_time_difference(competitor.trip.refined_start_time, datetime.time(13, 22, 40)) dist_diff = sum(competitor.trip.distances) - 283500 self.assertLessEqual(abs(time_diff), 1) self.assertEqual(len(competitor.trip.fixes), len(expected_waypoints)) self.assertLessEqual(abs(dist_diff), 1000)
def read_igc(filename): igc_reader = Reader() with open(filename, "r") as f: return igc_reader.read(f)
def index(): if request.method == 'POST': # check if the post request has the file part if 'file' not in request.files: flash('No file part') #return 'No file part' return redirect(url_for('index')) file = request.files['file'] # if user does not select file, browser also # submit an empty part without filename if file.filename == '': flash('No IGC file selected') #return 'No selected file' return redirect(url_for('index')) if file and allowed_file(file.filename): filename = secure_filename(file.filename) save_file = os.path.join(app.config['UPLOAD_FOLDER'], filename) file.save(save_file) #check for task file if 'task' in request.files: task = request.files['task'] if task and allowed_file(task.filename): taskname = secure_filename(task.filename) save_task = os.path.join(app.config['UPLOAD_FOLDER'], taskname) task.save(save_task) flash( 'File IGC & TASK have been uploaded: Save this URL to see the result directly (inlcuding parameters)' ) return redirect( url_for('index', filename=filename, taskname=taskname)) else: flash('File IGC has been uploaded') return redirect(url_for('index', filename=filename)) if request.method == 'GET': if request.args.get('filename'): file_to_open = os.path.join(app.config['UPLOAD_FOLDER'], request.args.get('filename')) if os.path.exists(file_to_open): flight_results = "" #check for task parameter and load task data task_filedata = False task_to_open = os.path.join(app.config['UPLOAD_FOLDER'], request.args.get('taskname')) if os.path.exists(task_to_open): with open(task_to_open) as task_file: task_filedata = json.load(task_file) if IGC_LIB == 'igc_lib': flight = Flight.create_from_file(file_to_open) if not flight.valid: flight_results += "Provided flight is invalid:\n" + str( flight.notes) + '\n' else: flight_results = extract_flight_details(flight) layer = {} layer['geojson'], layer['bbox'] = dump_flight( flight, file_to_open) make_map(layer_geojson=layer) return render_template('home.html', flight_data=flight_results, igc_content='') else: with open(file_to_open, 'r') as f: parsed_igc_file = Reader().read(f) flight_results += '<div class="btn btn-light" disabled>Your Track (IGC) data:</div>' task, task_coords = get_task(parsed_igc_file['task']) layer = {} geojson_file = "%s-flight.geojson" % os.path.splitext( file_to_open)[0] layer['geojson'] = geojson_file layer['bbox'] = get_track(parsed_igc_file['fix_records'], geojson_file) if task: flight_results += str(task) turnpoints = False if task_filedata: flight_results += '<div class="btn btn-light" disabled>Complete Task file data:</div>' task_html, turnpoints = get_task_fromfile( task_filedata) flight_results += str(task_html) igc_object = '<code>' + str(parsed_igc_file) + '</code>' make_map(layer_geojson=layer, points=task_coords, circles=turnpoints) #testing connection to DB # q = "SELECT * FROM TaskView LIMIT 1" with db_session() as db: t = db.query(T).first() # t = db.fetchall(q) # return render_template('home.html',flight_data=flight_results, igc_content=igc_object, mysql_query=t ) return render_template('home.html', flight_data=flight_results, igc_content=igc_object) else: flash('Missing file, please upload it first.') return render_template('home.html', flight_data='', igc_content='') else: make_map() return render_template('home.html', flight_data='', igc_content='')