def test_init(self):
     root_menu = CursesMenu("root_menu", "test_init")
     submenu1 = CursesMenu("submenu1", "test_init")
     submenu2 = CursesMenu("submenu2", "test_init")
     submenu3 = CursesMenu("submenu2", "test_init")
     menu_item_1 = SubmenuItem("menu_item_1", submenu1)
     menu_item_2 = SubmenuItem("menu_item_2", submenu2, root_menu, True)
     menu_item_3 = SubmenuItem(text="menu_item_3",
                               submenu=submenu3,
                               menu=root_menu,
                               should_exit=False)
     self.assertEqual(menu_item_1.text, "menu_item_1")
     self.assertEqual(menu_item_2.text, "menu_item_2")
     self.assertEqual(menu_item_3.text, "menu_item_3")
     self.assertIsNone(menu_item_1.menu)
     self.assertEqual(menu_item_2.menu, root_menu)
     self.assertEqual(menu_item_3.menu, root_menu)
     self.assertFalse(menu_item_1.should_exit)
     self.assertTrue(menu_item_2.should_exit)
     self.assertFalse(menu_item_3.should_exit)
     self.assertEqual(menu_item_1.submenu, submenu1)
     self.assertEqual(menu_item_2.submenu, submenu2)
     self.assertEqual(menu_item_3.submenu, submenu3)
     self.assertIsNone(menu_item_1.submenu.parent)
     self.assertEqual(menu_item_2.submenu.parent, root_menu)
     self.assertEqual(menu_item_3.submenu.parent, root_menu)
예제 #2
0
    def setUp(self):
        super(TestSampleMenu, self).setUp()

        self.menu = CursesMenu("self.menu", "TestSampleMenu")
        self.item1 = MenuItem("self.item1", self.menu)
        self.item2 = MenuItem("self.item2", self.menu)
        self.menu.append_item(self.item1)
        self.menu.append_item(self.item2)
        self.menu.start()
        self.menu.wait_for_start(timeout=10)
예제 #3
0
 def test_currently_active_menu(self):
     menu1 = CursesMenu("menu1", "test_currently_active_menu")
     menu2 = CursesMenu("menu2", "test_currently_active_menu")
     self.assertIsNone(CursesMenu.currently_active_menu)
     menu1.start()
     menu1.wait_for_start(10)
     self.assertIs(CursesMenu.currently_active_menu, menu1)
     menu2.start()
     menu2.wait_for_start(10)
     self.assertIs(CursesMenu.currently_active_menu, menu2)
예제 #4
0
def submenu_logging(menu_obj):
    submenu = CursesMenu("Logging Configuration")
    q1_item = FunctionItem("Do you want to turn enable logging?", input,
                           ['yes'])
    q2_item = FunctionItem(
        "If yes, do you want logging to stdout or a log file?", input,
        ['FILE'])
    submenu.append_item(q1_item)
    submenu.append_item(q2_item)
    submenu_item = SubmenuItem("Show a submenu", submenu, menu=menu_obj)
    return submenu_item
예제 #5
0
def submenu_backup(menu_obj):
    submenu = CursesMenu("Access Key Backup")
    q1_item = FunctionItem(
        "Do you want to retain a copy of newly created access keys?", input,
        ["yes"])
    q2_item = FunctionItem(
        "Enter the directory where a backup copy of the access keys should be stored",
        input, ["~/Backup"])
    submenu.append_item(q1_item)
    submenu.append_item(q2_item)
    submenu_item = SubmenuItem("Show a submenu", submenu, menu=menu_obj)
    return submenu_item
예제 #6
0
def create_menu(list_dict_stories, type_new):
    title = 'Pynews - {} stories'.format(type_new.capitalize())
    menu = CursesMenu(title, 'Select the new and press enter')
    msg = 'This new does not have an URL'
    for story in list_dict_stories:
        title = clean_title(story['title'])
        if 'url' in story:
            item = FunctionItem(title, url_open, args=[story['url']])
        else:
            item = FunctionItem(title, lambda x: print(x), args=[msg])
        menu.append_item(item)
    return menu
예제 #7
0
def create_menu(list_dict_stories, type_new):
    title = 'Pynews - {} stories'.format(type_new.capitalize())
    menu = CursesMenu(title, 'Select the new and press enter')
    msg = 'This new does not have an URL'
    for story in list_dict_stories:
        title = clean_title(story['title'])
        if 'url' in story:
            item = FunctionItem(title, url_open, args=[story['url']])
        else:
            item = FunctionItem(title, lambda x: print(x), args=[msg])
        menu.append_item(item)
    return menu
예제 #8
0
파일: editor.py 프로젝트: olagrottvik/bust
    def show_menu(self):
        self.menu = CursesMenu('bust - Module Editor', self.set_subtitle())

        self.menu.append_item(FunctionItem('Edit name', self.edit_name))
        self.menu.append_item(
            FunctionItem('List registers', self.list_registers))
        self.menu.append_item(
            FunctionItem('Add new register', self.add_register))
        self.menu.append_item(
            FunctionItem('Remove register', self.remove_register))
        self.menu.append_item(
            FunctionItem('Update addresses', self.update_addresses))
        self.menu.append_item(FunctionItem('Save JSON', self.save_JSON))
        self.menu.show()
예제 #9
0
 def test_init(self):
     menu1 = CursesMenu()
     menu2 = CursesMenu("menu2", "test_init", True)
     menu3 = CursesMenu(title="menu3",
                        subtitle="test_init",
                        show_exit_option=False)
     self.assertIsNone(menu1.title)
     self.assertEqual(menu2.title, "menu2")
     self.assertEqual(menu3.title, "menu3")
     self.assertIsNone(menu1.subtitle)
     self.assertEqual(menu2.subtitle, "test_init")
     self.assertEqual(menu3.subtitle, "test_init")
     self.assertTrue(menu1.show_exit_option)
     self.assertTrue(menu2.show_exit_option)
     self.assertFalse(menu3.show_exit_option)
예제 #10
0
class Xfce:
    """
    #
    # Модуль налаштувань для XFCE
    #
    """

    # Основне меню
    menu = CursesMenu("XFCE soft")

    # Пункти меню
    _menu_items = [
        CommandItem("All remove", "bash bash/xfce.sh"),
        CommandItem("Remove XFCE4-Notes", "sudo apt autoremove xfce4-notes"),
        CommandItem("Remove Pidgin", "sudo apt autoremove pidgin"),
        CommandItem("Remove Thunderbird", "sudo apt autoremove thunderird"),
        CommandItem("Remove Parole", "sudo apt autoremove parole"),
        CommandItem("Remove Sudoku", "sudo apt autoremove gnome-sudoku"),
        CommandItem("Remove Mines", "sudo apt autoremove gnome-mines"),
        CommandItem("Remove firefox", "sudo apt autoremove firefox")
    ]

    # Додавання пунктів до меню
    for item in _menu_items:
        menu.append_item(item)
예제 #11
0
class InstallSoft:
    """
    #
    # Модуль встановлення програм
    #
    """

    # Основне меню
    menu = CursesMenu("Install software", "DEPENDENCES!!!")

    # Пункти меню
    _menu_items = [
        CommandItem("All software", "bash bash/install.sh"),
        CommandItem("ssh", "sudo apt install ssh"),
        CommandItem("Gparted", "sudo apt install gparted"),
        CommandItem("VLC", "sudo apt install vlc"),
        CommandItem("screenfetch", "sudo apt install screenfetch"),
        CommandItem("f.lux", "bash bash/f.lux.sh"),
        CommandItem("gimp", "sudo apt install gimp"),
        CommandItem("Kdenlive", "sudo apt install kdenlive"),
        CommandItem("Wine", "sudo apt install wine"),
        CommandItem("Rhythmbox", "sudo apt install rhythmbox")
    ]

    # Додавання пунктів до меню
    for item in _menu_items:
        menu.append_item(item)
예제 #12
0
class RemoveProgram:
    """
    #
    # Видалення програм
    #
    """

    # Основне меню
    menu = CursesMenu("Remove software", "YOU DELETE SOFT!!!")

    # Пункти меню
    _menu_items = [
        CommandItem("All software", "bash bash/remove.sh"),
        CommandItem("ssh", "sudo apt autoremove ssh"),
        CommandItem("Gparted", "sudo apt autoremove gparted"),
        CommandItem("VLC", "sudo apt autoremove vlc"),
        CommandItem("screenfetch", "sudo apt autoremove screenfetch"),
        CommandItem("f.lux", "sudo apt autoremove flux"),
        CommandItem("gimp", "sudo apt autoremove gimp"),
        CommandItem("Kdenlive", "sudo apt autoremove kdenlive"),
        CommandItem("Wine", "sudo apt autoremove wine"),
        CommandItem("Rhythmbox", "sudo apt autoremove rhythmbox")
    ]
    # Додавання пунктів до меню
    for item in _menu_items:
        menu.append_item(item)
예제 #13
0
def step_impl(context):
    context.menu = CursesMenu("Test Menu", "Subtitle")
    context.menu_item = MenuItem("NORMAL", "Menu Item")
    context.menu.append_item(context.menu_item)
    context.function_item = FunctionItem("NORMAL", "Call a Python function",
                                         input, ["Enter an input"])
    context.menu.append_item(context.function_item)
    pass
예제 #14
0
    def setUp(self):
        super(TestSampleMenu, self).setUp()

        self.menu = CursesMenu("self.menu", "TestSampleMenu")
        self.item1 = MenuItem("self.item1", self.menu)
        self.item2 = MenuItem("self.item2", self.menu)
        self.menu.append_item(self.item1)
        self.menu.append_item(self.item2)
        self.menu.start()
        self.menu.wait_for_start(10)
예제 #15
0
class Menu:
    def __init__(self, recipes):
        self.recipes = recipes

        self.title = 'PyVegan - List of Recipes'
        self.menu = CursesMenu(self.title, 'Select one and press enter')
        self.error_msg = 'This search isn\'t a valid one'

    def build(self):
        for recipe in self.recipes:
            if recipe.link:
                item = FunctionItem(recipe.title, url_open, args=[recipe.link])
            else:
                item = FunctionItem(recipe.title,
                                    lambda x: print(x),
                                    args=[self.error_msg])
            self.menu.append_item(item)

    def show(self):
        self.menu.show()
예제 #16
0
def generate_menu(menu=None, menu_cfg=None, parent_title=None):
    if not menu_cfg:
        menu_cfg = c.get_menu()

    if not menu:
        title = get_string(menu_cfg, 'title')
        subtitle = get_string(menu_cfg, 'subtitle', params=parent_title)

        menu = CursesMenu(title, subtitle)

    options = menu_cfg['options']

    if type(options) == str and get_string(menu_cfg, 'type') == 'submenu':
        options_list = c.get_config()[options]
        for option in options_list:
            if 'on_item_select' in menu_cfg:
                title = get_string(menu_cfg, 'title')
                subtitle = get_string(menu_cfg['on_item_select'], 'subtitle', params=option)

                submenu = CursesMenu(title, subtitle)
                option_menu = generate_menu(menu_cfg=menu_cfg['on_item_select'], parent_title=option)
                item = SubmenuItem(option, option_menu, menu=submenu)
            else:
                item = FunctionItem(option, getattr(c.get_action_module(), menu_cfg['action']), [option])  # TODO allow for customisation of module name
            menu.append_item(item)

    else:
        for option in menu_cfg['options']:

            cmd_type = get_string(option, 'type')
            title = get_string(option, 'title')
            action = get_string(option, 'action')

            subtitle = get_string(option, 'subtitle')

            if cmd_type == 'function':
                item = FunctionItem(title, getattr(actions, action))

            elif cmd_type == 'submenu':
                submenu = CursesMenu(title, subtitle)
                item = SubmenuItem(title, submenu, menu=menu)
                generate_menu(submenu, option, title)
            else:
                item = MenuItem(title)

            menu.append_item(item)

    return menu
예제 #17
0
 def test_init(self):
     menu = CursesMenu("menu", "test_init")
     exit_item_1 = ExitItem("exit_item_1")
     exit_item_2 = ExitItem("exit_item_2", menu)
     exit_item_3 = ExitItem(text="exit_item_3", menu=menu)
     self.assertEqual(exit_item_1.text, "exit_item_1")
     self.assertEqual(exit_item_2.text, "exit_item_2")
     self.assertEqual(exit_item_3.text, "exit_item_3")
     self.assertEqual(exit_item_1.menu, None)
     self.assertEqual(exit_item_2.menu, menu)
     self.assertEqual(exit_item_3.menu, menu)
     self.assertTrue(exit_item_1.should_exit)
     self.assertTrue(exit_item_2.should_exit)
     self.assertTrue(exit_item_3.should_exit)
예제 #18
0
def step_impl(context):
    context.menu = CursesMenu("Test Menu", "Subtitle")
    context.menu_item = MenuItem("NORMAL", "Menu Item")
    context.menu.append_item(context.menu_item)
    context.function_item = FunctionItem("NORMAL", "Call a Python function",
                                         input, ["Enter an input"])
    context.menu.append_item(context.function_item)
    context.command_item = CommandItem("NORMAL", "Run a console command",
                                       "ipconfig /all")
    context.menu.append_item(context.command_item)
    context.selection_menu = SelectionMenu(["item1", "item2", "item3"])
    context.selection_submenu_item = SubmenuItem("NORMAL", "Submenu item",
                                                 context.selection_menu)
    context.menu.append_item(context.selection_submenu_item)
    pass
예제 #19
0
def main():
    """ Builds main menu, branches to submenus """

    # parent menu
    menu = CursesMenu("Local Configuration Menu", "keyup Project")

    try:
        submenu_backup = submenu_backup(menu)
        submenu_logging = submenu_logging(menu)

        # assemble main menu
        menu.append_item(submenu_backup)
        menu.append_item(submenu_logging)

        menu.show()
        user_selection = menu.selected_option
    except Exception as e:
        print('Unknown Exception: %s. Exit' % str(e))
        return False
    return True
예제 #20
0
def generate_menu(tasks):
    """ Create menu for process selection """
    menu = CursesMenu("Select something to kill him!")

    # a CommandItem runs a console command
    for pid, name in tasks.items():
        label = "{:<8} - {}".format('[' + str(pid) + ']', name[:40])
        command = "kill {}".format(pid)

        menu.append_item(cmitems.CommandItem(label, command))

    # show the menu and allow the user to interact
    menu.show()
예제 #21
0
class SshX:
    """
    #
    # Модуль підключення SSH з підтримкою запуска програм з графічним інтерфейсом
    #
    """

    menu = CursesMenu("SSH connect with X-window support")

    # Пункти
    _menu_items = [
        CommandItem("Home ms-7519(ivan)", "ssh -X [email protected]"),
        CommandItem("Acer-aspire V5-131(ivan)", "ssh -X [email protected]"),
        CommandItem("Lenovo B560(diana)", "ssh -X [email protected]"),
        CommandItem("Server(home)", "ssh -X [email protected]")
    ]

    #  Додаваня пунктів до меню
    for item in _menu_items:
        menu.append_item(item)
예제 #22
0
class SSH:
    """
   #
   # SSH підключення
   #
    """

    # Основне меню
    menu = CursesMenu("SSH Connect")

    # Пунктии меню
    _menu_items = [
        CommandItem("DIR 615-E4", "ssh [email protected]"),
        CommandItem("Home ms-7519(ivan)", "ssh [email protected]"),
        CommandItem("Acer-aspire V5-131(ivan)", "ssh [email protected]"),
        CommandItem("Lenovo B560(diana)", "ssh [email protected]"),
        CommandItem("Server(home)", "ssh [email protected]")
    ]

    # Додавання пунктів до меню
    for item in _menu_items:
        menu.append_item(item)
예제 #23
0
        submenu_logging = submenu_logging(menu)

        # assemble main menu
        menu.append_item(submenu_backup)
        menu.append_item(submenu_logging)

        menu.show()
        user_selection = menu.selected_option
    except Exception as e:
        print('Unknown Exception: %s. Exit' % str(e))
        return False
    return True


if __name__ == '__main__':
    menu = CursesMenu("Local Configuration Menu", "xlines Project")
    # backup
    submenu = CursesMenu("Exclusions",
                         'Do you want to add a new file type exclusion?')
    q1_item1 = FunctionItem("Yes", input, ["yes"])
    q1_item2 = FunctionItem("No", print('Exit'), ["no"])
    submenu.append_item(q1_item1)
    submenu.append_item(q1_item2)
    submenu_exclusions = SubmenuItem("Configure Exclusion List",
                                     submenu,
                                     menu=menu)
    menu.append_item(submenu_exclusions)
    if q1_item1 == "yes":
        display_exclusions()
        submenu = CursesMenu(
            "Access Key Backup",
예제 #24
0
 def setUp(self):
     super(TestCommandItem, self).setUp()
     self.menu = CursesMenu("self.menu", "TestCommandItem")
예제 #25
0
    def run(self):
        menu = CursesMenu("Openstack Toolset", "Restore OpenStack Virtual Machine Block Device from SAN - By Real World")
        options = ['Restore State']

        for idx, item in enumerate(options):
            menu.append_item(SelectionItem(item, idx))

        submenu = CursesMenu("Contact the Author.")
        contact = SubmenuItem("Author: Karl Kloppenborg", submenu=submenu)
        contact2 = SubmenuItem("Email: [email protected]", submenu=submenu)
        submenu.append_item(contact)
        submenu.append_item(contact2)

        sub = SubmenuItem("Help!", submenu, menu=menu)
        menu.append_item(sub)

        menu.show()
        return menu.selected_option
예제 #26
0
def step_impl(context):
    context.menu = CursesMenu("Test Menu", "Subtitle")
    pass
예제 #27
0
    def create_menu(self) -> None:
        # Create the menu
        self.menu = CursesMenu("PyMeterReader Configuration Wizard",
                               "Choose item to configure")

        function_item = FunctionItem("Volkszähler Gateway",
                                     self.input_gw, ["Enter URL: "],
                                     should_exit=True)
        self.menu.append_item(function_item)

        for meter in self.meters:
            meter_menu = CursesMenu(
                f"Connect channels for meter {meter.meter_id} at {meter.meter_address}",
                "By channel")
            for channel in meter.channels:
                map_menu = CursesMenu(
                    f"Choose uuid for {channel.channel_name}")
                for choice in self.gateway_channels:
                    map_menu.append_item(
                        FunctionItem(f"{choice.uuid}: {choice.title}",
                                     self.__assign,
                                     [meter, channel, choice.uuid, '30m'],
                                     should_exit=True))
                map_menu.append_item(
                    FunctionItem("Enter private UUID",
                                 self.__assign, [meter, channel, None, '30m'],
                                 should_exit=True))
                meter_menu.append_item(
                    SubmenuItem(
                        f"{channel.channel_name}: {channel.value} {channel.unit}",
                        map_menu, self.menu))
            submenu_item = SubmenuItem(f"Meter {meter.meter_id}", meter_menu,
                                       self.menu)

            self.menu.append_item(submenu_item)

        view_item = FunctionItem("View current mapping", self.__view_mapping)
        self.menu.append_item(view_item)

        save_item = FunctionItem("Save current mapping", self.__safe_mapping)
        self.menu.append_item(save_item)

        register_service = FunctionItem(
            "Register PymeterReader as systemd service.",
            self.__register_service)
        self.menu.append_item(register_service)

        reset_item = FunctionItem("Reset all mappings", self.__clear)
        self.menu.append_item(reset_item)

        self.menu.show()
예제 #28
0
class Wizard:
    CONFIG_FILE_NAME = "pymeterreader.yaml"
    POSIX_CONFIG_PATH = Path("/etc") / CONFIG_FILE_NAME

    def __init__(self) -> None:
        logging.basicConfig(level=logging.INFO)
        self.url = "http://localhost/middleware.php"
        self.gateway = VolkszaehlerGateway(self.url)
        self.gateway_channels = self.gateway.get_channels()
        self.menu: CursesMenu
        print("Detecting meters...")
        self.meters = detect()
        self.channel_config: tp.Dict[str, tp.Dict[str,
                                                  tp.Union[str,
                                                           tp.Dict]]] = {}
        self.restart_ui = True
        while self.restart_ui:
            self.restart_ui = False
            self.create_menu()

    def input_gw(self, text) -> None:
        def is_valid_url():
            return re.match(r"^https?://[/\w\d.]+.php$", self.url)

        self.restart_ui = True
        self.menu.clear_screen()
        self.url = "invalid"
        while self.url and not is_valid_url():
            self.url = input(text)
            if not self.url:
                self.menu.stdscr.addstr(
                    3, 0, "Defaulting to http://localhost/middleware.php")
                self.url = "http://localhost/middleware.php"
                self.menu.stdscr.getkey()
            elif not is_valid_url():
                self.menu.stdscr.addstr(
                    3, 0, "Entered url is not valid."
                    " It must start with 'http://' or 'https://' and end with '.php'"
                )
                self.menu.stdscr.getkey()
        self.gateway = VolkszaehlerGateway(self.url)
        self.gateway_channels = self.gateway.get_channels()
        if self.gateway_channels:
            self.menu.stdscr.addstr(
                3, 0,
                f"Found {len(self.gateway_channels)} public channels at gateway '{self.url}'."
            )
        else:
            self.menu.stdscr.addstr(
                3, 0, f"Unable to find any public channels at '{self.url}'.")
        self.menu.stdscr.getkey()

    def create_menu(self) -> None:
        # Create the menu
        self.menu = CursesMenu("PyMeterReader Configuration Wizard",
                               "Choose item to configure")

        function_item = FunctionItem("Volkszähler Gateway",
                                     self.input_gw, ["Enter URL: "],
                                     should_exit=True)
        self.menu.append_item(function_item)

        for meter in self.meters:
            meter_menu = CursesMenu(
                f"Connect channels for meter {meter.meter_id} at {meter.meter_address}",
                "By channel")
            for channel in meter.channels:
                map_menu = CursesMenu(
                    f"Choose uuid for {channel.channel_name}")
                for choice in self.gateway_channels:
                    map_menu.append_item(
                        FunctionItem(f"{choice.uuid}: {choice.title}",
                                     self.__assign,
                                     [meter, channel, choice.uuid, '30m'],
                                     should_exit=True))
                map_menu.append_item(
                    FunctionItem("Enter private UUID",
                                 self.__assign, [meter, channel, None, '30m'],
                                 should_exit=True))
                meter_menu.append_item(
                    SubmenuItem(
                        f"{channel.channel_name}: {channel.value} {channel.unit}",
                        map_menu, self.menu))
            submenu_item = SubmenuItem(f"Meter {meter.meter_id}", meter_menu,
                                       self.menu)

            self.menu.append_item(submenu_item)

        view_item = FunctionItem("View current mapping", self.__view_mapping)
        self.menu.append_item(view_item)

        save_item = FunctionItem("Save current mapping", self.__safe_mapping)
        self.menu.append_item(save_item)

        register_service = FunctionItem(
            "Register PymeterReader as systemd service.",
            self.__register_service)
        self.menu.append_item(register_service)

        reset_item = FunctionItem("Reset all mappings", self.__clear)
        self.menu.append_item(reset_item)

        self.menu.show()

    def __register_service(self) -> None:
        self.menu.clear_screen()
        if platform.system() != "Linux":
            self.menu.stdscr.addstr(
                0, 0,
                "Systemd Service registration is only supported on Linux!")
            self.menu.stdscr.addstr(1, 0, "(press any key)")
            self.menu.stdscr.getkey()
            return
        self.menu.stdscr.addstr(0, 0, "Installing service...")
        run(
            'sudo systemctl stop pymeterreader',  # pylint: disable=subprocess-run-check
            universal_newlines=True,
            shell=True)

        target_service_file = "/etc/systemd/system/pymeterreader.service"

        service_str = SERVICE_TEMPLATE.format(
            f'pymeterreader -c {self.POSIX_CONFIG_PATH.absolute()}')
        try:
            with open(target_service_file, 'w') as target_file:
                target_file.write(service_str)
            run(
                'systemctl daemon-reload',  # pylint: disable=subprocess-run-check
                universal_newlines=True,
                shell=True)
            if not exists(self.POSIX_CONFIG_PATH):
                self.menu.stdscr.addstr(
                    1, 0,
                    f"Copy example configuration file to '{self.POSIX_CONFIG_PATH.absolute()}'"
                )
                with open('example_configuration.yaml', 'r') as file:
                    example_config = file.read()
                with open(self.POSIX_CONFIG_PATH, 'w') as file:
                    file.write(example_config)
            self.menu.stdscr.addstr(
                2, 0, "Registered pymeterreader as service.\n"
                "Enable with 'sudo systemctl enable pymeterreader'\n."
                f"IMPORTANT: Create configuration file '{self.POSIX_CONFIG_PATH.absolute()}'"
            )
        except FileNotFoundError as err:
            self.menu.stdscr.addstr(4, 0, f"Could not access file: {err}!")
        except PermissionError:
            self.menu.stdscr.addstr(
                4, 0, "Cannot write service file to /etc/systemd/system. "
                "Run as root (sudo) to solve this.")
        self.menu.stdscr.addstr(6, 0, "(press any key)")
        self.menu.stdscr.getkey()

    def __clear(self) -> None:
        """
        Remove channel mappings
        """
        self.channel_config.clear()

    def __safe_mapping(self) -> None:
        """
        Save yaml to system
        """
        self.menu.clear_screen()
        result = generate_yaml(self.channel_config, self.url)
        try:
            if platform.system() in ["Linux", "Darwin"]:
                config_path = self.POSIX_CONFIG_PATH
            else:
                config_path = Path(".") / "pymeterreader.yaml"
            with open(config_path, "w") as config_file:
                config_file.write(result)
            self.menu.stdscr.addstr(0, 0, f"Saved to {config_path.absolute()}")
        except PermissionError:
            self.menu.stdscr.addstr(
                0, 0,
                f"Insufficient permissions: cannot write to {config_path.absolute()}!"
            )
        except FileNotFoundError:
            self.menu.stdscr.addstr(
                0, 0, f"Could not access path: {config_path.absolute()}!")
        self.menu.stdscr.addstr(1, 0, "(press any key)")
        self.menu.stdscr.getkey()

    def __view_mapping(self) -> None:
        self.menu.clear_screen()
        self.menu.stdscr.addstr(0, 0, "Mapped channels:")
        row = 2
        for meter in self.channel_config.values():
            for channel, content in meter['channels'].items():
                self.menu.stdscr.addstr(
                    row, 2,
                    f"{channel} at {meter.get('id')} mapped to UUID {content.get('uuid')}"
                )
                row += 1
        self.menu.stdscr.addstr(row, 0, "(press any key)")
        self.menu.stdscr.getkey()

    def __assign(self, meter: Device, channel: ChannelValue,
                 uuid: tp.Optional[str], interval: str) -> None:
        if uuid is None:
            self.menu.clear_screen()
            uuid = input("Enter private UUID: ")
        if meter.meter_id not in self.channel_config:
            self.channel_config[meter.meter_id] = {
                'channels': {},
                'protocol': meter.protocol,
                'meter_address': meter.meter_address,
                'meter_id': meter.meter_id
            }
        self.channel_config[meter.meter_id]['channels'][
            channel.channel_name] = {
                'uuid': uuid,
                'interval': interval
            }
예제 #29
0
def parse_old_menu(menu_data):
    """
    Take an old-style menuData dictionary and return a CursesMenu

    :param dict menu_data:
    :return: A new CursesMenu
    :rtype: CursesMenu
    """
    menu_title = menu_data['title']
    menu = CursesMenu(menu_title)
    for item in menu_data["options"]:
        item_type = item["type"]
        item_title = item["title"]
        if item_type == menuItem.COMMAND:
            item_command = item["command"]
            menu.append_item(CommandItem(item_title, item_command, menu))
        elif item_type == menuItem.FUNCTION:
            item_function = item["function"]
            menu.append_item(FunctionItem(item_title, item_function, menu))
        elif item_type == menuItem.EXITMENU:
            menu.append_item(ExitItem(item_title, menu))
        elif item_type == menuItem.NUMBER:
            menu.append_item(SelectionItem(item_title, menu))
        elif item_type == menuItem.MENU:
            new_menu = parse_old_menu(item)
            menu.append_item(SubmenuItem(item_title, menu, new_menu))

    return menu
예제 #30
0
# Основне меню. Запускати програму з цього файла
#

# Класи для створення меню
from cursesmenu import CursesMenu
from cursesmenu.items import CommandItem, SubmenuItem
import platform

from modules import InstallSoft as soft
from modules import RemoveProgram as remove
from modules import SSH as ssh
from modules import SshX as ssh_X
from modules import Xfce as xfce

# Створення основного меню
menu = CursesMenu("Ubuntu universal script", platform.version())
# Створення основних пунктів
_menu_items = [
    CommandItem("Update paсkages", "sudo apt update"),
    CommandItem("Upgrade paсkages", "sudo apt upgrade"),
    CommandItem("Autoremove paсkages", "sudo apt autoremove"),
    CommandItem("Remove other kernel`s", "bash bash/remove_kernel.sh"),
    CommandItem(
        "Cleaning pickings removed paсkages",
        "sudo dpkg -l | awk '/^rc/ {print $2}' | xargs sudo dpkg --purge"),

    # Відображення підменю
    SubmenuItem("Install soft", soft.menu, menu),
    SubmenuItem("Remove software", remove.menu, menu),
    SubmenuItem("Xfce soft", xfce.menu, menu),
    SubmenuItem("SSH Connect", ssh.menu, menu),
    def test_action(self):
        root_menu = CursesMenu("root_menu", "test_action")
        submenu1 = CursesMenu("submenu1", "test_action")
        submenu2 = CursesMenu("submenu2", "test_action")
        submenu_item_1 = SubmenuItem("submenu_item_1", submenu1, menu=root_menu)
        submenu_item_2 = SubmenuItem("submenu_item_2", submenu2, menu=root_menu)

        root_menu.append_item(submenu_item_1)
        root_menu.append_item(submenu_item_2)

        root_menu.start()
        root_menu.wait_for_start(timeout=10)
        self.assertIs(CursesMenu.currently_active_menu, root_menu)
        submenu_item_1.action()
        submenu1.wait_for_start(timeout=10)
        self.assertIs(CursesMenu.currently_active_menu, submenu1)
        CursesMenu.currently_active_menu.exit()
        submenu1.join(timeout=10)
        self.assertIs(CursesMenu.currently_active_menu, root_menu)
        submenu_item_2.action()
        submenu2.wait_for_start(timeout=10)
        self.assertIs(CursesMenu.currently_active_menu, submenu2)
예제 #32
0
def step_impl(context):
    context.menu = CursesMenu("Test Menu", "Subtitle")
    context.menu_item = MenuItem("NORMAL", "Menu Item")
    context.menu.append_item(context.menu_item)
    pass
예제 #33
0
파일: editor.py 프로젝트: olagrottvik/bust
class Editor(object):
    """A console-based menu system for creating and editing module descripting JSON files

    """
    def __init__(self, edit, jsonfile, output_dir='output/'):
        """Constructor

        Either reconstructs a module object from JSON, or create a new based on user input
        """
        self.jsonfile = jsonfile
        self.output_dir = output_dir
        self.recently_saved = False

        if edit:
            # Load the specified JSON file
            try:
                json = json_parser(jsonfile)
                self.settings = Settings(jsonfile, json['settings'])
                self.bus = Bus(json['bus'])
                self.mod = Module(json['module'], self.bus, self.settings)
                self.recently_saved = True
            except Exception as e:
                print('An unresolvable error has occurred:')
                print(str(e))
                print('Exiting...')
                exit()
        else:
            bus_dic = OrderedDict()
            bus_dic['type'] = get_list_choice('Choose a bus type: ',
                                              Bus.supported_bus)
            bus_dic['addr_width'] = 32
            bus_dic['data_width'] = 32
            bus_dic['reset'] = 'async'
            self.bus = Bus(bus_dic)

            # Get name, addr_width, data_width and description
            mod = OrderedDict()
            mod['name'] = get_identifier('Enter a module name: ')
            '''! @todo Add int check'''
            mod['addr_width'] = 32
            mod['data_width'] = 32
            mod['description'] = input('Enter a description for the module: ')
            mod['register'] = []

            self.settings = Settings(None, None)
            self.mod = Module(mod, self.bus, self.settings)

    def show_menu(self):
        self.menu = CursesMenu('bust - Module Editor', self.set_subtitle())

        self.menu.append_item(FunctionItem('Edit name', self.edit_name))
        self.menu.append_item(
            FunctionItem('List registers', self.list_registers))
        self.menu.append_item(
            FunctionItem('Add new register', self.add_register))
        self.menu.append_item(
            FunctionItem('Remove register', self.remove_register))
        self.menu.append_item(
            FunctionItem('Update addresses', self.update_addresses))
        self.menu.append_item(FunctionItem('Save JSON', self.save_JSON))
        self.menu.show()

    def update_menu(self):
        self.menu.subtitle = self.set_subtitle()

    def edit_name(self):
        print('Change the module name from current: ' + self.mod.name)
        self.mod.name = get_identifier('Enter a new name: ')
        self.recently_saved = False
        self.update_menu()

    def return_registers(self):
        while True:
            clear_screen()
            if len(self.mod.registers) < 1:
                print('No registers created at this point...')
                cont()
                return
            else:
                table = PrettyTable()
                table.field_names = [
                    '#', 'Name', 'Mode', 'Address', 'Type', 'Length', 'Reset',
                    'Description'
                ]
                for i, reg in enumerate(self.mod.registers):
                    table.add_row([
                        i, reg.name, reg.mode,
                        hex(reg.address), reg.sig_type, reg.length, reg.reset,
                        add_line_breaks(reg.description, 25)
                    ])
                return table

    def list_registers(self):
        table = self.return_registers()
        if table is None:
            return
        print(table)
        print(
            '\nEnter the register number for register details, or q to quit...'
        )
        while True:
            choice = input('Choice: ')
            if self.valid_register_input(choice):
                break
            else:
                print(choice + ' is not a valid choice')
        if choice == 'q':
            return
        else:
            clear_screen()
            self.print_register(int(choice), table)
            cont()

    def print_register(self, reg_num, table):
        reg = self.mod.registers[reg_num]
        print(table.get_string(start=reg_num, end=(reg_num + 1)))

        if len(reg.fields) > 0:
            print('\nFields:')
            table_fields = PrettyTable()
            table_fields.field_names = [
                '#', 'Name', 'Type', 'Position', 'Length', 'Reset',
                'Description'
            ]
            for i, field in enumerate(reg.fields):

                table_fields.add_row([
                    i, field.name, field.sig_type,
                    field.get_pos_str(), field.length, field.reset,
                    add_line_breaks(field.description, 25)
                ])

            print(table_fields)

    def add_register(self):
        """Adds a register to the module object

        Get user input to create a register that may or may not consists of individual fields
        """
        reg = OrderedDict()
        reg_names = [regs.name for regs in self.mod.registers]
        print('Input register information: ')
        try:
            reg['name'] = get_identifier('Name: ', reg_names)
            reg['description'] = input('Description: ')
            reg['mode'] = get_list_choice("Choose register mode: ",
                                          Register.supported_modes, 'lower', 0)

            fields = []

            width_consumed = 0
            while True:
                field_dic = OrderedDict()
                add_fields = input('Do you want to add a field? (Y/n): ')
                field_names = [field['name'] for field in fields]
                if add_fields.upper() == 'N':
                    break
                elif add_fields.upper() == 'Y' or add_fields == '':
                    field_dic['name'] = get_identifier('Field name: ',
                                                       field_names)
                    field_dic['type'] = get_list_choice(
                        'Field type: ', Field.supported_types)

                    if field_dic['type'] == 'slv':
                        max_width = self.mod.data_width - width_consumed

                        field_dic['length'] = get_int(
                            'Field length: ', 10, 1, max_width,
                            "The minimum width of a field is 1!",
                            "The maximum width of this field cannot extend" +
                            " the module data width minus the width already" +
                            " consumed by other fields: " + str(max_width))
                        width_consumed += field_dic['length']

                    else:
                        width_consumed += 1
                        field_dic['length'] = 1

                    max_reset = 2**field_dic['length'] - 1
                    field_dic['reset'] = hex(
                        get_int(
                            'Field reset in hex (default=0x0): ', 16, 0x0,
                            max_reset, "The minimum reset value is 0x0",
                            "The maximum reset value is based on the field width, "
                            + "and is " + str(hex(max_reset)), 0x0))

                    field_dic['description'] = input('Field description: ')

                    fields.append(field_dic)
                    # Check if all available data bits are use
                    if width_consumed == self.mod.data_width:
                        print(
                            "All available bits (" + str(self.mod.data_width) +
                            ") is consumed.\n" +
                            "No more fields can be added to this register.\n")
                        break
                    elif width_consumed > self.mod.data_width:
                        raise RuntimeError(
                            "More bits used by fields than available...")

                else:
                    print(add_fields + ' is not a valid choice...')

            if len(fields) > 0:
                reg['type'] = 'fields'
                reg['fields'] = fields

            else:
                reg['type'] = get_list_choice('Register type: ',
                                              Register.supported_types, None,
                                              0)

            # Make sure reg length is set to help calculate max reset later
            # Registers of field type will get an auto reset based on the field resets
            if reg['type'] == 'default':
                reg['length'] = self.mod.data_width
            elif reg['type'] == 'sl':
                reg['length'] = 1
            elif reg['type'] == 'slv':
                while True:
                    try:
                        reg['length'] = int(input('Length: '))
                        break
                    except Exception:
                        print('That is not a valid length...')

            if input('Auto-assign address? (Y/n): ').upper() == 'N':
                # Make sure the address is not out of range and that it is free
                max_address = 2**self.mod.addr_width - 1

                while True:
                    reg['address'] = get_int(
                        "Address in hex: ", 16, 0x0, max_address,
                        "The minimum address is 0x0",
                        "The maximum address is based on the module address width, "
                        + "and is " + str(hex(max_address)), 0x0)
                    # Perform an extra check of address range, although redundant
                    if self.mod.is_address_out_of_range(reg['address']):
                        print("Address is out of range...")
                        continue

                    # Check if the address has not been taken
                    if not self.mod.is_address_free(reg['address']):
                        print(
                            "The chosen address is already assigned to another register..."
                        )
                        continue

                    # Check whether the address is not byte-addressed, and give the user a choice to continue
                    if not self.mod.is_address_byte_based(reg['address']):
                        choice = input(
                            "The selected address is not byte-based. Continue? (y/N): "
                        )
                        if not choice.upper() == 'Y':
                            continue
                    break

            if reg['type'] != 'fields':

                max_reset = 2**reg['length'] - 1
                reg['reset'] = hex(
                    get_int(
                        'Register reset in hex (default=0x0): ', 16, 0x0,
                        max_reset, "The minimum reset value is 0x0",
                        "The maximum reset value is based on the register width, "
                        + "and is " + str(hex(max_reset)), 0x0))

            table = PrettyTable()
            table.field_names = [
                '#', 'Name', 'Mode', 'Address', 'Type', 'Length', 'Reset',
                'Description'
            ]

            # Table values based on what values exists
            table_name = reg['name']
            table_mode = reg['mode']

            if 'address' in reg:
                table_address = reg['address']
            else:
                table_address = 'auto'

            table_type = reg['type']

            if reg['type'] == 'fields':
                table_length = 'auto'
            elif 'length' in reg:
                table_length = reg['length']
            else:
                table_length = self.mod.bus.data_width

            if reg['type'] == 'fields':
                table_reset = 'auto'
            elif 'reset' in reg:
                table_reset = reg['reset']
            else:
                table_reset = 'auto'

            table_description = add_line_breaks(reg['description'], 25)

            table.add_row([
                len(self.mod.registers), table_name, table_mode, table_address,
                table_type, table_length, table_reset, table_description
            ])

            print(table)

            if 'fields' in reg:
                print('\nFields:')
                table_fields = PrettyTable()
                table_fields.field_names = [
                    '#', 'Name', 'Type', 'Length', 'Reset', 'Description'
                ]
                for i, field in enumerate(reg['fields']):

                    table_fields.add_row([
                        i, field['name'], field['type'], field['length'],
                        field['reset'], field['description']
                    ])

                print(table_fields)

            if input('Confirm creation of register? (Y/n): ').upper() != 'N':
                self.mod.add_register(reg)

                self.recently_saved = False
                self.update_menu()
            else:
                return

        except KeyboardInterrupt:
            print('\nAdding register aborted!')
            cont()

        except Exception as e:
            print('\nAdding register failed!')
            print(str(e))
            cont()

    def remove_register(self):
        table = self.return_registers()
        if table is None:
            return
        print(table)
        print('\nEnter the register number for removal, or q to quit...')
        while True:
            choice = input('Choice: ')
            if self.valid_register_input(choice):
                break
            else:
                print(choice + ' is not a valid choice')
        if choice == 'q':
            return
        else:
            clear_screen()
            self.print_register(int(choice), table)

            if input('Are you sure you want to delete this register? (y/N): '
                     ).upper() == 'Y':
                del self.mod.registers[int(choice)]
                self.recently_saved = False

        self.update_menu()

    def update_addresses(self):
        self.mod.update_addresses()
        print("Addresses are updated..")
        self.recently_saved = False
        self.update_menu()
        cont()

    def save_JSON(self):
        print('Saving ' + self.jsonfile + ' ...')

        # Get JSON with addresses
        json = self.mod.return_JSON(True)
        try:
            write_string_to_file(json, self.jsonfile, ".")
        except Exception as e:
            print('Saving failed...')
            print(e)
            cont()
            return

        self.recently_saved = True
        cont()
        self.update_menu()

    def set_subtitle(self):
        if self.recently_saved:
            s = ' - SAVED'
        else:
            s = ' - NOT SAVED'
        string = self.mod.name
        string += ' / ' + str(self.mod.addr_width)
        string += ' / ' + str(self.mod.data_width)
        string += ' / ' + str(hex(self.mod.baseaddr))
        string += s
        return string

    def valid_register_input(self, s):
        """ Returns boolean determining if a choice of register is valid

        The input is first checked against the quit-character, and then checked if it matches any
        valid indexes of the mod.registers list.
        """
        if s.upper() == 'Q':
            return True
        elif is_int(s):
            index = int(s)
            for i, reg in enumerate(self.mod.registers):
                if index == i:
                    return True
        return False
예제 #34
0
class TestSampleMenu(BaseTestCase):
    def setUp(self):
        super(TestSampleMenu, self).setUp()

        self.menu = CursesMenu("self.menu", "TestSampleMenu")
        self.item1 = MenuItem("self.item1", self.menu)
        self.item2 = MenuItem("self.item2", self.menu)
        self.menu.append_item(self.item1)
        self.menu.append_item(self.item2)
        self.menu.start()
        self.menu.wait_for_start(10)

    def tearDown(self):
        super(TestSampleMenu, self).tearDown()
        self.menu.exit()
        self.menu.join()

    def test_go_down(self):
        self.menu.go_down()
        self.assertEqual(self.menu.current_option, 1)
        self.assertIs(self.menu.current_item, self.item2)
        self.menu.go_down()
        self.assertEqual(self.menu.current_option, 2)
        self.assertEqual(self.menu.current_item, self.menu.exit_item)
        self.menu.go_down()
        self.assertEqual(self.menu.current_option, 0)
        self.assertIs(self.menu.current_item, self.item1)

    def test_go_up(self):
        self.menu.go_up()
        self.assertEqual(self.menu.current_option, 2)
        self.assertIs(self.menu.current_item, self.menu.exit_item)
        self.menu.go_up()
        self.assertEqual(self.menu.current_option, 1)
        self.assertEqual(self.menu.current_item, self.item2)
        self.menu.go_up()
        self.assertEqual(self.menu.current_option, 0)
        self.assertIs(self.menu.current_item, self.item1)

    def test_go_to(self):
        self.menu.go_to(1)
        self.assertEqual(self.menu.current_option, 1)
        self.assertEqual(self.menu.current_item, self.item2)

    def test_select(self):
        self.menu.select()
        self.assertEqual(self.menu.selected_option, 0)
        self.assertIs(self.menu.selected_item, self.item1)
        self.menu.go_down()
        self.menu.select()
        self.assertEqual(self.menu.selected_option, 1)
        self.assertIs(self.menu.selected_item, self.item2)
        self.menu.go_down()
        self.menu.select()
        self.assertEqual(self.menu.selected_option, 2)
        self.assertIs(self.menu.selected_item, self.menu.exit_item)
        self.menu.join(timeout=5)
        self.assertFalse(self.menu.is_alive())

    def test_exit(self):
        self.menu.exit()
        self.menu.join(timeout=5)
        self.assertFalse(self.menu.is_alive())
예제 #35
0
from cursesmenu import CursesMenu
from cursesmenu.items import *
from scriptku import menucurse

#Top Level Menu
toplv_menu = CursesMenu("Menu Raspberry Legend! - written by Pratama", "pilih satu")

#Youtube Menu
yt_menu = CursesMenu("Utility utk download youtube video", "pilih salah satu")

toplv_yt_item = SubmenuItem("Youtube Video Downloader", yt_menu, menu=toplv_menu)
yt1 = FunctionItem("Download single youtube video", menucurse.yt1)
yt_edit_links = FunctionItem("Edit list download", menucurse.yt_edit_links)
yt_bulk = FunctionItem("Bulk download youtube videos", menucurse.yt_bulk)

#Bulk rename menu
bulk_rename_item = FunctionItem("Bulk rename - WARNING(DANGEROUS TOOLS, USE AT YOUR OWN RISK)", menucurse.bulk_rename)

#Top Level Menu Append
toplv_menu.append_item(toplv_yt_item)
toplv_menu.append_item(bulk_rename_item)

#Youtube Menu Append
yt_menu.append_item(yt1)
yt_menu.append_item(yt_edit_links)
yt_menu.append_item(yt_bulk)

#Show the Top Level Menu
toplv_menu.show()
예제 #36
0
def parse_old_menu(menu_data):
    """
    Take an old-style menuData dictionary and return a CursesMenu

    :param dict menu_data:
    :return: A new CursesMenu
    :rtype: CursesMenu
    """
    menu_title = menu_data['title']
    menu = CursesMenu(menu_title)
    for item in menu_data["options"]:
        item_type = item["type"]
        item_title = item["title"]
        if item_type == menuItem.COMMAND:
            item_command = item["command"]
            menu.append_item(CommandItem(item_title, item_command, menu))
        elif item_type == menuItem.FUNCTION:
            item_function = item["function"]
            menu.append_item(FunctionItem(item_title, item_function, menu))
        elif item_type == menuItem.EXITMENU:
            menu.append_item(ExitItem(item_title, menu))
        elif item_type == menuItem.NUMBER:
            menu.append_item(SelectionItem(item_title, menu))
        elif item_type == menuItem.MENU:
            new_menu = parse_old_menu(item)
            menu.append_item(SubmenuItem(item_title, menu, new_menu))

    return menu
예제 #37
0
 def test_currently_active_menu(self):
     menu1 = CursesMenu("menu1", "test_currently_active_menu")
     menu2 = CursesMenu("menu2", "test_currently_active_menu")
     self.assertIsNone(CursesMenu.currently_active_menu)
     menu1.start()
     menu1.wait_for_start(10)
     self.assertIs(CursesMenu.currently_active_menu, menu1)
     menu2.start()
     menu2.wait_for_start(10)
     self.assertIs(CursesMenu.currently_active_menu, menu2)