def get(self): log_id = self.get_argument('log') if not validate_log_id(log_id): raise tornado.web.HTTPError(400, 'Invalid Parameter') log_file_name = get_log_filename(log_id) download_type = self.get_argument('type', default='0') if not os.path.exists(log_file_name): raise tornado.web.HTTPError(404, 'Log not found') if download_type == '1': # download the parameters ulog = load_ulog_file(log_file_name) param_keys = sorted(ulog.initial_parameters.keys()) self.set_header("Content-Type", "text/plain") self.set_header('Content-Disposition', 'inline; filename=params.txt') delimiter = ', ' for param_key in param_keys: self.write(param_key) self.write(delimiter) self.write(str(ulog.initial_parameters[param_key])) self.write('\n') elif download_type == '2': # download the kml file kml_path = get_kml_filepath() kml_file_name = os.path.join(kml_path, log_id.replace('/', '.') + '.kml') # check if chached file exists if not os.path.exists(kml_file_name): print('need to create kml file', kml_file_name) def kml_colors(flight_mode): """ flight mode colors for KML file """ if not flight_mode in flight_modes_table: flight_mode = 0 color_str = flight_modes_table[flight_mode][1][ 1:] # color in form 'ff00aa' # increase brightness to match colors with template rgb = [ int(color_str[2 * x:2 * x + 2], 16) for x in range(3) ] for i in range(3): rgb[i] += 40 if rgb[i] > 255: rgb[i] = 255 color_str = "".join(map(lambda x: format(x, '02x'), rgb)) return 'ff' + color_str[4:6] + color_str[2:4] + color_str[ 0:2] # KML uses aabbggrr style = {'line_width': 2} # create in random temporary file, then move it (to avoid races) try: temp_file_name = kml_file_name + '.' + str(uuid.uuid4()) convert_ulog2kml(log_file_name, temp_file_name, 'vehicle_global_position', kml_colors, style=style) shutil.move(temp_file_name, kml_file_name) except: print('Error creating KML file', sys.exc_info()[0], sys.exc_info()[1]) raise CustomHTTPError(400, 'No Position Data in log') # send the whole KML file self.set_header("Content-Type", "application/vnd.google-earth.kml+xml") self.set_header('Content-Disposition', 'attachment; filename=track.kml') with open(kml_file_name, 'rb') as kml_file: while True: data = kml_file.read(4096) if not data: break self.write(data) self.finish() elif download_type == '3': # download the non-default parameters ulog = load_ulog_file(log_file_name) param_keys = sorted(ulog.initial_parameters.keys()) self.set_header("Content-Type", "text/plain") self.set_header('Content-Disposition', 'inline; filename=params.txt') default_params = get_default_parameters() delimiter = ', ' for param_key in param_keys: try: param_value = str(ulog.initial_parameters[param_key]) is_default = False if param_key in default_params: default_param = default_params[param_key] if default_param['type'] == 'FLOAT': is_default = abs( float(default_param['default']) - float(param_value)) < 0.00001 else: is_default = int( default_param['default']) == int(param_value) if not is_default: self.write(param_key) self.write(delimiter) self.write(param_value) self.write('\n') except: pass else: # download the log file self.set_header('Content-Type', 'application/octet-stream') self.set_header("Content-Description", "File Transfer") self.set_header( 'Content-Disposition', 'attachment; filename={}'.format( os.path.basename(log_file_name))) with open(log_file_name, 'rb') as log_file: while True: data = log_file.read(4096) if not data: break self.write(data) self.finish()
def get(self, *args, **kwargs): """ GET request callback """ log_id = self.get_argument('log') if not validate_log_id(log_id): raise tornado.web.HTTPError(400, 'Invalid Parameter') log_file_name = get_log_filename(log_id) download_type = self.get_argument('type', default='0') if not os.path.exists(log_file_name): raise tornado.web.HTTPError(404, 'Log not found') def get_original_filename(default_value, new_file_suffix): """ get the uploaded file name & exchange the file extension """ try: con = sqlite3.connect(get_db_filename(), detect_types=sqlite3.PARSE_DECLTYPES) cur = con.cursor() cur.execute('select OriginalFilename ' 'from Logs where Id = ?', [log_id]) db_tuple = cur.fetchone() if db_tuple is not None: original_file_name = escape(db_tuple[0]) if original_file_name[-4:].lower() == '.ulg': original_file_name = original_file_name[:-4] return original_file_name + new_file_suffix cur.close() con.close() except: print("DB access failed:", sys.exc_info()[0], sys.exc_info()[1]) return default_value if download_type == '1': # download the parameters ulog = load_ulog_file(log_file_name) param_keys = sorted(ulog.initial_parameters.keys()) self.set_header("Content-Type", "text/plain") self.set_header('Content-Disposition', 'inline; filename=params.txt') delimiter = ', ' for param_key in param_keys: self.write(param_key) self.write(delimiter) self.write(str(ulog.initial_parameters[param_key])) self.write('\n') elif download_type == '2': # download the kml file kml_path = get_kml_filepath() kml_file_name = os.path.join(kml_path, log_id.replace('/', '.')+'.kml') # check if chached file exists if not os.path.exists(kml_file_name): print('need to create kml file', kml_file_name) def kml_colors(flight_mode): """ flight mode colors for KML file """ if not flight_mode in flight_modes_table: flight_mode = 0 color_str = flight_modes_table[flight_mode][1][1:] # color in form 'ff00aa' # increase brightness to match colors with template rgb = [int(color_str[2*x:2*x+2], 16) for x in range(3)] for i in range(3): rgb[i] += 40 if rgb[i] > 255: rgb[i] = 255 color_str = "".join(map(lambda x: format(x, '02x'), rgb)) return 'ff'+color_str[4:6]+color_str[2:4]+color_str[0:2] # KML uses aabbggrr style = {'line_width': 2} # create in random temporary file, then move it (to avoid races) try: temp_file_name = kml_file_name+'.'+str(uuid.uuid4()) convert_ulog2kml(log_file_name, temp_file_name, 'vehicle_global_position', kml_colors, style=style, camera_trigger_topic_name='camera_capture') shutil.move(temp_file_name, kml_file_name) except Exception as e: print('Error creating KML file', sys.exc_info()[0], sys.exc_info()[1]) raise CustomHTTPError(400, 'No Position Data in log') from e kml_dl_file_name = get_original_filename('track.kml', '.kml') # send the whole KML file self.set_header("Content-Type", "application/vnd.google-earth.kml+xml") self.set_header('Content-Disposition', 'attachment; filename='+kml_dl_file_name) with open(kml_file_name, 'rb') as kml_file: while True: data = kml_file.read(4096) if not data: break self.write(data) self.finish() elif download_type == '3': # download the non-default parameters ulog = load_ulog_file(log_file_name) param_keys = sorted(ulog.initial_parameters.keys()) self.set_header("Content-Type", "text/plain") self.set_header('Content-Disposition', 'inline; filename=params.txt') default_params = get_default_parameters() delimiter = ', ' for param_key in param_keys: try: param_value = str(ulog.initial_parameters[param_key]) is_default = False if param_key in default_params: default_param = default_params[param_key] if default_param['type'] == 'FLOAT': is_default = abs(float(default_param['default']) - float(param_value)) < 0.00001 else: is_default = int(default_param['default']) == int(param_value) if not is_default: self.write(param_key) self.write(delimiter) self.write(param_value) self.write('\n') except: pass else: # download the log file self.set_header('Content-Type', 'application/octet-stream') self.set_header("Content-Description", "File Transfer") self.set_header('Content-Disposition', 'attachment; filename={}'.format( os.path.basename(log_file_name))) with open(log_file_name, 'rb') as log_file: while True: data = log_file.read(4096) if not data: break self.write(data) self.finish()
def get_changed_parameters(ulog, plot_width): """ get a bokeh column object with a table of the changed parameters :param initial_parameters: ulog.initial_parameters """ param_names = [] param_values = [] param_defaults = [] param_mins = [] param_maxs = [] param_descriptions = [] param_colors = [] default_params = get_default_parameters() initial_parameters = ulog.initial_parameters system_defaults = None airframe_defaults = None if ulog.has_default_parameters: system_defaults = ulog.get_default_parameters(0) airframe_defaults = ulog.get_default_parameters(1) for param_name in sorted(initial_parameters): param_value = initial_parameters[param_name] if param_name.startswith('RC') or param_name.startswith('CAL_'): continue system_default = None airframe_default = None is_airframe_default = True if system_defaults is not None: system_default = system_defaults.get(param_name, param_value) if airframe_defaults is not None: airframe_default = airframe_defaults.get(param_name, param_value) is_airframe_default = abs( float(airframe_default) - float(param_value)) < 0.00001 try: if param_name in default_params: default_param = default_params[param_name] if system_default is None: system_default = default_param['default'] airframe_default = default_param['default'] if default_param['type'] == 'FLOAT': is_default = abs( float(system_default) - float(param_value)) < 0.00001 if 'decimal' in default_param: param_value = round(param_value, int(default_param['decimal'])) airframe_default = round(float(airframe_default), int(default_param['decimal'])) #pylint: disable=line-too-long else: is_default = int(system_default) == int(param_value) if not is_default: param_names.append(param_name) param_values.append(param_value) param_defaults.append(airframe_default) param_mins.append(default_param.get('min', '')) param_maxs.append(default_param.get('max', '')) param_descriptions.append( default_param.get('short_desc', '')) param_colors.append( 'black' if is_airframe_default else plot_color_red) else: # not found: add it as if it were changed param_names.append(param_name) param_values.append(param_value) param_defaults.append( airframe_default if airframe_default else '') param_mins.append('') param_maxs.append('') param_descriptions.append('(unknown)') param_colors.append( 'black' if is_airframe_default else plot_color_red) except Exception as error: print(type(error), error) param_data = dict(names=param_names, values=param_values, defaults=param_defaults, mins=param_mins, maxs=param_maxs, descriptions=param_descriptions, colors=param_colors) source = ColumnDataSource(param_data) formatter = HTMLTemplateFormatter( template='<font color="<%= colors %>"><%= value %></font>') columns = [ TableColumn(field="names", title="Name", width=int(plot_width * 0.2), sortable=False), TableColumn(field="values", title="Value", width=int(plot_width * 0.15), sortable=False, formatter=formatter), TableColumn(field="defaults", title="Frame Default" if airframe_defaults else "Default", width=int(plot_width * 0.1), sortable=False), TableColumn(field="mins", title="Min", width=int(plot_width * 0.075), sortable=False), TableColumn(field="maxs", title="Max", width=int(plot_width * 0.075), sortable=False), TableColumn(field="descriptions", title="Description", width=int(plot_width * 0.40), sortable=False), ] data_table = DataTable(source=source, columns=columns, width=plot_width, height=300, sortable=False, selectable=False, autosize_mode='none') div = Div( text= """<b>Non-default Parameters</b> (except RC and sensor calibration)""", width=int(plot_width / 2)) return column(div, data_table, width=plot_width)
def get_changed_parameters(initial_parameters, plot_width): """ get a bokeh widgetbox object with a table of the changed parameters :param initial_parameters: ulog.initial_parameters """ param_names = [] param_values = [] param_defaults = [] param_mins = [] param_maxs = [] param_descriptions = [] default_params = get_default_parameters() for param_name in sorted(initial_parameters): param_value = initial_parameters[param_name] if param_name.startswith('RC') or param_name.startswith('CAL_'): continue try: if param_name in default_params: default_param = default_params[param_name] if default_param['type'] == 'FLOAT': is_default = abs( float(default_param['default']) - float(param_value)) < 0.00001 if 'decimal' in default_param: param_value = round(param_value, int(default_param['decimal'])) else: is_default = int( default_param['default']) == int(param_value) if not is_default: param_names.append(param_name) param_values.append(param_value) param_defaults.append(default_param['default']) param_mins.append(default_param.get('min', '')) param_maxs.append(default_param.get('max', '')) param_descriptions.append( default_param.get('short_desc', '')) else: # not found: add it as if it were changed param_names.append(param_name) param_values.append(param_value) param_defaults.append('') param_mins.append('') param_maxs.append('') param_descriptions.append('(unknown)') except Exception as error: print(type(error), error) param_data = dict(names=param_names, values=param_values, defaults=param_defaults, mins=param_mins, maxs=param_maxs, descriptions=param_descriptions) source = ColumnDataSource(param_data) columns = [ TableColumn(field="names", title="Name", width=int(plot_width * 0.2), sortable=False), TableColumn(field="values", title="Value", width=int(plot_width * 0.15), sortable=False), TableColumn(field="defaults", title="Default", width=int(plot_width * 0.1), sortable=False), TableColumn(field="mins", title="Min", width=int(plot_width * 0.075), sortable=False), TableColumn(field="maxs", title="Max", width=int(plot_width * 0.075), sortable=False), TableColumn(field="descriptions", title="Description", width=int(plot_width * 0.40), sortable=False), ] data_table = DataTable(source=source, columns=columns, width=plot_width, height=300, sortable=False, selectable=False) div = Div( text= """<b>Non-default Parameters</b> (except RC and sensor calibration)""", width=int(plot_width / 2)) return widgetbox(div, data_table, width=plot_width)