def interactive_start(self):
     """选择交易所"""
     self.__se_info = checkboxlist_dialog(
         title="请选择股票交易所",
         text="使用上下键和Tab键进行切换,Enter键选中",
         ok_text="确认",
         cancel_text="取消",
         values=[
             ("上交所: http://yunhq.sse.com.cn:32041//v1/sh1/snap/", "上交所"),
             ("上交所ETF: http://yunhq.sse.com.cn:32041//v1/sh1/list/self/xxxxxx?callback=jQuery112408966245538614501_1602813033855&select=code%2Cname%2Copen%2Chigh%2Clow%2Clast%2Cprev_close%2Cchg_rate%2Cvolume%2Camount%2Ccpxxextendname&_=1602813033858",
              "上交所ETF"),
             ("深交所: http://www.szse.cn/api/market/ssjjhq/getTimeData?marketId=1&code=",
              "深交所"),
         ],
         style=Style.from_dict({
             "dialog": "bg:#cdbbb3",
             "button": "bg:#bf99a4",
             "checkbox": "#e8612c",
             "dialog.body": "bg:#a9cfd0",
             "dialog shadow": "bg:#c98982",
             "frame.label": "#fcaca3",
             "dialog.body label": "#fd8bb6",
         }),
     ).run()
     if self.__se_info is not None:  # 如果是None则说明用户选择了取消,退出系统
         self.__se_is_selected()  # 此时__se_info有两种情况,分别为[]和非空
Example #2
0
def ui_confirm_to_delete(apps):
    results = checkboxlist_dialog(
        title="Для подтверждения удаления еще раз выберете приложения",
        text="Внимание! Данные приложений будут потеряны",
        values=list(map(lambda x: (x, x), apps))
    ).run()
    return results
Example #3
0
def ui_select_apps(apps):
    results = checkboxlist_dialog(
        title="Выберите приложения для удаления",
        text="",
        values=list(map(lambda x: (x, x), apps))
    ).run()
    return results
Example #4
0
def get_accounts(data):
    display_keys = []
    for k in data.keys():
        display_keys.append((k, k))
    results_array = checkboxlist_dialog(
        title="Account selection dialog",
        text="Please select the account to fetch nondeliveries+spam users?",
        values=display_keys).run()

    return 1, results_array
Example #5
0
 def get_select_fields(self):
     return checkboxlist_dialog(
         title="Select",
         text="Which fields would you like to select in your query?",
         values=[
             (
                 f'{field["id"]} as "{field["name"]}"',
                 f'{field["name"]} ({field["id"]})',
             )
             for field in sorted(self.jira.fields(), key=lambda x: x["name"])
         ],
     ).run()
Example #6
0
def output_options_checklist() -> checkboxlist_dialog:
    """
    Displays a dialog for the user to input the output options they want
    :return:
    @author Conor Brosnan <*****@*****.**>
    """
    return checkboxlist_dialog(
        title="CheckboxList dialog",
        text=
        "Select one or more output options (press Tab to select Ok/Cancel)",
        values=[
            # ("csv", "CSV file containing temperature data (in degrees celsius)"),
            ("bwr", "Thermal image using bwr colormap"),
            ("gnuplot2", "Thermal image gnuplot2 colormap"),
            ("gist_ncar", "Thermal image gist_ncar colormap"),
        ],
    ).run()
Example #7
0
    def prompt_top50(self):
        """ prompts with a list of the top 50 files by size so the user can select to strip them """
        dialogue_top50 = []
        for filesize, filename in self.get_top50():
            dialogue_top50.append(
                (filename, f"{human_file_size(filesize)} - {filename}"))

        #dialogue_top50 = [ (filename, f"{filesize}\\t{filename}") for filesize, filename in allthedata.get_top50() ]
        results = checkboxlist_dialog(
            title="Select some files to strip",
            text="Here are the top 50 files",
            values=dialogue_top50,
        ).run()
        print(results)
        if results:
            for file in results:
                if file not in self.file_filters:
                    self.file_filters.append(file)
        # if you're changing the filter list, prompt again for writeout
        self.archive_written = False
        return results
Example #8
0
    def cmd_tui(self, args: argparse.Namespace):
        self.logger.info("start terminal ui")
        selection = checkboxlist_dialog(
            title="Select simulations",
            text="Select simulations to run operations on.",
            values=[(i, repr(combination))
                    for i, combination in enumerate(self.combinations)],
        ).run()

        if not selection:
            self.logger.info("no simulations selected, nothing to do")
            return

        self.logger.info("selected %d simulation(s)", len(selection))

        operation = radiolist_dialog(
            title="Select operation",
            text="Select operation to run on selected simulations",
            values=[("remove", "remove")],
        ).run()

        if not operation:
            self.logger.info("no operation selected, nothing to do")
            return

        self.logger.info(
            'running operation "%s" on %d simulation(s)',
            operation,
            len(selection),
        )

        if operation == "remove":
            cmd = [
                sys.executable,
                Path(get_main_path()).resolve(),
                "remove",
                ",".join(str(i) for i in selection),
            ]
            self.logger.info("command: %s", str(cmd))
            subprocess.run(cmd)
"""
Example of a checkbox-list-based dialog.
"""
from prompt_toolkit.shortcuts import checkboxlist_dialog, message_dialog
from prompt_toolkit.styles import Style

results = checkboxlist_dialog(
    title="CheckboxList dialog",
    text="What would you like in your breakfast ?",
    values=[
        ("eggs", "Eggs"),
        ("bacon", "Bacon"),
        ("croissants", "20 Croissants"),
        ("daily", "The breakfast of the day"),
    ],
    style=Style.from_dict({
        "dialog": "bg:#cdbbb3",
        "button": "bg:#bf99a4",
        "checkbox": "#e8612c",
        "dialog.body": "bg:#a9cfd0",
        "dialog shadow": "bg:#c98982",
        "frame.label": "#fcaca3",
        "dialog.body label": "#fd8bb6",
    }),
).run()
if results:
    message_dialog(
        title="Room service",
        text="You selected: %s\nGreat choice sir !" % ",".join(results),
    ).run()
else:
Example #10
0
def run_lesson(module_ind, lesson_ind):
    global SAVE_DATA
    if module_ind is None or lesson_ind is None:
        return
    lesson = LESSON_DATA[module_ind]['lessons'][lesson_ind]
    if len(lesson['steps']) == 0:
        message_dialog(title=lesson['lesson_name'], text=EMPTY_LESSON_TEXT, style=APP_STYLE).run()
    elif len(lesson['steps']) == 1:
        try:
            SAVE_DATA['completed'][module_ind][lesson_ind][0] = True
        except:
            SAVE_DATA = blank_save(); SAVE_DATA['completed'][module_ind][lesson_ind][0] = True
        save_game()
        button_dialog(title='%s (1/1)' % lesson['lesson_name'], text=HTML(lesson['steps'][0]['text']), style=APP_STYLE, buttons=[('Back', None)]).run()
    else:
        curr_step = 0
        while True:
            if curr_step is None:
                break
            curr_step_data = lesson['steps'][curr_step]
            curr_title = '%s (%d/%d)' % (lesson['lesson_name'], curr_step+1, len(lesson['steps']))
            if 'challenge' in curr_step_data: # challenge step
                solved = False

                # select all challenge
                if curr_step_data['challenge']['type'] == 'select_all':
                    options = curr_step_data['challenge']['options']
                    correct = {v for b,v in options if b}
                    values = [(v,HTML(v)) for b,v in options]
                    answer = checkboxlist_dialog(title=curr_title, text=HTML(curr_step_data['text']), style=APP_STYLE, values=values).run()
                    if answer is None:
                        if curr_step == 0:
                            curr_step = None
                        else:
                            curr_step = curr_step - 1
                    elif set(answer) == correct:
                        solved = True; message_dialog(title=curr_title, text=HTML(CHALLENGE_CORRECT_MESSAGE), style=APP_STYLE).run()
                    else:
                        message_dialog(title=curr_title, text=HTML(CHALLENGE_INCORRECT_MESSAGE), style=APP_STYLE).run()

                # multiple choice (select 1) challenge
                elif curr_step_data['challenge']['type'] == 'multiple_choice':
                    options = curr_step_data['challenge']['options']
                    correct = curr_step_data['challenge']['answer']
                    values = [(b,HTML(v)) for b,v in options]
                    answer = radiolist_dialog(title=curr_title, text=HTML(curr_step_data['text']), style=APP_STYLE, values=values).run()
                    if answer is None:
                        if curr_step == 0:
                            curr_step = None
                        else:
                            curr_step = curr_step - 1
                    elif answer == correct:
                        solved = True; message_dialog(title=curr_title, text=HTML(CHALLENGE_CORRECT_MESSAGE), style=APP_STYLE).run()
                    else:
                        message_dialog(title=curr_title, text=HTML(CHALLENGE_INCORRECT_MESSAGE), style=APP_STYLE).run()

                # short answer challenge
                elif curr_step_data['challenge']['type'] == 'short_answer':
                    correct = curr_step_data['challenge']['answer'].strip()
                    answer = input_dialog(title=curr_title, text=HTML(curr_step_data['text']), style=APP_STYLE).run()
                    if answer is None:
                        if curr_step == 0:
                            curr_step = None
                        else:
                            curr_step = curr_step - 1
                    elif answer.strip() == correct:
                        solved = True; message_dialog(title=curr_title, text=HTML(CHALLENGE_CORRECT_MESSAGE), style=APP_STYLE).run()
                    else:
                        message_dialog(title=curr_title, text=HTML(CHALLENGE_INCORRECT_MESSAGE), style=APP_STYLE).run()

                # math challenge
                elif curr_step_data['challenge']['type'] == 'math':
                    correct = curr_step_data['challenge']['answer']
                    answer = input_dialog(title=curr_title, text=HTML(curr_step_data['text']), style=APP_STYLE).run()
                    if answer is None:
                        if curr_step == 0:
                            curr_step = None
                        else:
                            curr_step = curr_step - 1
                    else:
                        try:
                            answer = float(answer)
                        except:
                            answer = None; message_dialog(title=curr_title, text=HTML(CHALLENGE_MATH_INVALID_NUM), style=APP_STYLE).run()
                        if answer is not None:
                            if abs(float(answer)-correct) < curr_step_data['challenge']['tolerance']:
                                solved = True; message_dialog(title=curr_title, text=HTML(CHALLENGE_CORRECT_MESSAGE), style=APP_STYLE).run()
                            else:
                                message_dialog(title=curr_title, text=HTML(CHALLENGE_INCORRECT_MESSAGE), style=APP_STYLE).run()

                # challenge type not yet implemented
                else:
                    raise NotImplementedError("Need to implement challenge type: %s" % curr_step_data['challenge']['type'])
                if solved:
                    try:
                        SAVE_DATA['completed'][module_ind][lesson_ind][curr_step] = True
                    except:
                        SAVE_DATA = blank_save(); SAVE_DATA['completed'][module_ind][lesson_ind][curr_step] = True
                    save_game()
                    if curr_step == len(lesson['steps'])-1:
                        curr_step = None
                    else:
                        curr_step = curr_step + 1
            else: # regular text step
                try:
                    SAVE_DATA['completed'][module_ind][lesson_ind][curr_step] = True
                except:
                    SAVE_DATA = blank_save(); SAVE_DATA['completed'][module_ind][lesson_ind][curr_step] = True
                save_game()
                buttons = list()
                if curr_step != len(lesson['steps'])-1:
                    buttons.append(('Next',curr_step+1))
                if curr_step != 0:
                    buttons.append(('Prev',curr_step-1))
                buttons.append(('Cancel',None))
                curr_step = button_dialog(title=curr_title, text=HTML(curr_step_data['text']), style=APP_STYLE, buttons=buttons).run()
def createconfig(config):
    configpath = os.path.dirname(os.path.abspath(__file__)) + "/cross.txt"
    config.read(configpath)

    if config.has_section('general') == False:
        config.add_section('general')
    if config.has_section('grab') == False:
        config.add_section('grab')
    if config.has_section('scan') == False:
        config.add_section('scan')
    message_dialog(
        title="Config Creator",
        text=
        "Welcome to the Config Creator.\nA config File is recommended to run this program\nWe will Start by adding root or Folders to Scan\nNote You'll need at least one root\nNote:This will overright cross.txt if you confirm at the end",
    ).run()

    newroot = True
    root = None
    rootstr = ""
    ignorestr = ""
    while newroot:
        if root == None:
            root = input_dialog(
                title='Getting Root Directories ',
                text='Please Enter the Path to a Root Directory:').run()
        if root == None:
            break
        addstring = "Adding:" + root + " is this Okay? "
        option = button_dialog(
            title=addstring,
            buttons=[("Yes", True), ("No", False)],
        ).run()
        if option == False:
            root = None
            pass
        else:
            rootstr = rootstr + root + ","
            root = None
        newroot = button_dialog(
            title="Add Another Root Folder ",
            buttons=[("Yes", True), ("No", False)],
        ).run()
    config.set('scan', "root", rootstr)

    confirm = button_dialog(
        title="Add a Folder or File to ignore ",
        buttons=[("Yes", True), ("No", False), ("Info", None)],
    ).run()
    while confirm != False:
        if confirm == None:
            message_dialog(
                title="Ignore Folders and Files",
                text=
                "Ignored Directories will not be scanned As a subdirectory of another Root Folder.\nHowever note that a ignored Folder can still be added as a root .\nIn that case the subdirectories of the ignore folder would be added\nIgnored Files will not be added at all",
            ).run()
        if confirm:
            ignorepath = input_dialog(
                title='Getting ignore Path ',
                text='Please Enter the Path to ignore:').run()
        if ignorepath == None:
            break
        addstring = "Adding:" + ignorepath + " is this Okay? "
        option = button_dialog(
            title=addstring,
            buttons=[("Yes", True), ("No", False)],
        ).run()
        if addstring == True:
            ignorestr = ignorestr + ignorepath
        confirm = button_dialog(
            title="Add Another Folder to ignore ",
            buttons=[("Yes", True), ("No", False)],
        ).run()

    config.set('scan', "ignore", ignorestr)
    newsite = True
    sitestr = ""
    while newsite:
        site = input_dialog(
            title='Add a Site to search ',
            text=
            "You'll have to get the name from jackett\nYou can get this by doing search with the desired site\nBy clicking the green search icon\n Name will appear on the addressbar next to tracker"
        ).run()
        if site == None:
            break
        addstring = "Adding:" + site + " is this Okay? "
        option = button_dialog(
            title=addstring,
            buttons=[("Yes", True), ("No", False)],
        ).run()
        if option == False:
            root = None
            pass
        else:
            sitestr = sitestr + site + ","
            site = None
        newsite = button_dialog(
            title="Add Another Site ",
            buttons=[("Yes", True), ("No", False)],
        ).run()
    config.set('grab', "sites", sitestr)

    confirm = False

    while confirm == False:
        filter = radiolist_dialog(
            values=[
                ("1", "Name + Season(TV) + Resolution + Source"),
                ("2", "Name + Season(TV) + Source"),
                ("3", "Name + Season(TV) + Resolution"),
                ("4", "Name + Season(TV)"),
                ("5", "Name"),
            ],
            title="Filter",
            text=
            "Pick the Source How you would like Searches to be done\nUnfortuntely some sites don't work with restrictive searching\nSo you should test this out yourself  \
        A search method that is not restrictive could slow down the searches with lots of results\nOr lead to false positives",
        ).run()
        if filter == None:
            break
        confirm = button_dialog(
            title="Is this okay",
            buttons=[("Yes", True), ("No", False)],
        ).run()
    config.set('grab', "filter", filter)

    #setup next few options as empty
    config.set('general', "txt", "")
    config.set('grab', "api", "")
    config.set('grab', "cookie", "")
    config.set('grab', "output", "")
    config.set('general', "misstxt", "")
    config.set('grab', "torrent", "")
    config.set('grab', "filter", "")

    #filter and jacket url

    confirm = False
    while confirm == False:
        txtpath = input_dialog(
            title='Scanner TXT File',
            text=
            'Please Enter the Path for scanner and grabber.\nFile Paths will Writen Here and is required '
        ).run()
        if txtpath == None:
            break
        config.set('general', "txt", txtpath)
        confirmtxt = "You entered:" + txtpath + " is this Okay?"
        confirm = button_dialog(
            title=confirmtxt,
            buttons=[("Yes", True), ("No", False)],
        ).run()
    confirm = False
    while confirm == False:
        torrent = input_dialog(
            title='Torrent Folder',
            text=
            'Please Enter the Path for downloading Torrents\nIf you leave this blank make sure to set Output\nThat step will come up later in this setup\nIt is okay to setup Both Torrent and Output\nHowever if None are selected then Nothing will happen when Downloader finds a match'
        ).run()
        if torrent == None:
            break
        config.set('grab', "torrent", torrent)
        confirmtxt = "You entered:" + torrent + " is this Okay?"
        confirm = button_dialog(
            title=confirmtxt,
            buttons=[("Yes", True), ("No", False)],
        ).run()

    confirm = False
    while confirm == False:
        key = input_dialog(
            title='Jackett Apikey',
            text=
            'Please Enter your Jackett Apikey.\n   This will be used to Download Torrent Files and Scan Jackett\nThis is Required'
        ).run()
        if key == None:
            break
        config.set('grab', "api", key)
        confirmtxt = "You entered:" + key + " is this Okay?"
        confirm = button_dialog(
            title=confirmtxt,
            buttons=[("Yes", True), ("No", False)],
        ).run()

    confirm = button_dialog(
        title=
        "Do you want to Exclude Certain Sources\nFor example all blu-ray encodes,etc\nThese will be ignored during grabbing/matching\nNote: Other are Files that don't fit in other selectors\nPress Cancel to Leave Blank",
        buttons=[("Yes", True), ("No", False)],
    ).run()
    excludestr = ""
    if confirm:
        exclude = checkboxlist_dialog(
            values=[
                ("remux", "Remux"),
                ("blu", "Blu-Ray Encode"),
                ("tv", "HDTV"),
                ("web", "WEB"),
                ("other", "Other"),
            ],
            title="Exclude",
            text="Pick the Source Types you would like to ignore ",
        ).run()

        for type in exclude:
            excludestr = excludestr + type + ","
    config.set('grab', "exclude", excludestr)

    confirm = False
    while confirm == False:
        outpath = input_dialog(
            title='Download Links Output TXT',
            text=
            'Please Enter a path for Writing Matched Links to.\nWith This Every Time a Match is found a download url will be written here\nPress Cancel to Leave Blank'
        ).run()
        if txtpath == None:
            break
        config.set('grab', "output", outpath)
        confirmtxt = "You entered:" + outpath + " is this Okay?"
        confirm = button_dialog(
            title=confirmtxt,
            buttons=[("Yes", True), ("No", False)],
        ).run()

    confirm = False
    while confirm == False:
        missingpath = input_dialog(
            title='Missing Files Output TXT',
            text=
            'Please Enter a path for Writing Potential Missing Files.\nDuring a "Missing Scan"  Every File is Compared to The Site Libary if the Slot is not already filled or your file is a encode.\nThe Path will be written to this TXT File\nThis is Required if you want to Find Files to upload'
        ).run()
        if txtpath == None:
            break
        config.set('general', "misstxt", missingpath)
        confirmtxt = "You entered:" + outpath + " is this Okay?"
        confirm = button_dialog(
            title=confirmtxt,
            buttons=[("Yes", True), ("No", False)],
        ).run()

    fd = ""
    config.set('general', "fd", fd)
    confirm = False
    while confirm == False:
        fd = input_dialog(
            title='FD',
            text=
            'FD is required for Program\nDownloads Can be found here https://github.com/sharkdp/fd/releases\nBy Default the program comes with a version of fd for your OS\nIf you want to use your own binary, you can enter your choice here \nPress Cancel to use the Default  '
        ).run()
        if txtpath == None:
            break
        config.set('general', "fd", fd)
        confirmtxt = "You entered:" + fd + " is this Okay?"
        confirm = button_dialog(
            title=confirmtxt,
            buttons=[("Yes", True), ("No", False)],
        ).run()

    wget = ""
    config.set('general', "wget", wget)
    confirm = False
    while confirm == False:
        wget = input_dialog(
            title='WGET',
            text=
            'WGET is required for Program\nLinux comes with this Preinstalled usually for windows:https://eternallybored.org/misc/wget/\nBy Default the program comes with a version of wget for Windows\nIf you want to use your own binary, you can enter your choice here \nPress Cancel to use the Default  '
        ).run()
        if txtpath == None:
            break
        config.set('general', "wget", wget)
        confirmtxt = "You entered:" + wget + " is this Okay?"
        confirm = button_dialog(
            title=confirmtxt,
            buttons=[("Yes", True), ("No", False)],
        ).run()

    sections = config.sections()
    config_string = ""
    for section in sections:
        options = config.options(section)
        for option in options:
            temp_dict = {}
            temp_dict[option] = config.get(section, option)
            config_string = config_string + str(temp_dict) + "\n"

    txt = "These are the Options that will be written to the configfile\nPlease Confirm if you want to save these Options\n Current File wil be overwritten\n\n" + config_string

    option = button_dialog(
        title="Confirm Options",
        text=txt,
        buttons=[("Yes", True), ("No", False)],
    ).run()
    if option == False:
        return
    with open(configpath, 'w') as configfile:
        print("Writing to configfile")
        config.write(configfile)
Example #12
0
from __future__ import unicode_literals

from prompt_toolkit.shortcuts import checkboxlist_dialog, message_dialog
from prompt_toolkit.styles import Style

results = checkboxlist_dialog(title="CheckboxList dialog",
                              text="What would you like in your breakfast ?",
                              values=[("eggs", "Eggs"), ("bacon", "Bacon"),
                                      ("croissants", "20 Croissants"),
                                      ("daily", "The breakfast of the day")],
                              style=Style.from_dict({
                                  'dialog':
                                  'bg:#cdbbb3',
                                  'button':
                                  'bg:#bf99a4',
                                  'checkbox':
                                  '#e8612c',
                                  'dialog.body':
                                  'bg:#a9cfd0',
                                  'dialog shadow':
                                  'bg:#c98982',
                                  'frame.label':
                                  '#fcaca3',
                                  'dialog.body label':
                                  '#fd8bb6',
                              })).run()
if results:
    message_dialog(title="Room service",
                   text="You selected: %s\nGreat choice sir !" %
                   ",".join(results)).run()
else:
"""
from __future__ import unicode_literals

from prompt_toolkit.shortcuts import checkboxlist_dialog, message_dialog
from prompt_toolkit.styles import Style

results = checkboxlist_dialog(
    title="CheckboxList dialog",
    text="What would you like in your breakfast ?",
    values=[
        ("eggs", "Eggs"),
        ("bacon", "Bacon"),
        ("croissants", "20 Croissants"),
        ("daily", "The breakfast of the day")
    ],
    style=Style.from_dict({
        'dialog': 'bg:#cdbbb3',
        'button': 'bg:#bf99a4',
        'checkbox': '#e8612c',
        'dialog.body': 'bg:#a9cfd0',
        'dialog shadow': 'bg:#c98982',
        'frame.label': '#fcaca3',
        'dialog.body label': '#fd8bb6',
    })
).run()
if results:
    message_dialog(
        title="Room service",
        text="You selected: %s\nGreat choice sir !" % ",".join(results)
    ).run()
else:
Example #14
0
        text = "Success, the image you have provided contains thermal data"
    else:
        sys.exit("The file you have provided does not contain thermal data")

else:
    sys.exit("The path you have provided does not exist")

message_dialog(title="Input Path Confirmation", text=text,
               ok_text="Continue").run()

results_array = checkboxlist_dialog(
    title="CheckboxList dialog",
    text="Select one or more output options (press tab to select ok/cancel)",
    values=[
        ("csv", "CSV file containing temperature data (in degrees celcius)"),
        ("bwr", "Thermal image using bwr colormap"),
        ("gnuplot2", "Thermal image gnuplot2 colormap"),
        ("gist_ncar", "Thermal image gist_ncar colormap"),
        # ("custom", "Thermal image using a custom colormap"),
    ],
).run()

# TODO; implement custom colormaps
# if "custom" in results_array:
#     custom_colormap = input_dialog(
#         title="Custom Matplotlib Colormap",
#         text="Matplotlib colormap name: ",
#     ).run()

# only ask the following if the user has selected a colormap
if not (len(results_array) == 1 and results_array[0] == "csv"):
Example #15
0
        install_result = radiolist_dialog(
            title="Linux CLI Toolkit",
            text="Select mode",
            values=[[Switch.Install.BUNDLES, "Bundles"],
                    [Switch.Install.PACKAGES, "Packages"]],
            style=style).run()

        if install_result == Switch.Install.BUNDLES:
            bundles = {
                "Networking": ["net-tools", "wireless-tools"],
                "Wireless hacking": ["aircrack-ng", "wifite", "hashcat"]
            }

            bundles_result = checkboxlist_dialog(title="Linux CLI Toolkit",
                                                 text="Select bundles",
                                                 values=[[bundles[i], i]
                                                         for i in bundles],
                                                 style=style).run()

            subprocess.run(["sudo apt update"], shell=True)
            subprocess.run([
                f"sudo apt install {' '.join([' '.join(i) for i in bundles_result])}"
            ],
                           shell=True)

        elif install_result == Switch.Install.PACKAGES:
            packages = {
                k: v
                for k, v in sorted({
                    "nmap": "Nmap",
                    "hashcat": "Hashcat",