def config_main_remote(git_remote, api_options): git_remote["repo_config"] = {} choices = [] title = git_remote["type"] + " repo configuration" dial = Dialog(dialog="dialog", autowidgetsize=True) dial.set_background_title(title) for i_choice in api_options: code, choice = config_remote_option(git_remote, api_options, i_choice, False) if isinstance(code, bool) and not code: return False if choice: choices += [choice] code, tags = dial.checklist("Which git remote to use as main remote ?", choices=choices, title=title, width=DIAL_MAXSIZE["width"]) for i_choice in choices: if i_choice[0] in tags: git_remote["repo_config"][i_choice[0]] = True else: git_remote["repo_config"][i_choice[0]] = False if git_remote["type"] == "github" and ( not ("allow_rebase_merge" in tags or "allow_merge_commit" in tags or "allow_squash_merge" in tags)): return github_config_merge_option(git_remote) GIT_REMOTE["repo"]["main_remote"] = git_remote["url"] + "/" \ + git_remote["namespace"] + "/" \ + git_remote["repo_config"]["name"] + ".git" return True
def ask_git_remote_to_use(): # pylint: disable=global-statement global GIT_REMOTE GIT_REMOTE["remote"] = list() choices = [] dial = Dialog(dialog="dialog", autowidgetsize=True) dial.set_background_title("Git remote selection") for i_git_remote in GIT_REMOTE["config"]: for i_remote in GIT_REMOTE["config"][i_git_remote]: if "name" in i_remote: choices += [(i_remote["name"], i_git_remote, False)] else: choices += [(i_remote["url"], i_git_remote, False)] code, tags = dial.checklist("Which git remote do you want to setup ?", choices=choices, title="Git remote selection", width=DIAL_MAXSIZE["width"]) if not code == dial.OK: return False elif not tags: dial.msgbox("Please select at least one remote to use !", title="Git remote selection ERROR", width=DIAL_MAXSIZE["width"], height=10) return False for i_git_remote in GIT_REMOTE["config"]: for i_remote in GIT_REMOTE["config"][i_git_remote]: if (("name" in i_remote) and (i_remote["name"] in tags) or (not "name" in i_remote) and (i_remote["name"] in tags)): i_remote["type"] = i_git_remote GIT_REMOTE["remote"].append(i_remote.copy()) return True
def choose_cols(self): # XX possibility un/check all chosens = [(str(i + 1), f, i in self.csv.settings["chosen_cols"]) for i, f in enumerate(self.csv.fields)] d = Dialog(autowidgetsize=True) ret, values = d.checklist("What fields should be included in the output file?", choices=chosens) if ret == "ok": self.csv.settings["chosen_cols"] = [int(v) - 1 for v in values] self.csv.is_processable = True
def _get_stream_indexes(metadata, lang_override=None) -> List[int]: d = Dialog(autowidgetsize=True) title = os.path.basename(metadata.file) if len(metadata.video_streams) > 0: video_options = [video_to_str(v) for v in metadata.video_streams] code, video_tags = d.checklist(title=title, text='Video Options', choices=video_options) if code != d.OK: return else: video_tags = [] if len(metadata.audio_streams) > 0: audio_options = [ audio_to_str(a) for a in sorted( metadata.audio_streams, key=lambda s: s.channels, reverse=True) ] code, audio_tags = d.checklist(title=title, text='Audio Options', choices=audio_options) if code != d.OK: return else: audio_tags = [] if len(metadata.subtitle_streams) > 0: sub_options = [ sub_to_str(a, lang_override) for a in metadata.subtitle_streams ] code, sub_tags = d.checklist(title=title, text='Subtitle Options', choices=sub_options) if code != d.OK: return else: sub_tags = [] return video_tags, audio_tags, sub_tags
def choose_servers(available_video_servers, available_controllers, opts): ''' Present a list of video servers to the user and let her chhoose which ones to operate on. ''' from dialog import Dialog d = Dialog() current_status = [] warnings = [] for vs in available_video_servers: controllers = vs.get_controllers() if controllers: for controller in controllers: current_status.append((controller.get_id(), vs.get_fqdn(), 0 if controller.is_quiescent() else 1)) else: warnings.append( 'WARNING: No controller found for {vls_server}'.format( vls_server=vs.get_fqdn())) for warning in validate_controllers(available_video_servers, available_controllers): warnings.append(warning) if not current_status: warnings.append( ('ERROR: No controller found for any of the' ' video servers {video_servers}.').format(video_servers=', '.join( [vs.get_fqdn() for vs in available_video_servers]))) d.msgbox('\n'.join(warnings)) return None, None if warnings: d.msgbox('\n'.join(warnings), width=0, height=0) code, requested_active_controller_ids = d.checklist( ('Please choose which controllers' ' should be active:'), choices=current_status) if code != 0: return None, None activate_controller_ids = [] quiesce_controller_ids = [] for vs in available_video_servers: for controller in vs.get_controllers(): controller_id = controller.get_id() if controller.is_quiescent(): if controller_id in requested_active_controller_ids: activate_controller_ids.append(controller_id) else: if controller_id not in requested_active_controller_ids: quiesce_controller_ids.append(controller_id) return activate_controller_ids, quiesce_controller_ids
def choose_cols(self): # XX possibility un/check all chosens = [(str(i + 1), str(f), f.is_chosen) for i, f in enumerate(self.parser.fields)] d = Dialog(autowidgetsize=True) ret, values = d.checklist( "What fields should be included in the output file?", choices=chosens) if ret == "ok": for f in self.parser.fields: f.is_chosen = False for v in values: self.parser.fields[int(v) - 1].is_chosen = True self.parser.is_processable = True
def ask(self): if hasattr(self.port, 'config'): dialog = Dialog(dialog='dialog') dialog.set_background_title('Conguration for {PORTNAME}'.format(PORTNAME=self.port.portname)) portchoices = [] for option, optvalues in self.port.config.items(): self.port.config[option]['user_choice'] = False portchoices.append((option, optvalues['description'], optvalues['default'])) code, tags = dialog.checklist( 'Choose your Configuration for {PORTNAME}'.format(PORTNAME=self.port.portname), choices=portchoices, title="Port configuration") if code == dialog.OK: for tag in tags: self.port.config[tag]['user_choice'] = True print('\n')
def read_tui(self): description_pkgs = [(pkg, '') for pkg in filter( lambda x: re.search('sweetie_bot_[\w]+?_description', x), rospack.list())] if len(description_pkgs) == 0: self.parser.error( "ROS packages sweetie_bot_*_description not found") d = Dialog(dialog="dialog") d.set_background_title(self.title) code, package_name = d.menu(self.description + self.what_file, choices=description_pkgs) if code != d.OK: return False self.file = self.is_valid_pkg(package_name) code, func_name = d.menu(self.description + self.what_todo, choices=plugins.functions_names) if code != d.OK: return False choices = [] for plugin in plugins.loaded.values(): if func_name in dir(plugin): choices.append( (plugin.display_name, plugin.cmd_letter, plugin.enabled)) code, tags = d.checklist(self.what_func % func_name, choices=choices, title=func_name + ' ' + os.path.basename(self.file), width=60) if code != d.OK: return False plugin_choices_list = [] for plugin in plugins.loaded.values(): if (plugin.display_name in tags): plugin_choices_list.append(plugin.name) setattr(self, func_name, plugin_choices_list) return True
def do_fuzzing(self, line): """fuzzing.\n\tRandom testing built on regex string generation.""" d = Dialog(dialog="dialog") d.set_background_title("Tiger Compiler TestSuite") code, tag = d.menu("Which type of fuzzing do you wanna do?", choices=[("(1)", "Random"), ("(2)", "Select from a list")]) if code == d.OK: if tag == "(2)": code, tags = d.checklist("For which categories?", choices=[ ("Literals", "", False), ("Array and record", "", False), ("Variables, field, elements", "", False), ("Object", "", False), ("Function", "", False), ("Method", "", False), ("Operations", "", False), ("Assignment", "", False), ("Type", "", False), ("Class", "", False), ("Control structures", "", False) ]) if code != d.OK: os.system('clear') return if not tags: os.system('clear') print("You didn't choose anything.") return else: tags = ("Literals", "Array and record", "Variables, field, elements", "Object", "Function", "Method", "Operations", "Assignement", "Type", "Class", "Control structures") os.system('clear') print(*tags, sep='\n') count = input("How many random tests should be created? ") for i in range(int(count)): global categories for cat in tags: print(rstr.xeger(categories[cat]())) else: os.system('clear')
def ask(self): if hasattr(self.port, 'config'): dialog = Dialog(dialog='dialog') dialog.set_background_title('Conguration for {PORTNAME}'.format( PORTNAME=self.port.portname)) portchoices = [] for option, optvalues in self.port.config.items(): self.port.config[option]['user_choice'] = False portchoices.append( (option, optvalues['description'], optvalues['default'])) code, tags = dialog.checklist( 'Choose your Configuration for {PORTNAME}'.format( PORTNAME=self.port.portname), choices=portchoices, title="Port configuration") if code == dialog.OK: for tag in tags: self.port.config[tag]['user_choice'] = True print('\n')
def dialog_field_checklist(): d = Dialog(dialog="dialog") d.set_background_title("FIELD section options") field_options = conf.get_field_options() choices = [] for entry in conf.list_dir("./field", ext=".txt"): choices += [(entry, "", (entry in field_options))] for entry in conf.list_dir("./field", ext=".sh"): choices += [(entry, "", (entry in field_options))] if len(choices): code, selection = d.checklist("select FIELD options", choices=choices) if code == d.OK: conf.set_field_options(selection) else: d.infobox("no option files in ./field", width=0, height=0, title="done") time.sleep(2)
def github_config_merge_option(git_remote): tags = list() title = git_remote["type"] + " repo configuration" dial = Dialog(dialog="dialog", autowidgetsize=True) msg = git_remote["url"] + "\n" choices = [] dial.set_background_title(title) while not ("allow_rebase_merge" in tags or "allow_merge_commit" in tags or "allow_squash_merge" in tags): choices = [("allow_squash_merge", "Does the repo allow squash merge ?", False), ("allow_merge_commit", "Does the repo allow merge ?", True), ("allow_rebase_merge", "Does the repo allow rebase merge ?", False)] code, tags = dial.checklist( msg + "At least one merge politics must be choose, please select at least" + " one of the following", choices=choices, title=title, width=DIAL_MAXSIZE["width"]) if not code == dial.OK: return False return True
class DialogUtil(object): """Create dialog checklist """ def __init__(self, *args): try: from dialog import Dialog except ImportError: print("Require 'pythondialog': Install with 'slpkg -s sbo " "python2-pythondialog'") raise SystemExit() self.d = Dialog(dialog="dialog", autowidgetsize=True) self.data = args[0] self.text = args[1] self.title = args[2] self.backtitle = args[3] self.status = args[4] self.ununicode = [] self.tags = [] def checklist(self): """Run dialog checklist """ choice = [] for item in self.data: choice.append((item, "", self.status)) code, self.tags = self.d.checklist( text=self.text, height=20, width=65, list_height=13, choices=choice, title=self.title, backtitle=self.backtitle) if code == "ok": self.unicode_to_string() return self.ununicode if code in ["cancel", "esc"]: self.exit() def buildlist(self, enabled): """Run dialog buildlist """ choice = [] for item in self.data: choice.append((item, False)) for item in enabled: choice.append((item, True)) items = [(tag, tag, sta) for (tag, sta) in choice] code, self.tags = self.d.buildlist( text=self.text, items=items, visit_items=True, item_help=False, title=self.title) if code == "ok": self.unicode_to_string() return self.ununicode if code in ["cancel", "esc"]: self.exit() def exit(self): """Exit from dialog """ self.clear_screen() raise SystemExit() def clear_screen(self): """Clear screen """ os.system("clear") def unicode_to_string(self): """Convert unicode in string """ for tag in self.tags: self.ununicode.append(str(tag))
d.set_background_title("My little program") # For older versions, you can use: # d.add_persistent_args(["--backtitle", "My little program"]) # In pythondialog 3.x, you can compare the return code to d.OK, Dialog.OK or # "ok" (same object). In pythondialog 2.x, you have to use d.DIALOG_OK, which # is deprecated since version 3.0.0. if d.yesno("Are you REALLY sure you want to see this?") == d.OK: d.msgbox("You have been warned...") # We could put non-empty items here (not only the tag for each entry) code, tags = d.checklist("What sandwich toppings do you like?", choices=[("Catsup", "", False), ("Mustard", "", False), ("Pesto", "", False), ("Mayonnaise", "", True), ("Horse radish", "", True), ("Sun-dried tomatoes", "", True)], title="Do you prefer ham or spam?", backtitle="And now, for something " "completely different...") if code == d.OK: # 'tags' now contains a list of the toppings chosen by the user pass else: code, tag = d.menu("OK, then you have two options:", choices=[("(1)", "Leave this fascinating example"), ("(2)", "Leave this fascinating example")]) if code == d.OK: # 'tag' is now either "(1)" or "(2)" pass
class DialogUtil(object): """Create dialog checklist """ def __init__(self, *args): try: from dialog import Dialog except ImportError: print("Require 'pythondialog': Install with '# slpkg -s sbo " "python2-pythondialog'") raise SystemExit() self.d = Dialog(dialog="dialog", autowidgetsize=True) self.data = args[0] self.text = args[1] self.title = args[2] self.backtitle = args[3] self.status = args[4] self.ununicode = [] self.tags = [] def checklist(self): """Run dialog checklist """ choice = [] for item in self.data: choice.append((item, "", self.status)) code, self.tags = self.d.checklist( text=self.text, height=20, width=65, list_height=13, choices=choice, title=self.title, backtitle=self.backtitle) if code == "ok": self.unicode_to_string() return self.ununicode if code in ["cancel", "esc"]: self.exit() def buildlist(self, enabled): """Run dialog buildlist """ choice = [] for item in self.data: choice.append((item, False)) for item in enabled: choice.append((item, True)) items = [(tag, tag, sta) for (tag, sta) in choice] code, self.tags = self.d.buildlist( text=self.text, items=items, visit_items=True, item_help=False, title=self.title) if code == "ok": self.unicode_to_string() return self.ununicode if code in ["cancel", "esc"]: self.exit() def exit(self): """Exit from dialog """ self.clear_screen() raise SystemExit() def clear_screen(self): """Clear screen """ os.system("clear") def unicode_to_string(self): """Convert unicode in string """ for tag in self.tags: self.ununicode.append(str(tag))
class WindowsInstallApp(object): def __init__(self, config=None): self.logger = logging.getLogger(__name__) self.config = config self.uefi = False self.boot_part = '' self.system_part = '' self.image_path = '' self.image_index = '' self.boot_dir = '/mnt/boot' self.system_dir = '/mnt/system' self.mbr_disk_signature = '4D34B30F' self.gpt_disk_signature = '572BD0E9-D39E-422C-82E6-F37157C3535D' self.boot_partuuid = '8d03c7bb-6b0c-4223-aaa1-f20bf521cd6e' self.system_partuuid = '57092450-f142-4749-b540-f2ec0a183b7b' self.cluster_size = 4096 self.fs_compression = False self.quick_format = True self.d = Dialog(dialog='dialog') self.d.set_background_title('KiWI: Killer Windows Installer') self.source_dir = '/mnt/source/' advanced_items = [ ('Filesystem options', MenuItem(self.fs_options)), ] advanced_submenu = Menu(self.d, advanced_items, title='Advanced Options') main_menu_items = [ ('Configure Networking', MenuItem(self.configure_network)), ('Prepare Storage Device', MenuItem(self.auto_prepare)), ('Select Installation Source', MenuItem(self.prepare_source)), ('Install OS', MenuItem(self.install_os)), #('Install Bootloader', self.install_bootloader), ('Reboot', MenuItem(self.reboot)), ('---', MenuItem(separator=True)), ('Advanced Options', advanced_submenu), ] self.running = True self.main_menu = StatefulMenu(self.d, main_menu_items, title='Main Menu') while self.running: self.main_menu.run(ret=self.exit()) def sync(self): self.d.infobox('Syncing buffered data\n\nDo NOT reboot!', width=30) subprocess.check_call(['sync']) def reboot(self): self.sync() subprocess.check_call(['reboot']) def fs_options(self): choices = [ ('Quick Format', '', 'quick_format'), ('NTFS Compression', '', 'fs_compression'), ('Force GPT/EFI', '', 'uefi'), ] code, selected = self.d.checklist('Filesystem Options', choices=[ (choice[0], choice[1], getattr(self, choice[2])) for choice in choices], cancel_label='Back') if code != self.d.OK: return for item in choices: tag = item[0] var_name = item[2] if tag in selected: setattr(self, var_name, True) else: setattr(self, var_name, False) def test_network(self): return True if subprocess.call( ['ping', '-c 2', '-i 0.2', '8.8.8.8'], stdout=subprocess.PIPE) == 0 else False def configure_network(self): if not self.test_network(): rc = subprocess.call('nmtui', shell=True) else: self.d.msgbox('Network Configuration Successful', width=40, title='Network Status') self.main_menu.advance() def detect_blockdevs(self): devices = [] p = subprocess.run(['lsblk', '-Ppd'], stdout=subprocess.PIPE) for line in p.stdout.decode('UTF-8').split('\n'): dev = {} for p in line.split(): pair = p.split('=') dev[pair[0]] = pair[1][1:-1] # We don't need read-only devices if 'RO' not in dev or dev['RO'] == '1': continue devices.append(dev) self.d.msgbox('Detected Devices:\n\n' + '\n'.join( [' '.join([dev['NAME'], dev['SIZE']]) for dev in devices])) self.devices = devices def select_disk(self): self.detect_blockdevs() entries = [tuple([device['NAME'], '-']) for device in self.devices] + [('OTHER', '+')] code, tag = self.d.menu('Choose an installation drive', choices=entries) if code != self.d.OK: raise FailedInstallStep if tag == 'OTHER': code, tag = self.d.inputbox('Enter a path to a block device') if code != self.d.OK: raise FailedInstallStep if not os.path.isfile(tag): raise FailedInstallStep import stat mode = os.stat(tag).st_mode if not stat.S_ISBLK(mode): raise FailedInstallStep code, confirmation = self.d.inputbox('This will erase ALL data on %s' % tag + \ '\n\nType \'YES\' to continue', width=40, height=15) if code != self.d.OK or confirmation != 'YES': raise FailedInstallStep self.install_drive = tag self.logger.info('Block device {} selected for installation'.format(self.install_drive)) def supports_uefi(self): p = subprocess.Popen(['efivar', '-l'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) uefi = True if p.returncode == 0 else False return uefi def auto_prepare(self): try: self.select_disk() except FailedInstallStep: self.d.msgbox('Disk selection failed. Please retry the step to prepare the storage device.', width=40) raise for dir in [self.system_dir, self.boot_dir]: if mountpoint(dir): unmount(dir) partitions = glob.glob(self.install_drive + '+.') for part in partitions: logger.debug('Unmounting partition {}'.format(part)) try: unmount(part) except subprocess.CalledProcessError: pass self.auto_partition() self.auto_format() self.main_menu.advance() def auto_partition(self): if self.uefi is False: self.uefi = self.supports_uefi() else: uefi_forced = True if self.uefi and not uefi_forced: self.logger.info('Detected machine booted with UEFI, using GPT') elif self.uefi and uefi_forced: self.logger.info('UEFI install forced, using GPT') else: self.logger.info('UEFI not supported, creating DOS partition table') partition_table = 'msdos' if not self.uefi else 'gpt' try: subprocess.check_call(['parted', '-s', self.install_drive, 'mklabel', partition_table]) if self.uefi: subprocess.check_call(['parted', '--align', 'optimal', '-s', self.install_drive, '--', 'mkpart', 'ESP', 'fat32', '0%s', '512', 'mkpart', 'Windows', 'NTFS', '512', '100%', 'set', '1', 'esp', 'on']) else: subprocess.check_call(['parted', '-s', self.install_drive, '--', 'mkpart', 'primary', 'NTFS', '2048s', '-1s', 'set', '1', 'boot', 'on']) except subprocess.CalledProcessError: self.d.msgbox('Partitioning/formatting failed. Please retry.', width=40) raise FailedInstallStep if self.uefi: self.boot_part = self.install_drive + '1' self.system_part = self.install_drive + '2' else: self.system_part = self.install_drive + '1' def auto_format(self): call = ['mkfs.ntfs'] call.append('-c') call.append(str(self.cluster_size)) if self.fs_compression: call.append('-C') if self.quick_format: call.append('-Q') call.append(self.system_part) try: subprocess.check_call(call, stdout=subprocess.PIPE, stderr=subprocess.PIPE) if self.uefi: subprocess.check_call(['mkfs.msdos', '-F32', self.boot_part], stdout = subprocess.PIPE, stderr=subprocess.PIPE) except subprocess.CalledProcessError: raise FailedInstallStep self.d.infobox('Formatting drive...') self.logger.info('Sucessfully formatted installation drive') def prepare_source(self): if not self.test_network(): self.configure_network() source_items = [ ('Network Filesystem (NFS)', MenuItem(self.prepare_nfs_source)), ('Windows Share (SMB/CIFS)', MenuItem(self.prepare_smb_source)), #('Network Block Device (NBD)', MenuItem()), ('SCP/SFTP (SSH)', MenuItem(self.prepare_sshfs_source)), ('Block Device (USB, CD/DVD, etc.)', self.prepare_blk_source), ('---', MenuItem(separator=True)), ('OTHER (Path)', MenuItem(self.prepare_fs_source)), ] try: Menu(self.d, source_items, 'Select Installation Source', ret=None).run() self.select_source() except FailedInstallStep: raise except subprocess.CalledProcessError: self.d.msgbox('Mount Failed. Please retry the installation source selection step') def prepare_nfs_source(self): code, path = self.d.inputbox('Enter an NFS server or share', init=self.config.get('source', 'default_nfs', fallback=''), width=40) mount(path, self.source_dir, force=True, mkdir=True) def prepare_smb_source(self): code, path = self.d.inputbox( 'Enter an SMB share path in the format \'user@//server/share\'', width=40) user, passwd, cred = '', '', '' if '@' in path: user, path = path.split('@') code, passwd = self.d.passwordbox( 'Enter the share password, if applicable', width=40) cred = 'password={},'.format(passwd) if user: cred += 'username={},'.format(user) mount(path, self.source_dir, options=cred, force=True, mkdir=True, fs_type='cifs') def prepare_fs_source(self): code, path = self.d.inputbox('Enter a UNIX path', width=40) mount(path, self.source_dir, force=True, mkdir=True, bind=True) def prepare_sshfs_source(self): code, path = self.d.inputbox('Enter an SSHFS path, in the format user@server:/', width=40) code, passwd = self.d.passwordbox('Enter the password', width=40) try: os.makedirs(self.source_dir) except FileExistsError: pass if mountpoint(self.source_dir): unmount(self.source_dir) disable_hostkey_check = ['-o', 'StrictHostKeyChecking=no'] call = ['sshfs', path, self.source_dir, '-o', 'password_stdin'] call += disable_hostkey_check p = subprocess.Popen(call, stdin=subprocess.PIPE, stdout=open('/dev/null', 'w')) p.communicate(input=passwd.encode('UTF-8')) if p.returncode != 0: raise subprocess.CalledProcessError def prepare_blk_source(self): code, path = self.d.inputbox('Enter a block device path', width=40) mount(path, self.source_dir, force=True, mkdir=True) def select_source(self): discovered_wims = glob.glob(self.source_dir + '**/*.wim', recursive=True) discovered_wims += glob.glob(self.source_dir + '**/.esd', recursive=True) #discovered_isos = glob.glob(self.source_dir + '**/.iso', recursive=True) if not discovered_wims: # or discovered_isos: self.d.msgbox('Failed to locate install sources. Check your media, and try again.', width=40) raise FailedInstallStep entries = [tuple([wim, '-']) for wim in discovered_wims] code, tag = self.d.menu('Choose a WIM', choices=entries) if code == self.d.OK: self.image_path = tag else: raise FailedInstallStep try: entries = [ tuple([ image['Index'], # Not every WIM has 'Display Name' defined image.get('Display Name') or image.get('Description') + ' ' + image.get('Architecture') ]) for image in wiminfo(self.image_path)] except subprocess.CalledProcessError: self.d.msgbox('Image is invalid or corrupt. Please retry the installation source step.', width=40) raise FailedInstallStep code, tag = self.d.menu('Choose an image', choices=entries, width=40) if code == self.d.OK: self.image_index = tag else: raise FailedInstallStep self.main_menu.advance() def install_os(self): if not self.system_part: self.auto_prepare() self.main_menu.position -= 1 if not (self.image_path and self.image_index): self.prepare_source() self.main_menu.position -= 1 self.extract_wim(self.image_path, self.image_index, self.system_part) self.sync() self.install_bootloader() self.main_menu.advance() def extract_wim(self, wimfile, imageid, target): r, w = os.pipe() process = subprocess.Popen(['wimlib-imagex', 'apply', wimfile, imageid, target], stdout=w, stderr=w) filp = os.fdopen(r) self.logger.info('Applying WIM...') while True: line = filp.readline() self.logger.debug('Discarding line from WIM STDOUT: {}'.format(line)) if 'Creating files' in line: break for stage in ['Creating files', 'Extracting file data']: self.d.gauge_start(text=stage, width=80, percent=0) while(True): line = filp.readline() self.logger.debug('Wim extraction STDOUT: {}'.format(line)) if stage not in line: continue pct = re.search(r'\d+%', line).group(0)[:-1] if pct: self.d.gauge_update(int(pct)) if pct == '100': break exit_code = self.d.gauge_stop() def ntfs_hide(self, path): subprocess.check_call(['setfattr', '-h', '-v', '0x02000000', '-n', 'system.ntfs_attrib', path]) def install_bootloader(self): from . import BCD mount(self.system_part, self.system_dir, mkdir=True) if not self.uefi: self.write_mbr() shutil.copytree( os.path.join(self.system_dir, 'Windows/Boot/PCAT'), os.path.join(self.system_dir, 'Boot')) shutil.copy2( os.path.join(self.system_dir, 'Boot/bootmgr'), self.system_dir) for file in ['Boot', 'bootmgr']: self.ntfs_hide(os.path.join(self.system_dir, file)) BCD.write_bcd(BCD.bios_bcd, os.path.join(self.system_dir, 'Boot/BCD')) else: mount(self.boot_part, self.boot_dir, mkdir=True) subprocess.check_call(['sgdisk', self.install_drive, '-U', self.gpt_disk_signature, '-u 1:' + self.boot_partuuid, '-u 2:' + self.system_partuuid]) for dir in ['Boot', 'Microsoft']: os.makedirs(os.path.join(self.boot_dir, 'EFI/' + dir)) shutil.copytree( os.path.join(self.system_dir, 'Windows/Boot/EFI'), os.path.join(self.boot_dir, 'EFI/Microsoft/Boot')) shutil.copyfile( os.path.join(self.boot_dir, 'EFI/Microsoft/Boot/bootmgfw.efi'), os.path.join(self.boot_dir, 'EFI/Boot/bootx64.efi')) BCD.write_bcd(BCD.uefi_bcd, os.path.join(self.boot_dir, 'EFI/Microsoft/Boot/BCD')) def write_mbr(self): subprocess.check_call(['ms-sys', '-S', self.mbr_disk_signature, '-7', self.install_drive], stdout=subprocess.PIPE, stderr=subprocess.PIPE) self.logger.info('MBR written to {}'.format(self.install_drive)) def exit(self): self.running = False
continue # P, K, B if tag == "P": os.system("clear") print(tabulate(data, headers="keys")) input("\nPress enter to go back.") if tag == "K": choices = [] for player in data: choices.append((player["name"], "", False)) code, tags = dialog.checklist( "Who all do you want to kick?", choices=choices) if code == dialog.OK: for tag in tags: response = interface.fetch( data=interface.prepare(["KICK", tag])) if response != "OK": dialog.msgbox( "\Z1Cannot kick {}:\n{}".format( tag, response)) else: continue if tag == "B": choices = [] for player in data:
class Journaler(): def __init__(self, config): self.config = config self.d = Dialog(dialog="dialog", autowidgetsize=True) self.d.set_background_title("SILO JOURNALING SYSTEM") @staticmethod def topic_from_filename(filename): try: topic = re.search( "[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]_(.+?)$", filename).group(1) except AttributeError: topic = "NO_TOPIC" return topic @staticmethod def date_from_filename(filename): try: date = re.search( "([0-9][0-9][0-9][-9]-[0-9][0-9]-[0-9][0-9])_.+?$", filename).group(1) except AttributeError: date = "NO_TOPIC" return date # generate the filepath for a specific entry def _get_entry_filename(self, topic, date): # TODO add sanity checks return "{0}/{1}_{2}".format(self.config.get_journal_path(), date, topic) # open a specific entry for a supplied topic and date def _open_entry(self, topic, date): subprocess.run( [self.config.get_editor(), self._get_entry_filename(topic, date)]) # gemerate the current date in a standard format def _get_current_date(self): return datetime.today().strftime('%Y-%m-%d') # load all entry metadata def _get_all_entries(self): entry_list = os.listdir(self.config.get_journal_path()) return entry_list # get all topics for all dates def _get_all_topics(self): topics = list() for item in self._get_all_entries(): try: found = re.search( "[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]_(.+?)$", item).group(1) topics.append(found) except AttributeError: pass return sorted(list(dict.fromkeys(topics))) # get all topics for all dates def _get_all_dates(self): dates = list() for item in self._get_all_entries(): try: found = re.search( "([0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9])_.+?$", item).group(1) dates.append(found) except AttributeError: pass return sorted(list(dict.fromkeys(dates))) # get all topics associated with a date def _get_topics(self, date): topics = list() for item in self._get_all_entries(): try: found = re.search("{0}_(.+?)$".format(date), item).group(1) topics.append(found) except AttributeError: pass return sorted(list(dict.fromkeys(topics))) # get all dates associated with a topic def _get_dates(self, topic): dates = list() for item in self._get_all_entries(): try: found = re.search( "([0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9])_{0}".format( topic), item).group(1) dates.append(found) except AttributeError: pass return sorted(list(dict.fromkeys(dates))) # browse topics for a specific date def do_topic_browse_by_date(self, date): print("topic browse by date: {}".format(date)) topics = self._get_topics(date) menu_choices = list() for i in range(len(topics)): menu_choices.append((topics[i], "[{}] total entries.".format( len(self._get_dates(topics[i]))))) code, topic = self.d.menu("Select a topic for date: {0}".format(date), choices=menu_choices, width=self.d.maxsize()[1], extra_button=True, extra_label="New...", ok_label="Select") if code == self.d.OK: self._open_entry(topic, date) self.do_topic_browse_by_date(date) elif code == self.d.EXTRA: input_code, input_topic = self.d.inputbox( "Creating a new topic for today: {}".format(date), width=self.d.maxsize()[1]) if input_code == self.d.OK: self.do_new_topic(input_topic) else: self.do_topic_browse_by_date(date) else: self.do_browse_topics() # browse dates for a specific topic def do_date_browse_by_topic(self, topic): dates = self._get_dates(topic) menu_choices = list() for i in range(len(dates)): menu_choices.append( (dates[i], "{} total topics.".format(len(self._get_topics(dates[i]))))) code, date = self.d.menu("Select a date for topic: {0}".format(topic), choices=menu_choices, width=self.d.maxsize()[1], cancel_label="Back", ok_label="Select") if code == self.d.OK: self._open_entry(topic, date) self.do_topic_browse_by_date(date) else: self.do_browse_topics() # return a list of tasks def _get_todos(self, complete=False): result = list() for file in sorted( glob.glob(f"{self.config.get_journal_path()}**/*", recursive=False)): with open(file) as _file: for position, line in enumerate(_file.readlines()): m = re.search("^TODO(.+?)$", line.rstrip().lstrip()) if m: task = Task(file, m.group(1).rstrip().lstrip(), position) if complete == True: # we only want completed tasks if self._check_task_completion(task): result.append(task) else: # we only want incomplete tasks if not self._check_task_completion(task): result.append(task) return sorted(result, key=lambda r: r.topic, reverse=True) # check if task is completed def _check_task_completion(self, task): # check if self.config.tracker file is there # create it if not exists # open self.config.tracker file # iterate through lines # find line that begins with hash if not os.path.exists(self.config.tracker): f = open(self.config.tracker, 'w+') f.close() with open(self.config.tracker, 'r') as tracker_file: for line in tracker_file: m = re.search("^{0}\t.*$".format(task.hash), line) if m: return True return False def _mark_task_complete(self, task): print("marking task {} complete".format(task.hash)) with open(self.config.tracker, 'a+') as tracker_file: tracker_file.write("{0}\t{1}:{2}\t{3}\t{4}\n".format( task.hash, task.creation_date, self._get_current_date(), task.topic, task.text)) def _mark_task_incomplete(self, task): print("marking task {} complete".format(task.hash)) # remove any line that starts with this hash with open(self.config.tracker, 'r') as tracker_file_r: lines = tracker_file_r.readlines() with open(self.config.tracker, 'w') as tracker_file_w: t = [] for line in lines: if not line.startswith(task.hash): tracker_file_w.write(line) def do_browse_completed_todo(self): choices = list() todos = self._get_todos(complete=True) for todo in todos: choices.append( (todo.hash, "({0}) {1}".format(todo.topic, todo.text), False)) if len(choices) > 0: code, hashes_marked_incomplete = self.d.checklist( text="Completed Tasks", choices=choices, backtitle="Select tasks to remark as incomplete...", width=self.d.maxsize()[1], ok_label="Re-Open", cancel_label="Pending Tasks", help_button=True, help_label="Journal") if code == self.d.OK: # mark these tasks as open by removing from the file tasks_to_open = list() for task in todos: for item in hashes_marked_incomplete: if todo.hash == item: tasks_to_open.append(task) for selection in tasks_to_open: self._mark_task_incomplete(selection) if code == self.d.CANCEL: # go to pending tasks view self.do_browse_todo_entries() if code == self.d.HELP: # go to journal view self.do_browse_topics() else: # no completed tasks, go to incomplete tasks view self.do_browse_todo_entries() def do_browse_todo_entries(self): choices = list() todos = self._get_todos(complete=False) for todo in todos: choices.append( (todo.hash, "({0}) {1}".format(todo.topic, todo.text), False)) if len(choices) > 0: code, hashes_marked_complete = self.d.checklist( text="Incomplete Tasks", choices=choices, backtitle="Select tasks to complete.", width=self.d.maxsize()[1], cancel_label="Journal", ok_label="Complete", extra_button=True, extra_label="Log...") if code == self.d.OK: # it only returns the hashes # we want to create a new list of tasks for tasks that should be completed tasks_to_complete = list() # iterate through all tasks so nothing gets missed for todo in todos: # in each iteration we want to iterate through the hashes marked complete and add tasks # with a matching hash to that new list for item in hashes_marked_complete: if todo.hash == item: tasks_to_complete.append(todo) for selection in tasks_to_complete: self._mark_task_complete(selection) elif code == self.d.CANCEL: self.do_browse_topics() elif code == self.d.EXTRA: self.do_browse_completed_todo() else: # no todo items self.do_browse_topics() def create_new_topic_ui(self): input_code, input_topic = self.d.inputbox( "Creating a new topic for today: {}".format( self._get_current_date()), width=self.d.maxsize()[1]) if input_code == self.d.OK: self.do_new_topic(input_topic) self.do_browse_topics() else: self.do_browse_topics() # browse topics for all dates def do_browse_topics(self): topics = self._get_all_topics() if len(topics) > 0: menu_choices = list() for i in range(len(topics)): menu_choices.append((topics[i], "{} total entries.".format( len(self._get_dates(topics[i]))))) code, topic = self.d.menu( "Select a topic whose dated entries you want to browse:", choices=menu_choices, width=self.d.maxsize()[1], cancel_label="Exit", ok_label="Select", extra_button=True, extra_label="New topic for today...", help_label="Task Manager", help_button=True) if code == self.d.OK: self.do_date_browse_by_topic(topic) elif code == self.d.EXTRA: self.create_new_topic_ui() elif code == self.d.HELP: self.do_browse_todo_entries() else: # no topics yet, create one self.create_new_topic_ui() # browse dates for all topics def do_list_dates(self): dates = sorted(self._get_all_dates()) menu_choices = list() for i in range(len(dates)): menu_choices.append( (dates[i], "{} total topics.".format(len(self._get_topics(dates[i]))))) code, date = self.d.menu( "Select a date to browse topics for that date...", choices=menu_choices, width=self.d.maxsize()[1]) if code == self.d.OK: self.do_topic_browse_by_date(date) def do_new_topic(self, topic): self._open_entry(topic, self._get_current_date())
def main(): if getpass.getuser() != "hadoop": raise_error("Please start from user hadoop") slaves_file = "/opt/hadoop/etc/hadoop/slaves" nodes_excluded_file = "/opt/hadoop/etc/hadoop/nodes.exlude" with open(slaves_file) as f: slaves_lines = f.read().splitlines() f.close() with open(nodes_excluded_file) as f: nodes_excluded_lines = f.read().splitlines() f.close() choices_list = [] for node in slaves_lines: if len(node) > 5: if node in nodes_excluded_lines: choices_list.append((node, '', True)) else: choices_list.append((node, '', False)) dialog = Dialog(dialog='dialog') (code, hosts) = dialog.checklist(text="Decommiss nodes managment", height=35, width=64, list_height=20, title="Decommiss nodes managment", backtitle="Decommiss nodes managment", choices=choices_list) if hosts != nodes_excluded_lines and code == dialog.OK: dialog.infobox("Write new nodes.exlude file") f = open(nodes_excluded_file, 'w') for host in hosts: f.write("{}\n".format(host)) f.close() hosts.sort() nodes_excluded_lines.sort() dialog.infobox("Refresh nodes") run_cmds([ "/opt/hadoop/bin/hdfs dfsadmin -refreshNodes", "/opt/hadoop/bin/yarn rmadmin -refreshNodes" ]) online_hosts = list(set(nodes_excluded_lines) - set(hosts)) if len(online_hosts) > 0: dialog.infobox( "Starting datanode and nodemanager on the {}".format( " ".join(online_hosts))) for host in online_hosts: hadoop_sbin_path = "/opt/hadoop/sbin" run_cmds([ "/usr/bin/ssh {} {}/hadoop-daemon.sh start datanode".format( host, hadoop_sbin_path), "/usr/bin/ssh {} {}/yarn-daemon.sh start nodemanager".format( host, hadoop_sbin_path) ], ignore_errors=True) timeout = 30 * 60 duration = 0 progress = 0 decommissioning_done = False time.sleep(30) dialog.gauge_start("Decommissioning in progress") while not decommissioning_done: output, error = run_cmd( "/opt/hadoop/bin/hdfs dfsadmin -report -decommissioning") if ("Decommission in progress" in output or "Decommission in progress" in error): progress += 1 dialog.gauge_update(progress) time.sleep(30) duration += 30 else: decommissioning_done = True if duration > timeout: raise_error("Decommissioning timeout") dialog.gauge_update(100) dialog.gauge_stop()
def editor(): if platform.system()=="Linux" or platform.system()=="Darwin" or platform.system()=="Haiku" or "BSD" in platform.system(): from dialog import Dialog, ExecutableNotFound #Check if config manually specified if args.config != None: if os.path.isfile(args.config): config = configparser.ConfigParser() config.read(args.config) configPath = args.config else: print("Invalid config file location specified: " + args.config) exit() else: #Load config from ~/.iicalc try: home = os.path.expanduser("~") print("Loading config...") config = configparser.ConfigParser() config.read(home + "/.iicalc/config.ini") config["paths"]["userPath"]=config["paths"]["userPath"].format(home) configPath = home + "/.iicalc/config.ini" with open(configPath, "w") as configFile: config.write(configFile) configFile.close() #Load config from current directory except: try: print("Loading portable config...") config = configparser.ConfigParser() config.read("config.ini") configPath = "config.ini" except: print("Fatal error: Cannot load config") exit() try: d = Dialog(dialog="dialog") except ExecutableNotFound: print(theme["styles"]["error"] + "Dialog Execeutable Not Found. (Try installing \'dialog\' with your package manager)" + theme["styles"]["normal"]) return while True: #Define menu options choices = [("Theme", "The colors the calculator will use"), ("Prompt", "The prompt that will be displayed"), ("Update", "Update to the latest version of ImaginaryInfinity Calculator"), ("Plugins", "Enable/disable plugins"), ("Safe mode", "Disable all plugins except core and settings"), ("Server Wakeup", "Start the index server on start"), ("Debug Mode", "Enable/disable debug mode"), ("Check for Updates", "Check for Updates on Starup"), ("Update Channel", "Switch which branch you\'re updating from") ] for plugin in plugins(False): try: exec("from plugins import " + plugin[:-3]) exec("choices += " + plugin[:-3] + ".settings.choices") except Exception as e: pass #print(e); import traceback; traceback.print_exc(); import sys; sys.exit(0) choices += [("Save and exit", "Exit the settings editor"), ("Exit without saving", "Exit the settings editor without saving changes")] #Display menu code, tag = d.menu("ImaginaryInfinity Calculator Settings", choices=choices, width=0, height=0, cancel_label="Quit") if code == d.OK: clear() #Theme settings if tag == "Theme": themeFiles = os.listdir(config["paths"]["userPath"] + "/themes/") + os.listdir(config["paths"]["systemPath"] + "/themes/") themeFiles.remove(".placeholder") if len(themeFiles) == 0: d.msgbox("No themes installed") pass else: choices = [] for themeFile in themeFiles: themeInfo = configparser.ConfigParser() if os.path.exists(config["paths"]["userPath"] + "/themes/" + themeFile): themeInfo.read(config["paths"]["userPath"] + "/themes/" + themeFile) else: themeInfo.read(config["paths"]["systemPath"] + "/themes/" + themeFile) try: print(themeInfo["theme"]["name"]) choices.append((themeInfo["theme"]["name"], themeInfo["theme"]["description"])) except: print("Invalid theme") tcode, ttag = d.menu("ImaginaryInfinity Calculator Theme Settings", choices=choices, width=0, height=0) if tcode == d.OK: themeFiles = os.listdir(config["paths"]["userPath"] + "/themes/") + os.listdir(config["paths"]["systemPath"] + "/themes/") themeFiles.remove(".placeholder") for themeFile in themeFiles: themeInfo = configparser.ConfigParser() if os.path.exists(config["paths"]["userPath"] + "/themes/" + themeFile): themeInfo.read(config["paths"]["userPath"] + "/themes/" + themeFile) else: themeInfo.read(config["paths"]["systemPath"] + "/themes/" + themeFile) if themeInfo["theme"]["name"] == ttag: config["appearance"]["theme"] = themeFile else: clear() #Prompt settings elif tag == "Prompt": #print(config) #import sys #sys.exit(0) pcode, pstring = d.inputbox("ImaginaryInfinity Calculator Prompt Settings", init = config["appearance"]["prompt"]) if pcode == d.OK: config["appearance"]["prompt"] = pstring else: clear() elif tag=="Update": update() elif tag=="Plugins": pluginslist = plugins(False) i=0 if len(pluginslist) > 0: for plugin in pluginslist: if plugin[-3:] == ".py": pluginslist[i] = (plugin, plugin, True) if plugin[-9:] == ".disabled": pluginslist[i] = (plugin, plugin, False) i += 1 pcode, ptags = d.checklist("Plugins", choices=pluginslist, height=0, width=0) i=0 #print(ptags) for plugin in pluginslist: if not plugin[0][-9:] == ".disabled" and not plugin[0] in ptags: os.rename(config["paths"]["userPath"] + "/plugins/" + plugin[0], config["paths"]["userPath"] + "/plugins/" + plugin[0] + ".disabled") if plugin[0][-9:] == ".disabled" and plugin[0] in ptags: os.rename(config["paths"]["userPath"] + "/plugins/" + plugin[0], config["paths"]["userPath"] + "/plugins/" + plugin[0][:-9]) else: d.msgbox("You have not installed any plugins.") #Safe mode settings elif tag=="Safe mode": scode, stag = d.menu("ImaginaryInfinity Calculator Safe Mode Settings", choices=[("On", "Enable safe mode"), ("Off", "Disable safe mode")], width=0, height=0) if scode == d.OK: if stag == "On": config["startup"]["safemode"] = "true" if stag == "Off": config["startup"]["safemode"] = "false" #Server wakeup settings elif tag == "Server Wakeup": startserver = d.menu("ImaginaryInfinity Calculator Server Wakeup", choices=[("On", "Enable starting server on start"), ("Off", "Disable starting server on start")]) if startserver[0] == d.OK: if startserver[1] == "On": config["startup"]["startserver"] = "true" else: config["startup"]["startserver"] = "false" #Debug mode settings elif tag == "Debug Mode": debugmode = d.menu("ImaginaryInfinity Calculator Debug Settings", choices=[("On", "Enable debug mode"), ("Off", "Disable debug mode")]) if debugmode[0] == d.OK: if debugmode[1] == "On": config["dev"]["debug"] = "true" else: config["dev"]["debug"] = "false" #Check for updates settings elif tag == "Check for Updates": checkupdates = d.menu("ImaginaryInfinity Calculator Update Checker Settings", choices=[("On", "Enable checking for updates"), ("Off", "Disable checking for updates")]) if checkupdates[0] == d.OK: if checkupdates[1] == "On": config["startup"]["checkupdates"] = "true" else: config["startup"]["checkupdates"] = "false" #Branch settings elif tag == "Update Channel": updatechannel = d.menu("ImaginaryInfinity Calculator Update Channel Settings", choices=[("Master", "This branch is the default stable branch"), ("Development", "This branch may have unstable beta features")]) if updatechannel[0] == d.OK: if updatechannel[1] == "Master": config["updates"]["branch"] = "master" else: config["updates"]["branch"] = "development" #Close settings without modifying config elif tag == "Save and exit": with open(configPath, "w") as configFile: config.write(configFile) configFile.close() break #Close settings and write changes to config elif tag == "Exit without saving": break else: config = signal("settingsPopup", config, "\"" + tag + "\"") else: code = d.yesno("Save changes?") if code == d.OK: tag = "Save and exit" else: tag = "" break #Prompt to restart to apply settings if tag == "Save and exit": restartbox = Dialog(dialog="dialog").yesno("Your settings have been saved. Some settings may require a restart to take effect. Would you like to restart?", width=0, height=0) if restartbox == "ok": clear() restart() else: clear() else: clear() #Display messages for unsupported operating systems elif platform.system() == "Windows": print("The setting editor does not support Windows. Don't start an issue, support will not be added.") else: print("The settings editor is not supported on your OS, start an issue and support for your OS may be added.")
def settingsPopup(tag, config): if tag == "Discord RPC Settings": choices = [( "Discord Rich Presence", "Display ImaginaryInfinity Calculator as your status in Discord" ), ("Dynamic RPC", "Update Discord RPC on calculation"), ("Plugins and Themes in RPC", "Show number of Installed Plugins/Themes"), ("Buttons", "Show buttons in RPC"), ("iiCalc Version", "Show iiCalc version"), ("Debug", "Debug Mode")] d = Dialog(autowidgetsize=True) default_selection = choices[0][0] while True: drpcmenu = d.menu("Discord RPC Settings", choices=choices, cancel_label="Back", default_item=default_selection) if drpcmenu[0] == d.OK: default_selection = drpcmenu[1] if drpcmenu[1] == "Discord Rich Presence": try: default = utils.getDefaultBoolMenuOption( config['discord']['enableRPC']) except AttributeError: default = "On" x = d.menu("Discord Rich Presence", choices=[("On", "Enable Discord RPC"), ("Off", "Disable Discord RPC")], default_item=default) if x[0] == d.OK: if x[1] == "On": config["discord"]["enableRPC"] = "true" else: config["discord"]["enableRPC"] = "false" elif drpcmenu[1] == "Dynamic RPC": try: default = utils.getDefaultBoolMenuOption( config['discord']['dynamicPresence']) except AttributeError: default = "On" x = d.menu( "Update Discord RPC with your last done calculation", choices=[("On", "Enable Dynamic RPC"), ("Off", "Disable Dynamic RPC")], default_item=default) if x[0] == d.OK: if x[1] == "On": config["discord"]["dynamicPresence"] = "true" else: config["discord"]["dynamicPresence"] = "false" elif drpcmenu[1] == "Plugins and Themes in RPC": pluginStatus = "on" if config["discord"][ "showAmountOfPlugins"] == "true" else "off" themeStatus = "on" if config["discord"][ "showAmountOfThemes"] == "true" else "off" x = d.checklist( "Show number of installed plugins/themes", choices=[ ("Plugins", "Show number of installed plugins", pluginStatus), ("Themes", "Show number of installed themes", themeStatus) ]) if x[0] == d.OK: if "Plugins" in x[1]: config["discord"][ "showAmountOfPlugins"] = "true" else: config["discord"][ "showAmountOfPlugins"] = "false" if "Themes" in x[1]: config["discord"][ "showAmountOfThemes"] = "true" else: config["discord"][ "showAmountOfThemes"] = "false" elif drpcmenu[1] == "Buttons": try: default = utils.getDefaultBoolMenuOption( config['discord']['showButtons']) except AttributeError: default = "On" x = d.menu("Show Buttons", choices=[("On", "Show buttons in RPC"), ("Off", "Hide buttons in RPC")], default_item=default) if x[0] == d.OK: if x[1] == "On": config["discord"]["showButtons"] = "true" else: config["discord"]["showButtons"] = "false" elif drpcmenu[1] == "Debug": try: default = utils.getDefaultBoolMenuOption( config['discord']['debug']) except AttributeError: default = "On" x = d.menu("Debug Mode", choices=[("On", "Debug mode on"), ("Off", "Debug mode off")], default_item=default) if x[0] == d.OK: if x[1] == "On": config["discord"]["debug"] = "true" else: config["discord"]["debug"] = "false" elif drpcmenu[1] == "iiCalc Version": try: default = utils.getDefaultBoolMenuOption( config['discord']['showversion']) except AttributeError: default = "On" x = d.menu("iiCalc Version", choices=[ ("On", "Show iiCalc version in status"), ("Off", "Don\'t show iiCalc version in status") ], default_item=default) if x[0] == d.OK: if x[1] == "On": config["discord"]["showversion"] = "true" else: config["discord"]["showversion"] = "false" else: break return config
print(u"사용자에의해 취소 되었습니다.") sys.exit() else: d.infobox(text=processingMsg) code, path = d.dselect(filepath=os.path.abspath(args.destination), width=50) if code == d.CANCEL: print(u"사용자에의해 취소 되었습니다.") sys.exit() """ 주소를 arguments로 직접 입력하였을시 빈 화면이 오래 보여지는 것 대신 처리중 문구를 보여 주기 위함. """ d.infobox(text=processingMsg) pyt = Playlist(url if url else args.playlisturl, path) d.infobox(text=processingMsg) code, tags = d.checklist(u"다운받을 영상을 선택하세요.", choices=[(item.code, item.title, True) for item in pyt.items]) pyt.checkDownload(tags=tags) d.infobox(text=processingMsg) if code == d.OK: lock = threading.Lock() def downloadFnc(item): pyt.download(int(item.code), on_progress_callback=progress_function) for n in pyt.items: doenloadThread = threading.Thread(target=downloadFnc, args=(n,)) doenloadThread.start()
def main(): parser = argparse.ArgumentParser(description='Interactive SQL runner.') parser.add_argument('config', type=str, help='Path to the config file') parser.add_argument('--database', help='Database name', nargs='?', default=False) args = parser.parse_args() with open(args.config) as fp: config = json.load(fp) sqlpath = config['sql_path'] del config d = Dialog(dialog="dialog") d.set_background_title("SQL Runner") code, action = d.menu( "What do you want to do?", choices= [('execute', 'Execute statements based on the provided list of CSV command files' ), ('test', 'Test execution of statements based on the provided list of CSV command files' ), ('staging', 'Executes commands as specified, but in staging schema'), ('deps', 'View dependencies graph'), ('clean', 'Schemata prefix to clean up')], title="What do you want to do?", backtitle="Interactive SQL Runner") if code != d.OK: Popen(["clear"]).wait() return cmd_args = [] if args.database: cmd_args += ['--database', args.database] if action != 'deps': available_files = list((os.path.basename(f).split('.')[0], "", False) for f in glob.glob(sqlpath + "/*.csv")) available_files.sort() code, files = d.checklist("Press Space to select", choices=available_files, title="Which files to run?", backtitle="Interactive SQL Runner") if code != d.OK: Popen(["clear"]).wait() return if files: cmd_args += ['--' + action] + files else: Popen(["clear"]).wait() return else: cmd_args += ['--' + action] Popen(["clear"]).wait() args = ["runner", '--config', args.config] + cmd_args print(" ".join(args)) proc = Popen(args) proc.wait()
class commitGUI(): """ Class that steps through a dialog and asks the user for the required input. The input will be validated immediatly. """ def __init__(self, commit_message, args): self.commit_message = commit_message self.d = Dialog(dialog="dialog") self.d.set_background_title("Git commit for SUSE documentation") self.interactive = True if args.interactive is True else False self.editor = True if args.editor is True else False self.argument_files(args) def argument_files(self, args): """ Parse argument files and paths """ if args.files is not None: for file in args.files: if os.path.isfile(file): self.commit_message.docrepo.stage_add_file(file) elif os.path.isdir(file) and not file == '.': for root, dirs, files in os.walk(file): for walkfile in files: self.commit_message.docrepo.stage_add_file( root + walkfile) def select_files(self): """ Dialog widget with file selection """ all_files = [] for filename, status in self.commit_message.docrepo.stage(): all_files.append(filename) if not all_files: print("No changed files in repository. Exiting ...") self.commit_message.docrepo.reset_repo() quit() code, filenames = self.d.checklist( "Select files", choices=[ (filename, "", status) for filename, status in self.commit_message.docrepo.stage() ], title="Select the files that should be committed.") if code == "cancel": self.commit_message.docrepo.reset_repo() quit() else: self.commit_message.docrepo.reset_repo() got_file = False for filename in filenames: self.commit_message.docrepo.stage_add_file(filename) got_file = True if got_file: self.show_diff() else: print("No files selected.") quit() def show_diff(self): """ Show the diff of staged files """ self.d.scrollbox(self.commit_message.docrepo.diff(True), height=30, width=78, \ title="Diff of staged files") self.enter_subject() def enter_subject(self, error=False): """ Dialog widget that asks for the subject """ if error: subject_info_temp = "# Invalid subject!\n" + subject_info else: subject_info_temp = subject_info code, self.commit_message.subject = self.d.inputbox( subject_info_temp, height=15, width=56, init=self.commit_message.subject) if code == 'cancel': self.commit_message.docrepo.reset_repo() quit() else: if self.commit_message.validate_subject(): self.enter_message() else: self.enter_subject(True) def enter_message(self, problems=None): """ Dialog widget that asks for the main message. This message is used for the docupdate section. """ global message_info message_info_tmp = message_info if problems is not None: message_info_tmp = message_info_tmp + "\nFix the following problems:\n" for problem in problems: message_info_tmp = message_info_tmp + "* " + problem + "\n" message_info_tmp = message_info_tmp + "\n" + \ self.commit_message.input_message code, txt = self.d.editbox_str(message_info_tmp, height=30, width=78) if code == 'cancel': self.commit_message.docrepo.reset_repo() quit() else: self.commit_message.input_message = \ "\n".join([line for line in txt.splitlines() if not line.startswith("#")]) self.commit_message.problems = [] if not self.commit_message.validate_message(): self.enter_message(self.commit_message.problems) else: self.enter_xml_ids() def enter_xml_ids(self, unknown_ids=None): """ Dialog widget that asks for the XML IDs """ global id_info id_info_tmp = id_info if unknown_ids is not None: id_info_tmp = id_info_tmp + "\n\nThe following XML IDs are invalid:\n" for xml_id in unknown_ids: id_info_tmp = id_info_tmp + "* " + xml_id + "\n" code, self.commit_message.xml_ids = self.d.inputbox( id_info_tmp, height=20, width=78, init=self.commit_message.xml_ids) if code == 'cancel': self.commit_message.docrepo.reset_repo() quit() self.commit_message.problems = [] if not self.commit_message.validate_xml_ids(): self.enter_xml_ids(self.commit_message.problems) self.enter_references() def enter_references(self, invalid_references=None): """ Dialog widget that asks for the references (BSC, FATE, etc.) """ global reference_info reference_info_tmp = reference_info if invalid_references is not None: reference_info_tmp = reference_info_tmp + "\n\nThe following references are invalid:\n" for reference in invalid_references: reference_info_tmp = reference_info_tmp + "* " + reference + "\n" code, self.commit_message.reference = \ self.d.inputbox(reference_info_tmp, height=20, width=78, init=self.commit_message.reference) if code == 'cancel': self.commit_message.docrepo.reset_repo() quit() self.commit_message.problems = [] if not self.commit_message.validate_references(): self.enter_references(self.commit_message.problems) self.enter_commits() def enter_commits(self, invalid_commits=None): """ Dialog widget that asks for commit hashes for mergers in doc updates """ global commit_info commit_info_tmp = commit_info if invalid_commits is not None: commit_info_tmp = commit_info_tmp + "\n\nThe following commit hashes are invalid:\n" for commit in invalid_commits: commit_info_tmp = commit_info_tmp + "* " + commit + "\n" code, self.commit_message.merge_commits = \ self.d.inputbox(commit_info_tmp, height=15, width=78, init=self.commit_message.merge_commits) if code == 'cancel': self.commit_message.docrepo.reset_repo() quit() self.commit_message.problems = [] if self.commit_message.merge_commits and not self.commit_message.validate_merge_commits( ): self.enter_commits(self.commit_message.problems) self.final_check() def final_check(self): """ Format commit message and display either in dialog or in editor """ text = "" if not self.commit_message.format( self.editor or (not self.interactive and not self.editor)): text = """# # !!! WARNING !!! # # The following problems have been found:\n""" for item in self.commit_message.problems: text = text + "# * " + item + "\n" text = text + '\n' commit = False else: commit = True # If neither interactive mode nor editor is selected, use editor if not self.interactive or self.editor: with open('/tmp/.doccommit', 'w') as tmpfile: tmpfile.write(text + self.commit_message.final_message) subprocess.call(['vim', '/tmp/.doccommit']) self.commit_message.parse_commit_message( open('/tmp/.doccommit', 'r').read()) self.commit_message.problems = [] if self.commit_message.validate(): asdf = input("Do you want to commit? [Y|n] ") if asdf.lower() != 'y' and asdf != '': quit() self.commit_message.docrepo.reset_repo() else: self.commit_message.commit(True) quit() else: asdf = input("Your input does not validate. Retry? [Y|n] ") if asdf.lower() == 'n': self.commit_message.docrepo.reset_repo() quit() else: self.final_check() # if interactive mode is used else: if commit: title = "Final check" text = self.commit_message.final_message + "\n\n# ---\n# Do you want to commit?" else: title = "Linting result" text = text + self.commit_message.final_message + "\n\n\n# Return to beginning?" code = self.d.yesno(text, height=30, width=78, title=title) if code == "ok" and commit: self.commit_message.commit(True) quit() elif code == "ok" and not commit: self.enter_subject() else: self.commit_message.docrepo.reset_repo() quit()
class STATES: #Current State current_state = 0 def __init__(self): #State : 0 locale.setlocale(locale.LC_ALL, '') self.text_port = "2222" self.text_host = "[email protected]" self.text_pass = "******" self.text_host_dir = "[email protected]:/home/pardus/Masaüstü/." self.path = "/home/" + pwd.getpwuid(os.getuid())[0] + "/Masaüstü/" self.d = Dialog(dialog="dialog") self.d.set_background_title("Yolla Gitsin Moruq") self.current_state = 1 def state_info(self): #State : 01 self.d.msgbox( "Hoş Geldiniz!\n\nLütfen dosyaların taşınmasını istediğiniz bilgisayarda openssh-server uygulamasının kurulu olduğundan emin olun.", width=40, height=12) self.current_state = 2 def state_02(self): #STATE 2 #Config Setting to Connect PC isDone, tag, text = self.d.inputmenu( "Bağlanılacak bilgisayarın bilgilerini giriniz", height=18, menu_height=16, choices=[("Port", self.text_port), ("Host", self.text_host), ("Host_Direction", self.text_host_dir), ("Password", self.text_pass)]) if (isDone == 'renamed'): if (tag == 'Port'): self.text_port = text elif tag == "Password": self.text_pass = text elif tag == "Host": self.text_host = text elif tag == "Host_Direction": self.text_host_dir = text elif (isDone == 'accepted'): self.current_state += 1 else: self.current_state -= 1 def state_03(self): #State : 03 code = self.d.yesno("SSH Key üretilsin mi?") if (code == self.d.OK): self.current_state = 4 #7. State'e dallan else: self.current_state = 7 def state_04(self): #State : 04 #SSH-KEYGEN os.popen("rm -rf ~/.ssh") output = Popen(['ssh-keygen', '-t', 'rsa'], stdout=PIPE, stdin=PIPE) output.stdin.write("\n\n\n".encode()) output.stdin.close() output.wait() self.d.infobox("SSH KEY'ler oluşturuldu.", width=0, height=0, title="Başarılı") time.sleep(2) self.current_state = 5 def state_05(self): #State : 05 #ALERT : SSH-KEY Karşı Bilgisayar Kopyalanıcak self.d.infobox("Public KEY karşı pc'ye kopyalanıcak") time.sleep(1) self.current_state = 6 def state_06(self): #State : 06 #SSH-COPY-ID output2 = Popen([ 'sshpass -p "{}" ssh-copy-id -o StrictHostKeyChecking=no -p {} {} ' .format(self.text_pass, self.text_port, self.text_host) ], stdout=PIPE, stdin=PIPE, shell=True) output2.stdin.close() output2.wait() self.d.infobox("SSH KEY'ler aktarıldı.", width=0, height=0, title="Başarılı") time.sleep(1) self.current_state = 8 def state_07(self): #State : 07 #SSH-KEYGEN ÜRETİLMEDEN çalıştırma self.d.infobox("SSH KEY üretilmeden devam ediliyor.", width=40, height=3) time.sleep(2) self.current_state = 8 def state_08(self): #State : 08 isDone, temp_path = self.d.dselect(self.path) if not (temp_path == ""): self.path = temp_path if isDone == 'ok': self.current_state = 9 else: self.current_state = 2 def state_09(self): #State : 09 onlyfiles = [ f for f in os.listdir(self.path) if os.path.isfile(os.path.join(self.path, f)) ] onlyfiles_len = len(onlyfiles) info4files = [] for i in range(onlyfiles_len): info4files.append((onlyfiles[i], "", False)) code, send_files = self.d.checklist("Gönderilecek dosyaları seç", height=20, choices=info4files) if code == 'cancel': self.current_state = 8 elif code == 'ok': send_files_len = len(send_files) if (send_files_len == 0): self.d.infobox("Dosya Seçilmedi") time.sleep(2) else: for i in range(send_files_len): output3 = Popen([ 'sshpass -p "{}" scp -P {} {} {}'.format( self.text_pass, self.text_port, os.path.join(self.path, send_files[i]), self.text_host_dir) ], stdin=PIPE, stdout=PIPE, shell=True) output3.stdin.close() out = output3.stdout.read().decode("utf-8") self.d.infobox(text=out) output3.wait() self.current_state = 10 def state_repeat(self): #State : 10 code = self.d.yesno("Dosya Yollamaya devam etmek ister misiniz?", yes_label="Yes Baba", no_label="No Baba") if (code == 'ok'): self.current_state = 8 else: self.current_state = 11 def state_final(self): #State : 11 self.d.infobox("Çıkıyor Moruq") time.sleep(2) def state_login(self): #2 code = self.d.yesno("Eski oturumlarla devam et", yes_label="Yes Baba", no_label="No Baba") if code == "ok": self.current_state = 21 else: self.current_state = 22 def state_login_read(self): # state 2.1 = 21 try: _choices = [] with open("Conf/conf.json", "r") as f: conf = json.load(f) for i in range(len(conf["user"])): _str = "{}".format(conf["user"][i]["host"]) _choices.append((str(i), _str, False)) code, tag = self.d.radiolist("kullanıcı ekranı", height=15, choices=_choices) if code == "ok": self.text_port = conf["user"][int(tag)]["port"] self.text_host = conf["user"][int(tag)]["host"] self.text_pass = conf["user"][int(tag)]["pass"] self.text_host_dir = conf["user"][int(tag)]["host_dir"] self.current_state = 3 else: self.current_state = 2 except (FileNotFoundError): self.d.infobox("Eski Oturum Bulunumadı!") time.sleep(2) self.current_state = 2 def state_login_create(self): #State : 2.2 - 22 isDone, tag, text = self.d.inputmenu( "Bağlanılacak bilgisayarın bilgilerini giriniz", height=18, menu_height=16, choices=[("Port", self.text_port), ("Host", self.text_host), ("Host_Direction", self.text_host_dir), ("Password", self.text_pass)]) if (isDone == 'renamed'): if (tag == 'Port'): self.text_port = text elif tag == "Password": self.text_pass = text elif tag == "Host": self.text_host = text elif tag == "Host_Direction": self.text_host_dir = text elif (isDone == 'accepted'): conf = {} append_data = { "port": self.text_port, "host": self.text_host, "pass": self.text_pass, "host_dir": self.text_host_dir } isSameData = False try: #Eğer dosya oluşturulduysa with open("Conf/conf.json", "r") as f: conf = json.load(f) isSameData = CONTROLLER.isDictSame(append_data, conf["user"]) except: conf = {"user": []} os.mkdir("Conf") finally: if not (isSameData): with open("Conf/conf.json", "w") as f: conf["user"].append(append_data) json.dump(conf, f, indent=4) self.current_state = 3 else: self.d.infobox("Daha önceden kaydedilmiş içerik.") time.sleep(2) self.current_state = 2 else: self.current_state = 2
d.set_background_title("Basit bir program") # For older versions, you can use: # d.add_persistent_args(["--backtitle", "Basit bir program"]) # In pythondialog 3.x, you can compare the return code to d.OK, Dialog.OK or # "ok" (same object). In pythondialog 2.x, you have to use d.DIALOG_OK, which # is deprecated since version 3.0.0. if d.yesno("Detayları görmek istiyor musun?") == d.OK: d.msgbox("Peki o zaman...") # We could put non-empty items here (not only the tag for each entry) code, tags = d.checklist("Tercihini yap?", choices=[("Kedi", "", False), ("Köpek", "", False), ("At", "", False), ("Kuş", "", True), ("Aslan","", True), ("Pardus", "", True)], title="Hangilerini tercih edersin?", backtitle="Öylesine şeyler " "completely different...") if code == d.OK: # 'tags' now contains a list of the toppings chosen by the user pass else: code, tag = d.menu("OK, o zaman iki seçeneğin var:", choices=[("(1)", "Çıkabilirim"), ("(2)", "Çıkabilirim")]) if code == d.OK: # 'tag' is now either "(1)" or "(2)" pass
def dialog_board_list(**kwargs): width = str(100) height = str(30) menu_height = str(28) list_height = menu_height checklist = kwargs.get("checklist","") selection = kwargs.get("selection","") check_enable = False check_standby = False check_select = False if checklist == "enable": check_enable = True if checklist == "standby": check_standby = True if checklist == "select": check_select = True empty_selection = False if selection == "none": empty_selection = True d = Dialog(dialog="dialog") d.set_background_title("view boards") if check_enable: d.set_background_title("enable/disable boards") if check_standby: d.set_background_title("set boards to standby") if check_select: d.set_background_title("select one or more boards") choices = [] info_format = "{:>6s} {:>4s} {:>7s} {:>5} {:>12s} {:>6s} {:>6s} {:>6s} {:>7s}" info = info_format.format("TDC", "CONN","chamber","layer","FPC ABCD", "BL cal", "t1 cal", "active","standby") if check_enable or check_standby or check_select: choices += [("board",info, False)] else: choices += [("board",info)] board_list = db.board_list() for board_name in board_list: board_info = db.find_board_by_name(board_name) board_calib = db.get_calib_json_by_name(board_name) bl_calib = " - " if board_info["baseline_is_calibrated"] == 1: bl_calib = "yes" elif board_info["baseline_is_calibrated"] == -1: bl_calib = "err" t1_calib = " - " if board_info["t1_is_calibrated"]: t1_calib = "yes" active = " - " active_bool = False if board_info["active"]: active = "yes" active_bool = True standby = " - " standby_bool = False if "standby" in board_info: if board_info["standby"]: standby = "yes" standby_bool = True info = info_format.format( board_info["tdc_addr"], str(board_info["tdc_connector"]), str(board_info["chamber"]), str(board_info["layer"]), str(board_info["fpc_a"]).rjust(2)+","+ str(board_info["fpc_b"]).rjust(2)+","+ str(board_info["fpc_c"]).rjust(2)+","+ str(board_info["fpc_d"]).rjust(2), bl_calib, t1_calib, active, standby ) if check_enable: if empty_selection: choices += [(board_name,info, False)] else: choices += [(board_name,info, active_bool)] elif check_standby: choices += [(board_name,info, standby_bool)] elif check_select: choices += [(board_name,info, False)] else: choices += [(board_name,info)] if check_enable: code, active_boards = d.checklist("enable/disable boards", choices=choices, width=width, height=height, list_height=list_height) if code == d.DIALOG_OK: for board_name in board_list: db.disable_board(board_name) for board_name in active_boards: if not(board_name == "board"): db.enable_board(board_name) elif check_standby: code, standby_boards = d.checklist("set board standby", choices= choices, width=width,height=height,list_height=list_height) if code == d.DIALOG_OK: for board_name in board_list: db.unset_standby_board(board_name) for board_name in standby_boards: if not(board_name == "board"): db.set_standby_board(board_name) elif check_select: code, selected_boards = d.checklist("select one or more boards", choices= choices, width=width,height=height,list_height=list_height) return code, selected_boards else: code, tag = d.menu("select a board:", choices= choices ,width=width,height=height,menu_height=menu_height) return code, tag
# d.add_persistent_args(["--backtitle", "My little program"]) # In pythondialog 3.x, you can compare the return code to d.OK, Dialog.OK or # "ok" (same object). In pythondialog 2.x, you have to use d.DIALOG_OK, which # is deprecated since version 3.0.0. if d.yesno("Are you REALLY sure you want to see this?") == d.OK: d.msgbox("You have been warned...") # We could put non-empty items here (not only the tag for each entry) code, tags = d.checklist( "What sandwich toppings do you like?", choices=[ ("Catsup", "", False), ("Mustard", "", False), ("Pesto", "", False), ("Mayonnaise", "", True), ("Horse radish", "", True), ("Sun-dried tomatoes", "", True), ], title="Do you prefer ham or spam?", backtitle="And now, for something " "completely different...", ) if code == d.OK: # 'tags' now contains a list of the toppings chosen by the user pass else: code, tag = d.menu( "OK, then you have two options:", choices=[("(1)", "Leave this fascinating example"), ("(2)", "Leave this fascinating example")], ) if code == d.OK:
class gitPlugin: dialog = None lastQueueLock = 0 __gitFilesCount = 0 currentBranch = "" def __init__(self, app): """ Constructor of a plugin :param app: Panthera Framework based application main class object :return: """ self.kernel = app # hook up to args init self.kernel.hooking.addOption('app.argsparsing.init', self.__pluginInit__, priority=98) def __pluginInit__(self, args = ''): """ Initialize the plugin after all dependencies are met :param args: :return: """ ## list all remotes at initialization remotes = self._gitCommand('remote -v') for remote in remotes.replace("\t", ' ').replace(' ', ' ').split("\n"): parts = remote.split(' ') if len(parts) < 3: continue self.kernel.logging.output('Detected git remote: '+parts[1]+' '+parts[2], 'git') if "fatal:" in remotes: self.kernel.logging.output('Git responded with a fatal error, '+remotes, 'git') return False ## check branch to display at init status = self._gitCommand('status').split("\n") self.currentBranch = self._gitCommand('rev-parse --abbrev-ref HEAD') self.kernel.logging.output(status[0], 'git') ## initialize interface self.dialog = Dialog(dialog="dialog") if self.kernel.interactive: self.kernel.interactive.recognizedChars['g'] = self.gitMenu ## hook up to queue (to hold on application on branch change) self.kernel.hooking.addOption('app.syncJob.Queue.append.before', self.queueAppendAction, priority=10) def queueAppendAction(self, status): """ On appending to queue :param status: :return: """ if self.kernel.queueLock: status[0] = True if '.git' in status[2]: self.__gitFilesCount = self.__gitFilesCount + 1 if self.kernel.queueLock: self.kernel.logging.output('Removing git lock', 'git') self.kernel.queueLock = False status[0] = True else: if self.__gitFilesCount > 4: branch = self._gitCommand('rev-parse --abbrev-ref HEAD') if branch != self.currentBranch: self.kernel.logging.output('Creating git lock, as branch changed', 'git') self.kernel.queueLock = True self.currentBranch = branch self.__gitFilesCount = 0 return status def gitMenu(self): """ Display a git menu :return: """ ## make application output silently for a moment f = open(os.devnull, 'w') __stdout = sys.stdout sys.stdout = f code, tag = self.dialog.menu("Options", choices=[("(1)", "Add untracked/uncommited files to queue"), ("(2)", "Send commits"), ("(3)", "Revert commits"), ("(4)", "Clear backup files after merge"), ("(5)", "Cancel")]) if tag == '(1)': self.selectAllMenu(callback = self.notCommitedFilesMenu, notCommitedMenu = True) elif tag == '(2)': self.commitsMenu() elif tag == '(3)': self.commitsMenu(revert = True) elif tag == '(4)': self.clearFilesAfterMerge() sys.stdout = __stdout def commitsMenu(self, revert = False): """ Recent commits menu Allows selecting commits to build list of files and send from selected revisions :author: Damian Kęska <*****@*****.**> :return: None """ commits = list() choices = [] log = self._gitCommand('--no-pager log --oneline') i = 0 for line in log.split("\n"): i = i + 1 separator = line.find(' ') commits.append({'id': line[0:separator], 'title': line[(separator+1):], 'number': i}) choices.append(("("+line[0:separator]+")", line[(separator+1):], 0)) if revert: code, tag = self.dialog.checklist("Revert commits (total: "+str(len(commits))+")", choices=choices, width=120, height=20, list_height=10) else: code, tag = self.dialog.checklist("Submit commits (total: "+str(len(commits))+")", choices=choices, width=120, height=20, list_height=10) if tag: if revert: return self._appendCommitRevertFiles(commits, selected=tag) ## array of fileName => contents files = {} i = 0 for commitID in tag: i = i + 1 commitID = commitID.replace('(', '').replace(')', '') filesList = self._gitCommand('diff-tree --no-commit-id --name-only -r '+commitID) if "fatal:" in filesList: self.kernel.logging.output('Cannot get list of files for revision '+commitID, 'git') continue self._appendCommitFiles(commitID, filesList, files, commitNumber = i) def _appendCommitRevertFiles(self, commits, selected): """ Append revert of commits :param commits: List of all avaliable commits :param selected: Selected commits :return: """ selectedList = list() filesList = {} # strip "(" and ")" from commits list for commit in selected: selectedList.append(commit.replace('(', '').replace(')', '')) # we have to preserve list order for commit in commits: # if commit was selected, and its not a first commit if commit['number'] < 2 or not (commit['id'] in selectedList): continue currentCommitFilesList = self._gitCommand('diff-tree --no-commit-id --name-only -r '+commit['id']).split("\n") previousCommitID = commits[commit['number']-2]['id'] for file in currentCommitFilesList: try: filesList[file] = self._gitCommand('show '+previousCommitID+':'+file) except Exception as e: # file propably removed filesList[file] = False self.kernel.appendToQueue(file, forceRemove = True) continue ## append oldest versions of files for file, contents in filesList.iteritems(): self.kernel.appendToQueue(file, contents = contents) def clearFilesAfterMerge(self): """ Clear files that stays after resolved merge conflict eg. with names ".orig" or ".LOCAL" :author: Damian Kęska <*****@*****.**> :return: None """ self._gitCommand('clean -fd') # TODO: Confirmation using clean -n (dry run) self.dialog.msgbox("Cleaned up git directory using 'git clean -fd'\nCurrent git status:\n"+subprocess.check_output('git status', shell=True), width=120, height=30) def selectAllMenu(self, callback, notCommitedMenu = False): choices = [ ("(1)", "All positions checked"), ("(2)", "All positions unchecked") ] if notCommitedMenu: choices.append(("(3)", "Check only tracked")) choices.append(("(4)", "Check only not commited")) code, tag = self.dialog.menu("Start with", choices=choices) checked = 0 if code > 0: return None if tag == '(1)': checked = 1 if notCommitedMenu: if tag == '(3)': return callback(checked = 0, commitedChecked = 0, untrackedChecked = 1) elif tag == '(4)': return callback(checked = 0, commitedChecked = 1, untrackedChecked = 0) return callback(checked=checked) def notCommitedFilesMenu(self, checked = 1, commitedChecked = None, untrackedChecked = None): """ Display menu with list of untracked files to select to add to queue :return: """ choices = [] gitOutput = self._gitCommand('status') # untracked files if untrackedChecked is not None: checked = untrackedChecked posStart = gitOutput.find("(use \"git add <file>...\" to include in what will be committed)\n\n") untrackedBlock = gitOutput[posStart:] for line in untrackedBlock.split("\n")[2:]: if not line: break choices.append((str(line.replace("\t", '')), "(untracked)", checked)) # not commited files if commitedChecked is not None: checked = commitedChecked posStart = gitOutput.find("to update what will be committed)\n") block = gitOutput[posStart:] for line in block.split("\n")[3:]: if not line: break choices.append((str(line.replace("\t", '').replace('modified: ', '')), "", checked)) if not choices: return self.gitMenu() code, tags = self.dialog.checklist("Select untracked files:", choices=choices, width=100, height=25, list_height=18) if tags: for file in tags: self.kernel.appendToQueue(file) else: self.gitMenu() def _appendCommitFiles(self, commitID, filesList, files, commitNumber): """ Helper method for commitsMenu() Appends commited files to queue :param commitID: :param filesList: :param files: "Global" array with list of files we already appended :return: files array """ for file in filesList.split("\n"): if not file or not os.path.isfile(self.kernel.localDirectory + "/" + file): continue if not file in files: files[file] = self._gitCommand('show '+commitID+':'+file) tmp = open(file, 'r') self.kernel.appendToQueue(file, tmp.read()) tmp.close() return files def _gitCommand(self, command): """ Execute a git command :param string command: Command line query string :return: string """ os.chdir(self.kernel.localDirectory) return subprocess.check_output('git '+command, shell = True)
class FormDialog: """ Property that stores an object of type Dialog. """ d = None """ Property that stores an object of type Utils. """ utils = None """ Property that stores an object of type Elastic. """ elastic = None """ Property that stores an object of type Logger. """ logger = None """ Property that stores an object of type Telegram. """ telegram = None configuration = None """ Constructor for the FormDialog class. Parameters: self -- An instantiated object of the FormDialog class. """ def __init__(self): self.d = Dialog(dialog="dialog") self.logger = Logger() self.utils = Utils(self) self.elastic = Elastic(self) self.telegram = Telegram(self) self.configuration = Configuration(self) self.d.set_background_title("SNAP-TOOL") """ Method that generates the menu interface. Parameters: self -- An instantiated object of the FormDialogs class. text -- Text displayed on the interface. options -- List of options that make up the menu. title -- Title displayed on the interface. Return: tag_menu -- Chosen option. """ def getMenu(self, text, options, title): code_menu, tag_menu = self.d.menu(text=text, choices=options, title=title) if code_menu == self.d.OK: return tag_menu if code_menu == self.d.CANCEL: exit(0) """ Method that generates the interface for entering decimal or floating type data. Parameters: self -- An instantiated object of the FormDialogs class. text -- Text displayed on the interface. initial_value -- Default value shown on the interface. Return: tag_inputbox -- Decimal or float value entered. """ def getDataNumberDecimal(self, text, initial_value): decimal_reg_exp = re_compile(r'^[1-9](\.[0-9]+)?$') while True: code_inputbox, tag_inputbox = self.d.inputbox(text=text, height=10, width=50, init=initial_value) if code_inputbox == self.d.OK: if (not self.utils.validateRegularExpression( decimal_reg_exp, tag_inputbox)): self.d.msgbox( text= "\nInvalid data entered. Required value (decimal or float).", height=8, width=50, title="Error Message") else: return tag_inputbox elif code_inputbox == self.d.CANCEL: self.mainMenu() """ Method that generates an interface to enter an IP address. Parameters: self -- An instantiated object of the FormDialogs class. text -- Text displayed on the interface. initial_value -- Default value shown on the interface. Return: tag_inputbox -- IP address entered. """ def getDataIP(self, text, initial_value): ip_reg_exp = re_compile( r'^(?:(?:[1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}(?:[1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^localhost$' ) while True: code_inputbox, tag_inputbox = self.d.inputbox(text=text, height=10, width=50, init=initial_value) if code_inputbox == self.d.OK: if (not self.utils.validateRegularExpression( ip_reg_exp, tag_inputbox)): self.d.msgbox( text= "\nInvalid data entered. Required value (IP address).", height=8, width=50, title="Error Message") else: return tag_inputbox elif code_inputbox == self.d.CANCEL: self.mainMenu() """ Method that generates an interface to enter a port. Parameters: self -- An instantiated object of the FormDialogs class. text -- Text displayed on the interface. initial_value -- Default value shown on the interface. Return: tag_inputbox -- Port entered. """ def getDataPort(self, text, initial_value): port_reg_exp = re_compile( r'^([0-9]{1,4}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$' ) while True: code_inputbox, tag_inputbox = self.d.inputbox(text=text, height=10, width=50, init=initial_value) if code_inputbox == self.d.OK: if (not self.utils.validateRegularExpression( port_reg_exp, tag_inputbox)): self.d.msgbox( text= "\nInvalid data entered. Required value (0 - 65535).", height=8, width=50, title="Error Message") else: return tag_inputbox elif code_inputbox == self.d.CANCEL: self.mainMenu() """ Method that generates an interface to enter text. Parameters: self -- An instantiated object of the FormDialogs class. text -- Text displayed on the interface. initial_value -- Default value shown on the interface. Return: tag_inputbox -- Text entered. """ def getDataInputText(self, text, initial_value): while True: code_inputbox, tag_inputbox = self.d.inputbox(text=text, height=10, width=50, init=initial_value) if code_inputbox == self.d.OK: if tag_inputbox == "": self.d.msgbox( text= "\nInvalid data entered. Required value (not empty).", height=8, width=50, title="Error Message") else: return tag_inputbox elif code_inputbox == self.d.CANCEL: self.mainMenu() """ Method that generates an interface to enter a password. Parameters: self -- An instantiated object of the FormDialogs class. text -- Text displayed on the interface. initial_value -- Default value shown on the interface. Return: tag_passwordbox -- Password entered. """ def getDataPassword(self, text, initial_value): while True: code_passwordbox, tag_passwordbox = self.d.passwordbox( text=text, height=10, width=50, init=initial_value, insecure=True) if code_passwordbox == self.d.OK: if tag_passwordbox == "": self.d.msgbox( text= "\nInvalid data entered. Required value (not empty).", height=8, width=50, title="Error Message") else: return tag_passwordbox elif code_passwordbox == self.d.CANCEL: self.mainMenu() """ Method that generates a decision-making interface (yes / no). Parameters: self -- An instantiated object of the FormDialogs class. text -- Text displayed on the interface. title -- Title displayed on the interface. Return: tag_yesno -- Chosen option (yes or no). """ def getDataYesOrNo(self, text, title): tag_yesno = self.d.yesno(text=text, height=10, width=50, title=title) return tag_yesno """ Method that generates an interface with several available options, and where only one of them can be chosen. Parameters: self -- An instantiated object of the FormDialogs class. text -- Text displayed on the interface. options -- List of options that make up the interface. title -- Title displayed on the interface. Return: tag_radiolist -- Chosen option. """ def getDataRadioList(self, text, options, title): while True: code_radiolist, tag_radiolist = self.d.radiolist(text=text, width=65, choices=options, title=title) if code_radiolist == self.d.OK: if len(tag_radiolist) == 0: self.d.msgbox(text="\nSelect at least one option.", height=7, width=50, title="Error Message") else: return tag_radiolist elif code_radiolist == self.d.CANCEL: self.mainMenu() """ Method that generates an interface with several available options, and where you can choose one or more of them. Parameters: self -- An instantiated object of the FormDialogs class. text -- Text displayed on the interface. options -- List of options that make up the interface. title -- Title displayed on the interface. Return: tag_checklist -- List with the chosen options. """ def getDataCheckList(self, text, options, title): while True: code_checklist, tag_checklist = self.d.checklist(text=text, width=75, choices=options, title=title) if code_checklist == self.d.OK: if len(tag_checklist) == 0: self.d.msgbox(text="\nSelect at least one option.", height=7, width=50, title="Error Message") else: return tag_checklist elif code_checklist == self.d.CANCEL: self.mainMenu() """ Method that generates an interface to select a file. Parameters: self -- An instantiated object of the FormDialogs class. initial_path -- Initial path in the interface. title -- Title displayed on the interface. extension_file -- Allowed file extension. Return: tag_fselect -- Path of the selected file. """ def getFile(self, initial_path, title, extension_file): while True: code_fselect, tag_fselect = self.d.fselect(filepath=initial_path, height=8, width=50, title=title) if code_fselect == self.d.OK: if tag_fselect == "": self.d.msgbox(text="\nSelect a file. Required value: " + extension_file + " file.", height=7, width=50, title="Error Message") else: ext_file = Path(tag_fselect).suffix if not ext_file == extension_file: self.d.msgbox( text="\nSelect a file. Required value: " + extension_file + " file.", height=7, width=50, title="Error Message") else: return tag_fselect elif code_fselect == self.d.CANCEL: self.mainMenu() """ Method that generates an interface to select a directory. Parameters: self -- An instantiated object of the FormDialog class. initial_path -- Initial path in the interface. title -- Title displayed on the interface. Return: tag_dselect -- Selected directory. """ def getDirectory(self, initial_path, title): while True: code_dselect, tag_dselect = self.d.dselect(filepath=initial_path, height=8, width=50, title=title) if code_dselect == self.d.OK: if tag_dselect == "": self.d.msgbox( text= "\nSelect a directory. Required value (not empty).", height=7, width=50, title="Error Message") else: return tag_dselect elif code_dselect == self.d.CANCEL: self.mainMenu() """ Method that generates an interface with scroll box. Parameters: self -- An instantiated object of the FormDialogs class. text -- Text displayed on the interface. title -- Title displayed on the interface. """ def getScrollBox(self, text, title): code_scrollbox = self.d.scrollbox(text=text, height=15, width=70, title=title) """ Method that defines the action to be performed on the Snap-Tool configuration file (creation or modification). Parameters: self -- An instantiated object of the FormDialog class. """ def defineConfiguration(self): options_conf_false = [("Create", "Create the configuration file", 0)] options_conf_true = [("Modify", "Modify the configuration file", 0)] if not path.exists(self.configuration.conf_file): opt_conf_false = self.getDataRadioList("Select a option:", options_conf_false, "Configuration Options") if opt_conf_false == "Create": self.configuration.createConfiguration() else: opt_conf_true = self.getDataRadioList("Select a option:", options_conf_true, "Configuration Options") if opt_conf_true == "Modify": self.configuration.updateConfiguration() """ Method that creates a repository of type FS in ElasticSearch. Parameters: self -- An instantiated object of the FormDialog class. Exceptions: KeyError -- A Python KeyError exception is what is raised when you try to access a key that isn’t in a dictionary (dict). """ def createRepository(self): try: if not path.exists(self.configuration.conf_file): self.d.msgbox(text="\nConfiguration file not found.", height=7, width=50, title="Error Message") else: repository_name = self.getDataInputText( "Enter the name to be assigned to the repository:", "repository_name") path_repository = self.getDirectory("/etc/Snap-Tool", "Repository path") compress_repository = self.getDataYesOrNo( "\nDo you require metadata files to be stored compressed?", "Repository compression") if compress_repository == "ok": compress_repository = True else: compress_repository = False snap_tool_conf = self.utils.readYamlFile( self.configuration.conf_file, 'r') conn_es = self.elastic.getConnectionElastic() self.elastic.createRepositoryFS(conn_es, repository_name, path_repository, compress_repository) message_create_repository = self.telegram.getMessageCreateRepository( repository_name, path_repository, compress_repository) self.telegram.sendTelegramAlert( self.utils.decryptAES( snap_tool_conf['telegram_chat_id']).decode('utf-8'), self.utils.decryptAES( snap_tool_conf['telegram_bot_token']).decode('utf-8'), message_create_repository) self.logger.createSnapToolLog( "Repository created: " + repository_name, 1) self.d.msgbox(text="\nRepository created: " + repository_name, height=7, width=50, title="Notification Message") conn_es.transport.close() self.mainMenu() except KeyError as exception: self.logger.createSnapToolLog("Key Error: " + exception, 3) self.d.msgbox( text= "\nFailed to create snapshot. For more information, see the logs.", height=8, width=50, title="Error Message") self.mainMenu() """ Method that removes one or more FS type repositories in ElasticSearch. Parameters: self -- An instantiated object of the FormDialog class. Exceptions: KeyError -- A Python KeyError exception is what is raised when you try to access a key that isn’t in a dictionary (dict). """ def deleteRepository(self): try: if not path.exists(self.configuration.conf_file): self.d.msgbox(text="\nConfiguration file not found.", height=7, width=50, title="Error Message") else: conn_es = self.elastic.getConnectionElastic() list_aux_repositories = self.elastic.getAllRepositories( conn_es) if len(list_aux_repositories) == 0: self.d.msgbox(text="\nThere are no repositories created.", height=7, width=50, title="Notification Message") else: snap_tool_conf = self.utils.readYamlFile( self.configuration.conf_file, 'r') list_all_repositories = self.utils.convertListToCheckOrRadioList( list_aux_repositories, "Repository Name") opt_repos = self.getDataCheckList( "Select one or more options:", list_all_repositories, "Repositories") confirm_delete_repos = self.getDataYesOrNo( "\nAre you sure to delete the following repository(s)?", "Delete repositories") if confirm_delete_repos == "ok": message_to_display = "\nDeleted repositories:\n\n" for repo_name in opt_repos: self.elastic.deleteRepositoryFS(conn_es, repo_name) message_to_display += "\n- " + repo_name message_delete_repository = self.telegram.getMessageDeleteRepository( repo_name) self.telegram.sendTelegramAlert( self.utils.decryptAES( snap_tool_conf['telegram_chat_id']).decode( 'utf-8'), self.utils.decryptAES( snap_tool_conf['telegram_bot_token']). decode('utf-8'), message_delete_repository) self.logger.createSnapToolLog( "Deleted repository: " + repo_name, 2) self.getScrollBox(message_to_display, "Deleted repositories") conn_es.transport.close() self.mainMenu() except KeyError as exception: self.logger.createSnapToolLog("Key Error: " + exception, 3) self.d.msgbox( text= "\nFailed to delete repository. For more information, see the logs.", height=8, width=50, title="Error Message") self.mainMenu() """ Method that creates a snapshot of a particular index and allows the index to be deleted or not. Parameters: self -- An instantiated object of the FormDialog class. Exceptions: KeyError -- A Python KeyError exception is what is raised when you try to access a key that isn’t in a dictionary (dict). """ def createSnapshot(self): try: if not path.exists(self.configuration.conf_file): self.d.msgbox(text="\nConfiguration file not found.", height=7, width=50, title="Error Message") else: conn_es = self.elastic.getConnectionElastic() list_aux_indices = self.elastic.getIndices(conn_es) if len(list_aux_indices) == 0: self.d.msgbox(text="\nThere are no indexes to back up.", height=7, width=50, title="Notification Message") else: list_all_indices = self.utils.convertListToCheckOrRadioList( list_aux_indices, "Index name") opt_index = self.getDataRadioList("Select a option:", list_all_indices, "Indices") list_aux_repositories = self.elastic.getAllRepositories( conn_es) if len(list_aux_repositories) == 0: self.d.msgbox(text="\nThere are no repositories.", height=7, width=50, title="Notification Message") else: snap_tool_conf = self.utils.readYamlFile( self.configuration.conf_file, 'r') list_all_repositories = self.utils.convertListToCheckOrRadioList( list_aux_repositories, "Repository name") opt_repo = self.getDataRadioList( "Select a option:", list_all_repositories, "Repositories") self.elastic.createSnapshot(conn_es, opt_repo, opt_index) message_creation_start = self.telegram.getMessageStartCreationSnapshot( opt_index, opt_repo) self.telegram.sendTelegramAlert( self.utils.decryptAES( snap_tool_conf['telegram_chat_id']).decode( 'utf-8'), self.utils.decryptAES( snap_tool_conf['telegram_bot_token']).decode( 'utf-8'), message_creation_start) self.logger.createSnapToolLog( "Snapshot creation has started: " + opt_index, 1) while True: status_snapshot = self.elastic.getStatusSnapshot( conn_es, opt_repo, opt_index) if status_snapshot == "SUCCESS": break sleep(60) snapshot_info = self.elastic.getSnapshotInfo( conn_es, opt_repo, opt_index) self.logger.createSnapToolLog( "Snapshot creation has finished: " + opt_index, 1) message_creation_end = self.telegram.getMessageEndSnapshot( opt_index, opt_repo, snapshot_info['snapshots'][0]['start_time'], snapshot_info['snapshots'][0]['end_time']) self.telegram.sendTelegramAlert( self.utils.decryptAES( snap_tool_conf['telegram_chat_id']).decode( 'utf-8'), self.utils.decryptAES( snap_tool_conf['telegram_bot_token']).decode( 'utf-8'), message_creation_end) self.d.msgbox(text="\nSnapshot created: " + opt_index, height=7, width=50, title="Notification Message") if snap_tool_conf['is_delete_index'] == True: self.elastic.deleteIndex(conn_es, opt_index) if not conn_es.indices.exists(opt_index): self.logger.createSnapToolLog( "Index removed: " + opt_index, 1) message_delete_index = self.telegram.getMessageDeleteIndex( opt_index) self.telegram.sendTelegramAlert( self.utils.decryptAES( snap_tool_conf['telegram_chat_id']). decode('utf-8'), self.utils.decryptAES( snap_tool_conf['telegram_bot_token']). decode('utf-8'), message_delete_index) self.d.msgbox(text="\nIndex removed: " + opt_index, height=7, width=50, title="Notification Message") else: delete_index = self.getDataYesOrNo( "\nDo you want to delete the index?\n\n- " + opt_index, "Delete Index") if delete_index == "ok": self.elastic.deleteIndex(conn_es, opt_index) if not conn_es.indices.exists(opt_index): self.logger.createSnapToolLog( "Index removed: " + opt_index, 1) message_delete_index = self.telegram.getMessageDeleteIndex( opt_index) self.telegram.sendTelegramAlert( self.utils.decryptAES( snap_tool_conf['telegram_chat_id'] ).decode('utf-8'), self.utils.decryptAES(snap_tool_conf[ 'telegram_bot_token']).decode( 'utf-8'), message_delete_index) self.d.msgbox(text="\nIndex removed: " + opt_index, height=7, width=50, title="Notification Message") conn_es.transport.close() self.mainMenu() except KeyError as exception: self.logger.createSnapToolLog("Key Error: " + exception, 3) self.d.msgbox( text= "\nFailed to create snapshot. For more information, see the logs.", height=8, width=50, title="Error Message") self.mainMenu() """ Method that removes one or more snapshots from ElasticSearch. Parameters: self -- An instantiated object of the FormDialog class. Exceptions: KeyError -- A Python KeyError exception is what is raised when you try to access a key that isn’t in a dictionary (dict). """ def deleteSnapshot(self): try: if not path.exists(self.configuration.conf_file): self.d.msgbox(text="\nConfiguration file not found.", height=7, width=50, title="Error Message") else: conn_es = self.elastic.getConnectionElastic() list_aux_repositories = self.elastic.getAllRepositories( conn_es) if len(list_aux_repositories) == 0: self.d.msgbox(text="\nThere are no repositories created.", height=7, width=50, title="Notification Message") else: list_all_repositories = self.utils.convertListToCheckOrRadioList( list_aux_repositories, "Repository Name") opt_repo = self.getDataRadioList("Select a option:", list_all_repositories, "Repositories") list_aux_snapshots = self.elastic.getAllSnapshots( conn_es, opt_repo) if len(list_aux_snapshots) == 0: self.d.msgbox(text="\nThere are no snapshots created.", height=7, width=50, title="Notification Message") else: snap_tool_conf = self.utils.readYamlFile( self.configuration.conf_file, 'r') list_all_snapshots = self.utils.convertListToCheckOrRadioList( list_aux_snapshots, "Snapshot Name") opt_snapshots = self.getDataCheckList( "Select one or more options:", list_all_snapshots, "Snapshots") delete_snapshot = self.getDataYesOrNo( "\nAre you sure to delete the selected snapshot(s)?", "Delete Snapshot(s)") if delete_snapshot == "ok": for snapshot in opt_snapshots: self.elastic.deleteSnapshotElastic( conn_es, opt_repo, snapshot) message_delete_snapshot = self.telegram.getMessageDeleteSnapshot( snapshot, opt_repo) self.telegram.sendTelegramAlert( self.utils.decryptAES( snap_tool_conf['telegram_chat_id']). decode('utf-8'), self.utils.decryptAES( snap_tool_conf['telegram_bot_token']). decode('utf-8'), message_delete_snapshot) message = "\nThe following snapshots were removed:\n\n" message += self.utils.convertListToString( opt_snapshots) self.getScrollBox(message, "Snapshot(s) deleted") conn_es.transport.close() self.mainMenu() except KeyError as exception: self.logger.createSnapToolLog("Key Error: " + exception, 3) self.d.msgbox( text= "\nFailed to delete snapshot(s). For more information, see the logs.", height=8, width=50, title="Error Message") self.mainMenu() """ Method that restores a particular snapshot from ElasticSearch. Parameters: self -- An instantiated object of the FormDialog class. Exceptions: KeyError -- A Python KeyError exception is what is raised when you try to access a key that isn’t in a dictionary (dict). """ def restoreSnapshot(self): try: if not path.exists(self.configuration.conf_file): self.d.msgbox(text="\nConfiguration file not found.", height=7, width=50, title="Error Message") else: conn_es = self.elastic.getConnectionElastic() list_aux_repositories = self.elastic.getAllRepositories( conn_es) if len(list_aux_repositories) == 0: self.d.msgbox(text="\nThere are no repositories created.", height=7, width=50, title="Notification Message") else: list_all_repositories = self.utils.convertListToCheckOrRadioList( list_aux_repositories, "Repository Name") opt_repo = self.getDataRadioList("Select a option:", list_all_repositories, "Repositories") list_aux_snapshots = self.elastic.getAllSnapshots( conn_es, opt_repo) if len(list_aux_snapshots) == 0: self.d.msgbox(text="\nThere are no snapshots created.", height=7, width=50, title="Notification Message") else: snap_tool_conf = self.utils.readYamlFile( self.configuration.conf_file, 'r') list_all_snapshots = self.utils.convertListToCheckOrRadioList( list_aux_snapshots, "Snapshot Name") opt_snapshot = self.getDataRadioList( "Select a option:", list_all_snapshots, "Snapshots") self.elastic.restoreSnapshot(conn_es, opt_repo, opt_snapshot) message_restore_snapshot = self.telegram.getMessageRestoreSnapshot( opt_repo, opt_snapshot) self.telegram.sendTelegramAlert( self.utils.decryptAES( snap_tool_conf['telegram_chat_id']).decode( 'utf-8'), self.utils.decryptAES( snap_tool_conf['telegram_bot_token']).decode( 'utf-8'), message_restore_snapshot) self.logger.createSnapToolLog( "Snapshot restored: " + opt_snapshot, 1) self.d.msgbox(text="\nSnapshot restored: " + opt_snapshot + '.', height=7, width=50, title="Notification Message") conn_es.transport.close() self.mainMenu() except KeyError as exception: self.logger.createSnapToolLog("Key Error: " + exception, 3) self.d.msgbox( text= "\nFailed to restore snapshot. For more information, see the logs.", height=8, width=50, title="Error Message") self.mainMenu() """ Method that mounts a snapshot as a searchable snapshot in ElasticSearch. Parameters: self -- An instantiated object of the FormDialog class. Exceptions: KeyError -- A Python KeyError exception is what is raised when you try to access a key that isn’t in a dictionary (dict). """ def mountSearchableSnapshot(self): try: if not path.exists(self.configuration.conf_file): self.d.msgbox(text="\nConfiguration file not found.", height=7, width=50, title="Error Message") else: conn_es = self.elastic.getConnectionElastic() list_aux_repositories = self.elastic.getAllRepositories( conn_es) if len(list_aux_repositories) == 0: self.d.msgbox(text="\nThere are no repositories created.", height=7, width=50, title="Notification Message") else: list_all_repositories = self.utils.convertListToCheckOrRadioList( list_aux_repositories, "Repository Name") opt_repo = self.getDataRadioList("Select a option:", list_all_repositories, "Repositories") list_aux_snapshots = self.elastic.getAllSnapshots( conn_es, opt_repo) if len(list_aux_snapshots) == 0: self.d.msgbox(text="\nThere are no snapshots created.", height=7, width=50, title="Notification Message") else: snap_tool_conf = self.utils.readYamlFile( self.configuration.conf_file, 'r') list_all_snapshots = self.utils.convertListToCheckOrRadioList( list_aux_snapshots, "Snapshot Name") opt_snapshot = self.getDataRadioList( "Select a option:", list_all_snapshots, "Snapshots") self.elastic.mountSearchableSnapshot( conn_es, opt_repo, opt_snapshot) message_searchable_snapshot = self.telegram.getMessageSearchableSnapshot( opt_repo, opt_snapshot) self.telegram.sendTelegramAlert( self.utils.decryptAES( snap_tool_conf['telegram_chat_id']).decode( 'utf-8'), self.utils.decryptAES( snap_tool_conf['telegram_bot_token']).decode( 'utf-8'), message_searchable_snapshot) self.logger.createSnapToolLog( "Snapshot mounted as searchable snapshot: " + opt_snapshot, 1) self.d.msgbox( text="\nSnapshot mounted as searchable snapshot: " + opt_snapshot + '.', height=8, width=50, title="Notification Message") conn_es.transport.close() self.mainMenu() except KeyError as exception: self.logger.createSnapToolLog("Key Error: " + exception, 3) self.d.msgbox( text= "\nFailed to mount snapshot as a searchable snapshot. For more information, see the logs.", height=8, width=50, title="Error Message") self.mainMenu() """ Method that removes one or more indexes in ElasticSearch. Parameters: self -- An instantiated object of the FormDialog class. Exceptions: KeyError -- A Python KeyError exception is what is raised when you try to access a key that isn’t in a dictionary (dict). """ def deleteIndices(self): try: if not path.exists(self.configuration.conf_file): self.d.msgbox(text="\nConfiguration file not found.", height=7, width=50, title="Error Message") else: conn_es = self.elastic.getConnectionElastic() list_aux_indices = self.elastic.getIndices(conn_es) if len(list_aux_indices) == 0: self.d.msgbox(text="\nThere are no indexes to remove.", height=7, width=50, title="Notification Message") else: list_all_indices = self.utils.convertListToCheckOrRadioList( list_aux_indices, "Index name") opt_indices = self.getDataCheckList( "Select a option:", list_all_indices, "Indices") confirm_delete_indices = self.getDataYesOrNo( "\nAre you sure to delete the selected indices?", "Delete indices") if confirm_delete_indices == "ok": snap_tool_conf = self.utils.readYamlFile( self.configuration.conf_file, 'r') message_to_display = "\nIndices removed:\n" for index_name in opt_indices: self.elastic.deleteIndex(conn_es, index_name) message_to_display += "\n- " + index_name self.logger.createSnapToolLog( "Index removed: " + index_name, 2) message_delete_indices = self.telegram.getMessageDeleteIndex( index_name) self.telegram.sendTelegramAlert( self.utils.decryptAES( snap_tool_conf['telegram_chat_id']).decode( 'utf-8'), self.utils.decryptAES( snap_tool_conf['telegram_bot_token']). decode('utf-8'), message_delete_indices) self.getScrollBox(message_to_display, "Indices Removed") conn_es.transport.close() self.mainMenu() except KeyError as exception: self.logger.createSnapToolLog("Key Error: " + exception, 3) self.d.msgbox( text= "\nFailed to delete indices. For more information, see the logs.", height=8, width=50, title="Error Message") self.mainMenu() """ Method that displays information related to the percentage of occupied disk space of the nodes of the elasticsearch cluster. Parameters: self -- An instantiated object of the FormDialog class. """ def showNodesDiskSpace(self): message_to_display = "Occupied space in nodes:\n\n" conn_es = self.elastic.getConnectionElastic() nodes_info = self.elastic.getNodesInformation(conn_es) for node in nodes_info: message_to_display += "- " + nodes_info[node]['name'] + '\n' total_disk = nodes_info[node]['fs']['total']['total_in_bytes'] available_disk = nodes_info[node]['fs']['total'][ 'available_in_bytes'] percentage = 100 - (available_disk * 100 / total_disk) message_to_display += "Percent occupied on disk: " + str( round(percentage, 2)) + "%\n\n" conn_es.transport.close() self.getScrollBox(message_to_display, "Node Information") self.mainMenu() """ Method that displays a message on the screen with information about the application. Parameters: self -- An instantiated object of the FormDialog class. """ def getAbout(self): message = "\nCopyright@2021 Tekium. All rights reserved.\nSnap-Tool v3.1\nAuthor: Erick Rodriguez\nEmail: [email protected], [email protected]\n" + "License: GPLv3\n\nSnap-Tool is a tool that allows the management of snaphots in\nElasticSearch through a graphical interface." self.getScrollBox(message, "About") self.mainMenu() """ Method that launches an action based on the option chosen in the main menu. Parameters: self -- An instantiated object of the FormDialog class. option -- Chosen option. """ def switchMmenu(self, option): if option == 1: self.defineConfiguration() elif option == 2: self.repositoryMenu() elif option == 3: self.snapshotMenu() elif option == 4: self.indicesMenu() elif option == 5: self.showNodesDiskSpace() elif option == 6: self.getAbout() elif option == 7: exit(0) """ Method that launches an action based on the option chosen in the Repositories menu. Parameters: self -- An instantiated object of the FormDialog class. option -- Chosen option. """ def switchRmenu(self, option): if option == 1: self.createRepository() elif option == 2: self.deleteRepository() """ Method that launches an action based on the option chosen in the Snapshots menu. Parameters: self -- An instantiated object of the FormDialog class. option -- Chosen option. """ def switchSmenu(self, option): if option == 1: self.createSnapshot() elif option == 2: self.deleteSnapshot() elif option == 3: self.restoreSnapshot() elif option == 4: self.mountSearchableSnapshot() """ Method that launches an action based on the option chosen in the Indices menu. Parameters: self -- An instantiated object of the FormDialog class. option -- Chosen option. """ def switchImenu(self, option): if option == 1: self.deleteIndices() """ Method that defines the menu on the actions to be carried out in the main menu. Parameters: self -- An instantiated object of the FormDialog class. """ def mainMenu(self): options_mm = [("1", "Snap-Tool Configuration"), ("2", "Repositories"), ("3", "Snapshots"), ("4", "Indices"), ("5", "Nodes information"), ("6", "About"), ("7", "Exit")] option_mm = self.getMenu("Select a option:", options_mm, "Main Menu") self.switchMmenu(int(option_mm)) """ Method that defines the menu of actions that can be performed in relation to repositories. Parameters: self -- An instantiated object of the FormDialog class. """ def repositoryMenu(self): options_rm = [("1", "Create repository"), ("2", "Delete repositories")] option_rm = self.getMenu("Select a option:", options_rm, "Repositories menu") self.switchRmenu(int(option_rm)) """ Method that defines the menu of actions that can be performed in relation to snaphosts. Parameters: self -- An instantiated object of the FormDialog class. """ def snapshotMenu(self): options_sm = [("1", "Create Snapshot"), ("2", "Delete Snapshot(s)"), ("3", "Restore snapshot"), ("4", "Mount searchable snapshot")] option_sm = self.getMenu("Select a option:", options_sm, "Snapshots Menu") self.switchSmenu(int(option_sm)) """ Method that defines the menu of actions that can be performed in relation to indices. Parameters: self -- An instantiated object of the FormDialog class. """ def indicesMenu(self): options_im = [("1", "Delete indices")] option_im = self.getMenu("Select a option:", options_im, "Indices Menu") self.switchImenu(int(option_im))
def commandline(): TXT_WELCOME_TITLE = 'Yet Another Common Criteria Parser and Checklist Generator!\n\nThis tool helps you to generate a quick workunit checklist.\n\nUse by your own risk' locale.setlocale(locale.LC_ALL, '') # You may want to use 'autowidgetsize=True' here (requires pythondialog >= 3.1) d = Dialog(dialog="dialog") #d = Dialog(dialog='dialog', autowidgetsize=True) # Dialog.set_background_title() requires pythondialog 2.13 or later d.set_background_title(TXT_WELCOME_TITLE) # For older versions, you can use: # d.add_persistent_args(["--backtitle", "My little program"]) # In pythondialog 3.x, you can compare the return code to d.OK, Dialog.OK or # "ok" (same object). In pythondialog 2.x, you have to use d.DIALOG_OK, which # is deprecated since version 3.0.0. code = d.yesno(TXT_WELCOME_TITLE, height="15", width="65", yes_label="OK", no_label="Cancel") if (code == Dialog.CANCEL or code == Dialog.ESC): clearquit() else: code, tag = d.menu("OK, then you have four options:", choices=[("(1)", "Parse CC into a Database"), ("(2)", "Export CC"), ("(3)", "Parse and Export"), ("(4)", "Generate Checklist")]) if code == d.OK: if tag == "(1)": os.system('clear') if not (os.path.isfile("doc/cc3R4.xml")): d.msgbox("Error loading cc3R4.xml",height="10", width="45") sys.exit(1) os.system("python CCParser.py -ask doc/cc3R4.xml") d.msgbox("Generated database in data/ccdb.sqlite3",height="10", width="45") quit() elif tag == "(2)": os.system('clear') if not (os.path.isfile("data/ccdb.sqlite3")): d.msgbox("Error loading database. Must run CCParser.py first",height="10", width="45") sys.exit(1) os.system("python CChtmlExport.py -ask data/ccdb.sqlite3") d.msgbox("Generated export in output/",height="10", width="45") quit() elif tag == "(3)": os.system('clear') if not (os.path.isfile("doc/cc3R4.xml")): d.msgbox("Error loading cc3R4.xml",height="10", width="45") sys.exit(1) os.system("python CCParser.py doc/cc3R4.xml && python CChtmlExport.py -ask data/ccdb.sqlite3") d.msgbox("Generated database in data/ccdb.sqlite3 and export in output/",height="10", width="75") quit() elif tag == "(4)": if not (os.path.isfile("data/ccdb.sqlite3")): d.msgbox("Error loading database. Must run CCParser.py first",height="10", width="45") sys.exit(1) code, tag = d.menu("Evaluation Assurance Level:", choices=[("(EAL1)", "Evaluation Assurance Level 1"), ("(EAL2)", "Evaluation Assurance Level 2"), ("(EAL3)", "Evaluation Assurance Level 3"), ("(EAL4)", "Evaluation Assurance Level 4"), ("(EAL5)", "Evaluation Assurance Level 5"), ("(EAL6)", "Evaluation Assurance Level 6"), ("(EAL7)", "Evaluation Assurance Level 7")]) if code == d.OK: if tag == "(EAL1)": EALSELECTED = "EAL1" if tag == "(EAL2)": EALSELECTED = "EAL2" if tag == "(EAL3)": EALSELECTED = "EAL3" if tag == "(EAL4)": EALSELECTED = "EAL4" if tag == "(EAL5)": EALSELECTED = "EAL5" if tag == "(EAL6)": EALSELECTED = "EAL6" if tag == "(EAL7)": EALSELECTED = "EAL7" code, tags = d.checklist("Family", choices=[("ACO_DEV.1", "", False), ("ACO_DEV.2", "", False), ("ACO_DEV.3", "", False), ("ACO_REL.1", "", False), ("ACO_REL.2", "", False), ("ACO_CTT.1", "", False), ("ACO_CTT.2", "", False), ("ACO_VUL.1", "", False), ("ACO_VUL.2", "", False), ("ACO_VUL.3", "", False), ("ADV_ARC.1", "", False), ("ADV_FSP.2", "", False), ("ADV_FSP.3", "", False), ("ADV_FSP.4", "", False), ("ADV_FSP.5", "", False), ("ADV_FSP.6", "", False), ("ADV_IMP.1", "", False), ("ADV_IMP.2", "", False), ("ADV_INT.1", "", False), ("ADV_INT.2", "", False), ("ADV_SPM.1", "", False), ("ADV_TDS.3", "", False), ("ADV_TDS.4", "", False), ("ADV_TDS.5", "", False), ("AGD_OPE.1", "", False), ("AGD_PRE.1", "", False), ("ALC_CMC.1", "", False), ("ALC_CMC.2", "", False), ("ALC_CMC.3", "", False), ("ALC_CMC.4", "", False), ("ALC_CMC.5", "", False), ("ALC_CMS.1", "", False), ("ALC_CMS.2", "", False), ("ALC_CMS.3", "", False), ("ALC_CMS.4", "", False), ("ALC_CMS.5", "", False), ("ALC_DEL.1", "", False), ("ALC_DVS.1", "", False), ("ALC_DVS.2", "", False), ("ALC_FLR.1", "", False), ("ALC_FLR.2", "", False), ("ALC_FLR.3", "", False), ("ALC_LCD.1", "", False), ("ALC_LCD.2", "", False), ("ALC_TAT.1", "", False), ("ALC_TAT.2", "", False), ("ALC_TAT.3", "", False), ("APE_INT.1", "", False), ("APE_CCL.1", "", False), ("APE_SPD.1", "", False), ("APE_OBJ.1", "", False), ("APE_OBJ.2", "", False), ("APE_ECD.1", "", False), ("APE_REQ.1", "", False), ("APE_REQ.2", "", False), ("ASE_INT.1", "", False), ("ASE_CCL.1", "", False), ("ASE_SPD.1", "", False), ("ASE_OBJ.1", "", False), ("ASE_OBJ.2", "", False), ("ASE_ECD.1", "", False), ("ASE_REQ.1", "", False), ("ASE_REQ.2", "", False), ("ASE_TSS.1", "", False), ("ASE_TSS.2", "", False), ("ATE_COV.1", "", False), ("ATE_COV.2", "", False), ("ATE_DPT.1", "", False), ("ATE_DPT.2", "", False), ("ATE_DPT.3", "", False), ("ATE_FUN.1", "", False), ("ATE_IND.1", "", False), ("ATE_IND.2", "", False), ("AVA_VAN.1", "", False), ("AVA_VAN.2", "", False), ("AVA_VAN.3", "", False), ("AVA_VAN.4", "", False), ("AVA_VAN.5", "", False), ], title="Evaluation Assurance Level", backtitle="Select one...") if code == d.OK: AC ="" for i in tags: AC = AC + " " + i code, tag = d.menu("Detail level:", choices=[("(D1)", "Detail Level 1"), ("(D2)", "Detail Level 2"), ("(D3)", "Detail Level 3"), ("(D4)", "Detail Level 4")]) if code == d.OK: if tag == "(D1)": DETAILSELECTED = "1" if tag == "(D2)": DETAILSELECTED = "2" if tag == "(D3)": DETAILSELECTED = "3" if tag == "(D4)": DETAILSELECTED = "4" if AC: os.system('clear') os.system("python CCChecklist.py -eal " + EALSELECTED + " -ac " + AC + " -p " + DETAILSELECTED + " -ask data/ccdb.sqlite3") else: os.system('clear') os.system("python CCChecklist.py -eal " + EALSELECTED + " -p " + DETAILSELECTED + " -ask data/ccdb.sqlite3") else: quit() d.msgbox("Check /output folder") quit() else: quit() else: quit() else: quit()