def load_all_apps(self): base_menu = Menu([], self.i, self.o, "Main app menu", exitable=False) # Main menu for all applications. base_menu.exit_entry = ["Exit", "exit"] base_menu.process_contents() self.subdir_menus[self.app_directory] = base_menu apps_blocked_in_config = self.config.get("do_not_load", {}) for path, subdirs, modules in app_walk(self.app_directory): for subdir in subdirs: # First, we create subdir menus (not yet linking because they're not created in correct order) and put them in subdir_menus. subdir_path = os.path.join(path, subdir) self.subdir_menus[subdir_path] = Menu([], self.i, self.o, subdir_path) for _module in modules: # Then, we load modules and store them along with their paths try: module_path = os.path.join(path, _module) if module_path in apps_blocked_in_config: logger.warning( "App {} blocked from config; not loading".format( module_path)) continue app = self.load_app(module_path) logger.info("Loaded app {}".format(module_path)) self.app_list[module_path] = app except Exception as e: logger.error("Failed to load app {}".format(module_path)) logger.error(traceback.format_exc()) Printer(["Failed to load", os.path.split(module_path)[1]], self.i, self.o, 2) for subdir_path in self.subdir_menus: # Now it's time to link menus to parent menus if subdir_path == self.app_directory: continue parent_path = os.path.split(subdir_path)[0] ordering = self.get_ordering(parent_path) parent_menu = self.subdir_menus[parent_path] subdir_menu = self.subdir_menus[subdir_path] subdir_menu_name = self.get_subdir_menu_name(subdir_path) # Inserting by the ordering given parent_menu_contents = self.insert_by_ordering( [subdir_menu_name, subdir_menu.activate], os.path.split(subdir_path)[1], parent_menu.contents, ordering) parent_menu.set_contents(parent_menu_contents) for app_path in self.app_list: # Last thing is attaching applications to the menu structure created. app = self.app_list[app_path] subdir_path, app_dirname = os.path.split(app_path) ordering = self.get_ordering(subdir_path) menu_name = app.menu_name if hasattr( app, "menu_name") else app_dirname.capitalize() self.bind_callback(app, app_path, menu_name, ordering, subdir_path) return base_menu
def process_choice(choice, bugreport, li): logger.info("Processing choice: {}".format(choice)) if choice == "zpui_logs": dir = "logs/" logfiles = [os.path.join(dir, f) for f in os.listdir(dir) if f.startswith('zpui.log')] for logfile in logfiles: bugreport.add_file(logfile) if choice == "zpui_screenshots": dir = "screenshots/" bugreport.add_dir(dir) elif choice == "zpui_info": import __main__ bugreport.add_file(__main__.config_path) try: branch = git_if.get_current_branch() head = git_if.get_head_for_branch(branch)[:10] except: logger.exception("Can't get git information!") branch = "unknown" head = "unknown" git_info = "ZPUI branch: {}; commit: {}".format(branch, head) bugreport.add_text(git_info, "zpui_git_info.txt") elif choice == "zpui_threads": data = [] for th in threading.enumerate(): data.append(str(th)) log = traceback.format_stack(sys._current_frames()[th.ident]) for frame in log: data.append(str(frame)) bugreport.add_text("\n".join(data), "zpui_threads.txt") elif choice == "zpui_contexts": raise NotImplementedError elif choice == "dmesg": bugreport.add_text(json.dumps(dmesg.get_dmesg()), "dmesg.json") elif choice == "var_log": dir = "/var/log/" bugreport.add_dir(dir) elif choice == "ps": data = [] attrs = ["cmdline", "pid", "memory_info", "memory_percent", "cpu_times", "cpu_percent", "exe", "name", "ionice", "nice", "num_threads", "username"] for p in psutil.process_iter(): p_data = {} for attr in attrs: m = getattr(p, attr, "Error") try: v = m() if callable(m) else m except: v = "call error" p_data[attr] = v data.append(p_data) bugreport.add_text(json.dumps(data), "psinfo.json") elif choice == "custom": file_list = [] def remove_file(file): choice = DialogBox("yn", i, o, message="Remove from list?", name="Bugreport app custom file picker remove confirmation DialogBox").activate() if choice: file_list.remove(file) def add_file(): default_path = PathPicker.default_path if not file_list else file_list[-1] path = PathPicker(default_path, i, o, name="Bugreport app custom file picker PathPicker", display_hidden = True).activate() if path: file_list.append(path) def add_dir(): default_path = PathPicker.default_path if not file_list else file_list[-1] path = PathPicker(default_path, i, o, dirs_only=True, name="Bugreport app custom file picker PathPicker", display_hidden = True).activate() if path: file_list.append(path) def get_contents(): c = [] for f in file_list: c.append([f, lambda x=f: remove_file(x)]) c.append(["Add file", add_file]) c.append(["Add dir", add_dir]) return c m = Menu([], i, o, name="Bugreport app custom file picker menu", contents_hook=get_contents) m.exit_entry = ["Send", 'exit'] with li.paused: m.activate() for path in file_list: try: bugreport.add_dir_or_file(path) except ValueError: logger.warning("Path {} is neither file nor directory, ignoring".format(path))