def mkdir(self, newdir): status = self.remote_directory_worker.mkdir(newdir) if status == "mkdirsuccess": self.expand(None, "\\".join(newdir.split("\\")[0:-1])) self.select(newdir.split("\\")[-1]) elif status == "mkdirfailedfileexists": ErrorDialog(self.controller, title="Error", label="Could not create directory:\n\n" + newdir + "\n\nFile exists.") self.expand(newparent=self.current_parent) elif status == "mkdirfailedpermission": ErrorDialog( self.controller, title="Error", label="Could not create directory:\n\n" + newdir + "\n\nPermission denied.", ) self.expand(newparent=self.current_parent) elif "mkdirfailed" in status: ErrorDialog(self.controller, title="Error", label="Could not create directory:\n\n" + newdir) self.expand(newparent=self.current_parent)
def inner_mkdir(dir_to_make: str, action: Any): mkdir_status = self.remote_directory_worker.mkdir(dir_to_make) print("MKDIR STATUS!!") print(mkdir_status) if mkdir_status == "mkdirsuccess": action() elif mkdir_status == "mkdirfailedfileexists": ErrorDialog( self.controller, title="Error", label="Could not create directory:\n\n" + dir_to_make + "\n\nFile exists.", ) elif mkdir_status == "mkdirfailedpermission": ErrorDialog( self.controller, title="Error", label="Could not create directory:\n\n" + dir_to_make + "\n\nPermission denied.", ) elif "mkdirfailed" in mkdir_status: ErrorDialog(self.controller, title="Error", label="Could not create directory:\n\n" + dir_to_make)
def remove_retry(self, need_new: bool = True): if need_new: self.controller.wait_dialog = None removed = self.controller.rm_current() if removed: numstr = str(self.controller.spec_num) if numstr == "None": numstr = self.controller.spec_startnum_entry.get() while len(numstr) < utils.NUMLEN: numstr = "0" + numstr self.controller.log("Warning: overwriting " + self.controller.spec_save_path + "\\" + self.controller.spec_basename + numstr + ".asd.") # If we are retrying taking a spectrum or white references, don't do input checks again. if self.controller.take_spectrum in self.controller.queue[0]: garbage = self.controller.queue[0][ self.controller.take_spectrum][2] self.controller.queue[0] = { self.controller.take_spectrum: [True, True, garbage] } elif self.controller.wr in self.controller.queue[0]: self.controller.queue[0] = {self.controller.wr: [True, True]} self.controller.next_in_queue() else: ErrorDialog( self.controller, label= "Error: Failed to remove file. Choose a different base name,\nspectrum number, or save" " directory and try again.", )
def plot(self, plot_input_file): if len(self.controller.queue) > 0: if self.plot in self.controller.queue[0]: # Happens if we just transferred data from spec compy. self.controller.complete_queue_item() self.controller.wait_dialog.top.destroy() try: data_loaded = self.plotter.load_samples(self.dataset_name, plot_input_file) if not data_loaded: ErrorDialog(self.controller, "Error", "Error: Could not load data.") print("Error: Could not load data.") # pylint: disable = broad-except except (IndexError, KeyError, Exception): Dialog( self.controller, "Plotting Error", "Error: Plotting failed.\n\nDoes file exist? Is data formatted correctly?\nIf plotting a remote file," " is the server accessible?", {"ok": {}}, ) return self.plotter.new_tab()
def remove_retry(file, action): try: os.remove(file) action() except OSError: ErrorDialog(self.controller, title="Error overwriting file", label="Error: Could not delete file.\n\n" + file)
def try_mk_dir(dir_to_make: str, action: Any) -> None: try: os.makedirs(dir_to_make) action() except OSError: ErrorDialog(self.controller, title="Cannot create directory", label="Cannot create directory:\n\n" + dir_to_make)
def check_angle_lists(self, incidences: str, emissions: str, azimuths: str) -> Tuple[List, List, List]: def check_list(list_to_check: str) -> Tuple[List, List]: invalid_list = [] list_to_check = list_to_check.split(",") if "None" in list_to_check or "none" in list_to_check: while "None" in list_to_check: list_to_check.remove("None") while "none" in list_to_check: list_to_check.remove("none") list_to_check.append(None) if list_to_check == [""]: list_to_check = [] print(list_to_check) # If e.g. %5 is included in the list, include all angles where angle % 5 == 0 n = 0 while n < len(list_to_check): angle = list_to_check[n] if "%" in str(angle): try: val = int(str(angle).replace("%", "")) except ValueError: invalid_list.append(angle) continue for k in range(-70, 171): if k % val == 0: list_to_check.insert(n, k) n += 1 list_to_check.remove(angle) n -= 1 n += 1 for n, angle in enumerate(list_to_check): if angle is not None: try: list_to_check[n] = int(angle) except ValueError: invalid_list.append(angle) return list_to_check, invalid_list incidences, invalid_incidences = check_list(incidences) emissions, invalid_emissions = check_list(emissions) azimuths, invalid_azimuths = check_list(azimuths) if invalid_incidences != [] or invalid_emissions != [] or invalid_azimuths != []: error_string = "Warning! Not all angles entered are valid.\n" if invalid_incidences != []: error_string += "\nInvalid incidences: " + str( invalid_incidences) if invalid_emissions != []: error_string += "\nInvalid emissions: " + str( invalid_emissions) if invalid_azimuths != []: error_string += "\nInvalid azimuths: " + str(invalid_azimuths) ErrorDialog(self.controller, "Warning!", error_string) return incidences, emissions, azimuths
def lost_dialog(self, buttons: Dict): ErrorDialog( controller=self.controller, title="Lost Connection", label= "Error: Lost connection with spec compy.\n\nCheck that you and the spectrometer computer are\n" "both connected to the same network.", buttons=buttons, button_width=15, )
def lost_dialog(self, buttons: Dict): ErrorDialog( controller=self.controller, title="Lost Connection", label="Error: Lost connection with Raspberry Pi.\n\n" "Check you and the Raspberry Pi are\n" "both connected to the same network.", buttons=buttons, button_width=15, )
def ok(self): try: color_variable = int(self.hue_entry.get()) if color_variable < 0 or color_variable > 359: raise ValueError except ValueError: ErrorDialog(self.controller, "Error", "Error: Invalid custom hue.\n\nEnter a number 0-359.") return self.func(int(self.hue_entry.get())) self.top.destroy()
def apply_x(self): self.view_notebook.select(self.tab.top) try: x1 = float(self.left_zoom_entry.get()) x2 = float(self.right_zoom_entry.get()) self.tab.adjust_x(x1, x2) except: ErrorDialog(self, title='Invalid Zoom Range', label='Error: Invalid x limits: ' + self.left_zoom_entry.get() + ', ' + self.right_zoom_entry.get())
def apply_y(self): self.view_notebook.select(self.tab.top) try: y1 = float(self.left_zoom_entry2.get()) y2 = float(self.right_zoom_entry2.get()) self.tab.adjust_y(y1, y2) except Exception as e: print(e) ErrorDialog(self, title='Invalid Zoom Range', label='Error! Invalid y limits: ' + self.left_zoom_entry2.get() + ', ' + self.right_zoom_entry2.get())
def setup_process(self) -> Tuple[str, str, str]: output_file: str = self.output_file_entry.get() if output_file == "": ErrorDialog(self.controller, label="Error: Enter an output file name") raise ProcessFileError if output_file[-4:] != ".csv": output_file = output_file + ".csv" self.output_file_entry.insert("end", ".csv") input_directory = self.input_dir_entry.get() if input_directory[-1] == "\\": input_directory = input_directory[:-1] output_directory = self.output_dir_entry.get() if self.process_save_dir.get(): file = open( self.config_info.local_config_loc + "process_directories.txt", "w+") file.write(self.proc_local_remote + "\n") file.write(input_directory + "\n") file.write(output_directory + "\n") file.write(output_file + "\n") file.close() if self.proc_local.get() == 1: self.controller.plot_manager.plot_local_remote = "local" check = self.check_local_file(self.output_dir_entry.get(), output_file, self.controller.process_cmd) if not check: raise ProcessFileError # If the file exists, controller.check_local_file_exists # gives the user the option to overwrite, in which case process_cmd gets called again. check = self.check_local_folder(output_directory, self.controller.process_cmd) if not check: raise ProcessFileError # Same deal for the folder (except existing is good). self.controller.plot_manager.plot_local_remote = "local" return input_directory, output_directory, output_file if self.proc_local.get() == 0: check = self.check_remote_folder(output_directory, self.controller.process_cmd) if not check: raise ProcessFileError self.controller.plot_manager.plot_local_remote = "remote" return input_directory, output_directory, output_file
def apply_z(self): self.view_notebook.select(self.tab.top) try: z1 = float(self.left_zoom_entry_z.get()) z2 = float(self.right_zoom_entry_z.get()) self.tab.adjust_z(z1, z2) except Exception as e: print(e) ErrorDialog(self, title='Invalid Zoom Range', label='Error: Invalid z limits: ' + self.left_zoom_entry.get() + ', ' + self.right_zoom_entry.get())
def apply_y(self): self.controller.view_notebook.select(self.tab.top) try: y1 = float(self.left_zoom_entry2.get()) y2 = float(self.right_zoom_entry2.get()) self.tab.adjust_y(y1, y2) # utils.lift_widget(self.analysis_dialog.top) except ValueError: # utils.lift_widget(self.analysis_dialog.top) ErrorDialog( self, title="Invalid Zoom Range", label="Error! Invalid y limits: " + self.left_zoom_entry2.get() + ", " + self.right_zoom_entry2.get(), )
def apply_z(self) -> None: self.controller.view_notebook.select(self.tab.top) try: z1 = float(self.left_zoom_entry_z.get()) z2 = float(self.right_zoom_entry_z.get()) self.tab.adjust_z(z1, z2) # utils.lift_widget(self.plot_settings_dialog.top) except ValueError: # utils.lift_widget(self.plot_settings_dialog.top) ErrorDialog( self.controller, title="Invalid Zoom Range", label="Error: Invalid z limits: " + self.left_zoom_entry_z.get() + ", " + self.right_zoom_entry_z.get(), )
def ok(self): bad_vals = [] for val in self.values: self.mins[val] = self.values[val][1] self.maxes[val] = self.values[val][2] valid = utils.validate_float_input( self.entries[val].get(), self.mins[val], self.maxes[val] ) # Weird for tray position - not valid for white reference if val == "Tray position": valid = True if not valid: bad_vals.append(val) if len(bad_vals) == 0: pos = self.entries["Tray position"].get() if pos == "White reference": pos = "WR" incidence = float(self.entries["Incidence"].get()) emission = float(self.entries["Emission"].get()) self.controller.queue[0][self.controller.configure_pi] = [ incidence, emission, pos ] self.top.destroy() ok_dict = self.buttons["ok"] for func in ok_dict: args = ok_dict[func] func(*args) else: err_str = "Error: Invalid " if len(bad_vals) == 1: for val in bad_vals: err_str += (val.lower() + " value.\nPlease enter a number from " + str(self.mins[val]) + " to " + str(self.maxes[val]) + ".") else: err_str += "input. Please enter the following:\n\n" for val in bad_vals: err_str += val + " from " + str( self.mins[val]) + " to " + str(self.maxes[val]) + "\n" ErrorDialog(self.controller, title="Error: Invalid Input", label=err_str)
def calculate(self): try: self.controller.view_notebook.select(self.tab.top) except TclError: print("Error selecting tab in analysis_tools_manager.calculate().") print(self.tab) pass artifact_warning = False if self.analyze_var.get() == "slope": left, right, slopes, artifact_warning = self.tab.calculate_slopes( self.left_slope_entry.get(), self.right_slope_entry.get()) self.update_entries(left, right) self.populate_listbox(slopes) self.update_plot_menu(["e", "i", "g", "e,i", "theta", "az, e"]) elif self.analyze_var.get() == "band depth": left, right, depths, artifact_warning = self.tab.calculate_band_depths( self.left_slope_entry.get(), self.right_slope_entry.get(), self.neg_depth.get(), self.use_delta.get(), ) self.update_entries(left, right) self.populate_listbox(depths) self.update_plot_menu(["e", "i", "g", "e,i", "theta", "az, e"]) elif self.analyze_var.get() == "band center": left, right, centers, artifact_warning = self.tab.calculate_band_centers( self.left_slope_entry.get(), self.right_slope_entry.get(), self.use_max_for_centers.get(), self.use_delta.get(), ) self.update_entries(left, right) self.populate_listbox(centers) self.update_plot_menu(["e", "i", "g", "e,i", "theta", "az, e"]) elif self.analyze_var.get() == "reflectance": left, right, reflectance, artifact_warning = self.tab.calculate_avg_reflectance( self.left_slope_entry.get(), self.right_slope_entry.get()) self.update_entries(left, right) self.populate_listbox(reflectance) self.update_plot_menu(["e", "i", "g", "e,i", "theta", "az, e"]) elif self.analyze_var.get() == "reciprocity": left, right, reciprocity, artifact_warning = self.tab.calculate_reciprocity( self.left_slope_entry.get(), self.right_slope_entry.get()) self.update_entries(left, right) self.populate_listbox(reciprocity) self.update_plot_menu(["e", "i", "g", "e,i"]) elif self.analyze_var.get() == "difference": left, right, error, artifact_warning = self.tab.calculate_error( self.left_slope_entry.get(), self.right_slope_entry.get(), self.abs_val.get()) # Tab validates left and right values. If they are no good, put in min and max wavelengths available. self.update_entries(left, right) self.populate_listbox(error) self.update_plot_menu(["\u03bb", "e,i"]) if artifact_warning: ErrorDialog( self, "Warning", "Warning: Excluding data potentially\ninfluenced by artifacts from 1000-1400 nm." ) self.analysis_dialog.min_height = 1000 self.analysis_dialog.update()
def listen(self): while len(self.local_server.queue) > 0: message = self.local_server.queue.pop(0) cmd, params = utils.decrypt(message) if "lostconnection" not in cmd: print("Spec read command: " + cmd) if cmd == "listdir": # RemoteDirectoryWorker in wait_for_contents is waiting for a file that contains a list of the contents # of a given folder on the spec compy. This file will have an encrypted version of the parent # directory's path in its title e.g. listdir&R=+RiceData+Kathleen+spectral_data self.queue.append(message) elif "spec_data" in cmd: found = False for item in self.queue: if "spec_data" in item: found = True item["spec_data"] = item["spec_data"] + "&".join( params) if not found: self.queue.append({"spec_data": "&".join(params)}) if cmd == "spec_data_final": self.queue.append("spec_data_transferred") elif cmd == "savedfile": self.queue.append(cmd) elif cmd == "restarting": self.queue.append(cmd) elif "log_data" in cmd: found = False for item in self.queue: if "log_data" in item: found = True item["log_data"] = item["log_data"] + "&".join(params) if not found: self.queue.append({"log_data": "&".join(params)}) if cmd == "log_data_final": self.queue.append("log_data_transferred") elif "listcontents" in cmd: self.queue.append(message) elif "lostconnection" in cmd and not self.controller.restarting_spec_compy: if self.alert_lostconnection: self.alert_lostconnection = False time.sleep(4) self.controller.freeze() buttons = { "retry": { self.set_alert_lostconnection: [True], }, "work offline": {}, "exit": { utils.exit_func: [] }, } ErrorDialog( controller=self.controller, title="Lost Connection", label= "Error: RS3 has no connection with the spectrometer.\nCheck that the spectrometer is" " on.\n\nNote that RS3 can take some time to connect to the spectrometer.\nBe patient" " and wait for the dot at the lower right of RS3 to turn green.", buttons=buttons, button_width=15, width=600, ) elif "unexpectedfile" in cmd and not self.controller.restarting_spec_compy: if self.new_dialogs: ErrorDialog( self.controller, title="Untracked Files", label= "There is an untracked file in the data directory.\nDoes this belong here?\n\n" + params[0], ) else: for param in params: print(param) self.unexpected_files.append(param) elif "batch" in cmd: if "batch" in cmd: self.locked = True self.queue.append(cmd + "&".join(params)) self.locked = False # print("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@adding to queue") # print(cmd + "&".join(params)[0:100]) else: self.queue.append(cmd + "&".join(params))
def expand( self, event: Optional[Event] = None, newparent: Optional[str] = None, buttons: Optional[Dict] = None, select: Optional[str] = None, destroy: bool = False, ): print("expanding!") if newparent is None: index = self.listbox.curselection()[0] if self.listbox.itemcget(index, "foreground") == "darkblue": return newparent = self.current_parent + "\\" + self.listbox.get(index) if newparent[1:2] != ":" or len( newparent) > 2 and newparent[1:3] != ":\\": ErrorDialog( self.controller, title="Error: Invalid input", label="Error: Invalid input.\n\n" + newparent + "\n\nis not a valid filename.", ) if self.current_parent is None: self.expand(newparent="C:\\Users") return if newparent[-1] == "\\": newparent = newparent[:-1] # Send a command to the spec compy asking it for directory contents if self.directories_only: status: Union[List, str] = self.remote_directory_worker.get_contents( newparent) else: status: Union[List, str] = self.remote_directory_worker.get_contents( newparent) # if we succeeded, the status will be a list of the contents of the directory if isinstance(status, list): self.listbox.delete(0, "end") for directory in status: if directory[0:2] == "~:": self.listbox.insert(END, directory[2:]) self.listbox.itemconfig(END, fg="darkblue") else: self.listbox.insert(END, directory) self.current_parent = newparent self.path_entry.delete(0, "end") self.path_entry.insert("end", newparent) if select is not None: self.select(select) if destroy: self.close() elif status == "listdirfailed": if self.current_parent is None: self.current_parent = "C:\\Users" if buttons is None: buttons = { "yes": { self.mkdir: [newparent] }, "no": { self.expand: [None, self.current_parent] } } ErrorDialog( self.controller, title="Error", label=newparent + "\ndoes not exist. Do you want to create this directory?", buttons=buttons, ) return elif status == "listdirfailedpermission": ErrorDialog(self.controller, label="Error: Permission denied for\n" + newparent) return elif status == "timeout": ErrorDialog( self.controller, label="Error: Operation timed out.\n" "Check that the automation script is running on the spectrometer computer.", ) self.cancel()
def check_remote_folder(self, remote_dir: str, next_action: Any) -> bool: print(remote_dir) def inner_mkdir(dir_to_make: str, action: Any): mkdir_status = self.remote_directory_worker.mkdir(dir_to_make) print("MKDIR STATUS!!") print(mkdir_status) if mkdir_status == "mkdirsuccess": action() elif mkdir_status == "mkdirfailedfileexists": ErrorDialog( self.controller, title="Error", label="Could not create directory:\n\n" + dir_to_make + "\n\nFile exists.", ) elif mkdir_status == "mkdirfailedpermission": ErrorDialog( self.controller, title="Error", label="Could not create directory:\n\n" + dir_to_make + "\n\nPermission denied.", ) elif "mkdirfailed" in mkdir_status: ErrorDialog(self.controller, title="Error", label="Could not create directory:\n\n" + dir_to_make) status = self.remote_directory_worker.get_dirs(remote_dir) if status == "listdirfailed": buttons = { "yes": { inner_mkdir: [remote_dir, next_action] }, "no": {} } ErrorDialog( self.controller, title="Directory does not exist", label=remote_dir + "\ndoes not exist. Do you want to create this directory?", buttons=buttons, ) return False if status == "listdirfailedpermission": ErrorDialog(self.controller, label="Error: Permission denied for\n" + remote_dir) return False if status == "timeout": if not self.controller.text_only: buttons = { "cancel": {}, "retry": { self.controller.spec_commander.remove_from_listener_queue: [["timeout"]], self.controller.next_in_queue: [], }, } dialog = ErrorDialog( self.controller, label= "Error: Operation timed out.\n\nCheck that the automation script is running on the" " spectrometer\n computer and the spectrometer is connected.", buttons=buttons, ) for button in dialog.tk_buttons: button.config(width=15) else: self.controller.log("Error: Operation timed out.") return False self.controller.spec_commander.check_writeable(remote_dir) t = 3 * utils.BUFFER while t > 0: if "yeswriteable" in self.controller.spec_listener.queue: self.controller.spec_listener.queue.remove("yeswriteable") return True if "notwriteable" in self.controller.spec_listener.queue: self.controller.spec_listener.queue.remove("notwriteable") ErrorDialog( self.controller, label= "Error: Permission denied.\nCannot write to specified directory." ) return False time.sleep(utils.INTERVAL) t = t - utils.INTERVAL if t <= 0: ErrorDialog(self.controller, label="Error: Operation timed out.") return False
def check_local_folder(self, local_dir: str, next_action: Any) -> bool: def try_mk_dir(dir_to_make: str, action: Any) -> None: try: os.makedirs(dir_to_make) action() except OSError: ErrorDialog(self.controller, title="Cannot create directory", label="Cannot create directory:\n\n" + dir_to_make) exists = os.path.exists(local_dir) if exists: # If the file exists, try creating and deleting a new file there to make sure we have permission. try: if self.config_info.opsys in ("Linux", "Mac"): if local_dir[-1] != "/": local_dir += "/" else: if local_dir[-1] != "\\": local_dir += "\\" existing = os.listdir(local_dir) i = 0 delme = "delme" + str(i) while delme in existing: i += 1 delme = "delme" + str(i) os.mkdir(local_dir + delme) os.rmdir(local_dir + delme) return True except OSError: ErrorDialog( self.controller, title="Error: Cannot write", label="Error: Cannot write to specified directory.\n\n" + local_dir, ) return False else: if ( self.controller.script_running ): # If we're running a script, just try making the directory automatically. try_mk_dir(local_dir, next_action) else: # Otherwise, ask the user. buttons = { "yes": { try_mk_dir: [local_dir, next_action] }, "no": {} } ErrorDialog( self.controller, title="Directory does not exist", label=local_dir + "\n\ndoes not exist. Do you want to create this directory?", buttons=buttons, ) # TODO: check these return statements make sense. return exists