hspylib-clitt 0.9.119__py3-none-any.whl → 0.9.121__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of hspylib-clitt might be problematic. Click here for more details.
- clitt/.version +1 -1
- clitt/__init__.py +3 -3
- clitt/addons/__init__.py +3 -3
- clitt/addons/appman/__init__.py +3 -3
- clitt/addons/appman/templates/__init__.py +3 -3
- clitt/addons/widman/__init__.py +3 -3
- clitt/addons/widman/widgets/__init__.py +3 -3
- clitt/core/__init__.py +3 -3
- clitt/core/exception/__init__.py +3 -3
- clitt/core/icons/__init__.py +3 -3
- clitt/core/icons/emojis/__init__.py +3 -3
- clitt/core/icons/font_awesome/__init__.py +3 -3
- clitt/core/term/__init__.py +3 -3
- clitt/core/tui/__init__.py +3 -3
- clitt/core/tui/line_input/__init__.py +3 -3
- clitt/core/tui/line_input/keyboard_input.py +85 -78
- clitt/core/tui/mchoose/__init__.py +3 -3
- clitt/core/tui/mdashboard/__init__.py +3 -3
- clitt/core/tui/menu/__init__.py +3 -3
- clitt/core/tui/minput/__init__.py +3 -3
- clitt/core/tui/minput/menu_input.py +7 -15
- clitt/core/tui/mselect/__init__.py +3 -3
- clitt/core/tui/table/__init__.py +3 -3
- clitt/utils/__init__.py +3 -3
- {hspylib_clitt-0.9.119.dist-info → hspylib_clitt-0.9.121.dist-info}/METADATA +2 -2
- hspylib_clitt-0.9.121.dist-info/RECORD +97 -0
- {hspylib_clitt-0.9.119.dist-info → hspylib_clitt-0.9.121.dist-info}/top_level.txt +0 -1
- build/lib/build/lib/build/lib/build/lib/clitt/__classpath__.py +0 -28
- build/lib/build/lib/build/lib/build/lib/clitt/__init__.py +0 -13
- build/lib/build/lib/build/lib/build/lib/clitt/__main__.py +0 -139
- build/lib/build/lib/build/lib/build/lib/clitt/addons/__init__.py +0 -12
- build/lib/build/lib/build/lib/build/lib/clitt/addons/appman/__init__.py +0 -13
- build/lib/build/lib/build/lib/build/lib/clitt/addons/appman/appman.py +0 -305
- build/lib/build/lib/build/lib/build/lib/clitt/addons/appman/appman_enums.py +0 -39
- build/lib/build/lib/build/lib/build/lib/clitt/addons/appman/templates/__init__.py +0 -11
- build/lib/build/lib/build/lib/build/lib/clitt/addons/widman/__init__.py +0 -14
- build/lib/build/lib/build/lib/build/lib/clitt/addons/widman/widget.py +0 -70
- build/lib/build/lib/build/lib/build/lib/clitt/addons/widman/widget_entry.py +0 -54
- build/lib/build/lib/build/lib/build/lib/clitt/addons/widman/widgets/__init__.py +0 -14
- build/lib/build/lib/build/lib/build/lib/clitt/addons/widman/widgets/widget_free.py +0 -110
- build/lib/build/lib/build/lib/build/lib/clitt/addons/widman/widgets/widget_punch.py +0 -246
- build/lib/build/lib/build/lib/build/lib/clitt/addons/widman/widgets/widget_send_msg.py +0 -272
- build/lib/build/lib/build/lib/build/lib/clitt/addons/widman/widgets/widget_time_calc.py +0 -146
- build/lib/build/lib/build/lib/build/lib/clitt/addons/widman/widman.py +0 -123
- build/lib/build/lib/build/lib/build/lib/clitt/core/__init__.py +0 -15
- build/lib/build/lib/build/lib/build/lib/clitt/core/exception/__init__.py +0 -11
- build/lib/build/lib/build/lib/build/lib/clitt/core/exception/exceptions.py +0 -19
- build/lib/build/lib/build/lib/build/lib/clitt/core/icons/__init__.py +0 -12
- build/lib/build/lib/build/lib/build/lib/clitt/core/icons/emojis/__init__.py +0 -12
- build/lib/build/lib/build/lib/build/lib/clitt/core/icons/emojis/emojis.py +0 -41
- build/lib/build/lib/build/lib/build/lib/clitt/core/icons/emojis/face_smiling.py +0 -40
- build/lib/build/lib/build/lib/build/lib/clitt/core/icons/font_awesome/__init__.py +0 -18
- build/lib/build/lib/build/lib/build/lib/clitt/core/icons/font_awesome/app_icons.py +0 -55
- build/lib/build/lib/build/lib/build/lib/clitt/core/icons/font_awesome/awesome.py +0 -76
- build/lib/build/lib/build/lib/build/lib/clitt/core/icons/font_awesome/dashboard_icons.py +0 -93
- build/lib/build/lib/build/lib/build/lib/clitt/core/icons/font_awesome/form_icons.py +0 -69
- build/lib/build/lib/build/lib/build/lib/clitt/core/icons/font_awesome/game_icons.py +0 -59
- build/lib/build/lib/build/lib/build/lib/clitt/core/icons/font_awesome/nav_icons.py +0 -42
- build/lib/build/lib/build/lib/build/lib/clitt/core/icons/font_awesome/trickplay_icons.py +0 -39
- build/lib/build/lib/build/lib/build/lib/clitt/core/icons/font_awesome/widget_icons.py +0 -37
- build/lib/build/lib/build/lib/build/lib/clitt/core/preferences.py +0 -87
- build/lib/build/lib/build/lib/build/lib/clitt/core/term/__init__.py +0 -14
- build/lib/build/lib/build/lib/build/lib/clitt/core/term/commons.py +0 -106
- build/lib/build/lib/build/lib/build/lib/clitt/core/term/cursor.py +0 -174
- build/lib/build/lib/build/lib/build/lib/clitt/core/term/screen.py +0 -106
- build/lib/build/lib/build/lib/build/lib/clitt/core/term/terminal.py +0 -202
- build/lib/build/lib/build/lib/build/lib/clitt/core/tui/__init__.py +0 -20
- build/lib/build/lib/build/lib/build/lib/clitt/core/tui/line_input/__init__.py +0 -12
- build/lib/build/lib/build/lib/build/lib/clitt/core/tui/line_input/keyboard_input.py +0 -229
- build/lib/build/lib/build/lib/build/lib/clitt/core/tui/line_input/line_input.py +0 -31
- build/lib/build/lib/build/lib/build/lib/clitt/core/tui/mchoose/__init__.py +0 -12
- build/lib/build/lib/build/lib/build/lib/clitt/core/tui/mchoose/mchoose.py +0 -43
- build/lib/build/lib/build/lib/build/lib/clitt/core/tui/mchoose/menu_choose.py +0 -192
- build/lib/build/lib/build/lib/build/lib/clitt/core/tui/mdashboard/__init__.py +0 -14
- build/lib/build/lib/build/lib/build/lib/clitt/core/tui/mdashboard/dashboard_builder.py +0 -54
- build/lib/build/lib/build/lib/build/lib/clitt/core/tui/mdashboard/dashboard_item.py +0 -31
- build/lib/build/lib/build/lib/build/lib/clitt/core/tui/mdashboard/mdashboard.py +0 -26
- build/lib/build/lib/build/lib/build/lib/clitt/core/tui/mdashboard/menu_dashboard.py +0 -148
- build/lib/build/lib/build/lib/build/lib/clitt/core/tui/menu/__init__.py +0 -16
- build/lib/build/lib/build/lib/build/lib/clitt/core/tui/menu/tui_menu.py +0 -111
- build/lib/build/lib/build/lib/build/lib/clitt/core/tui/menu/tui_menu_action.py +0 -47
- build/lib/build/lib/build/lib/build/lib/clitt/core/tui/menu/tui_menu_factory.py +0 -117
- build/lib/build/lib/build/lib/build/lib/clitt/core/tui/menu/tui_menu_item.py +0 -196
- build/lib/build/lib/build/lib/build/lib/clitt/core/tui/menu/tui_menu_ui.py +0 -98
- build/lib/build/lib/build/lib/build/lib/clitt/core/tui/menu/tui_menu_view.py +0 -57
- build/lib/build/lib/build/lib/build/lib/clitt/core/tui/minput/__init__.py +0 -19
- build/lib/build/lib/build/lib/build/lib/clitt/core/tui/minput/access_type.py +0 -26
- build/lib/build/lib/build/lib/build/lib/clitt/core/tui/minput/field_builder.py +0 -117
- build/lib/build/lib/build/lib/build/lib/clitt/core/tui/minput/form_builder.py +0 -72
- build/lib/build/lib/build/lib/build/lib/clitt/core/tui/minput/form_field.py +0 -180
- build/lib/build/lib/build/lib/build/lib/clitt/core/tui/minput/input_type.py +0 -30
- build/lib/build/lib/build/lib/build/lib/clitt/core/tui/minput/input_validator.py +0 -98
- build/lib/build/lib/build/lib/build/lib/clitt/core/tui/minput/menu_input.py +0 -292
- build/lib/build/lib/build/lib/build/lib/clitt/core/tui/minput/minput.py +0 -44
- build/lib/build/lib/build/lib/build/lib/clitt/core/tui/minput/minput_utils.py +0 -156
- build/lib/build/lib/build/lib/build/lib/clitt/core/tui/mselect/__init__.py +0 -12
- build/lib/build/lib/build/lib/build/lib/clitt/core/tui/mselect/menu_select.py +0 -170
- build/lib/build/lib/build/lib/build/lib/clitt/core/tui/mselect/mselect.py +0 -36
- build/lib/build/lib/build/lib/build/lib/clitt/core/tui/table/__init__.py +0 -12
- build/lib/build/lib/build/lib/build/lib/clitt/core/tui/table/table_enums.py +0 -47
- build/lib/build/lib/build/lib/build/lib/clitt/core/tui/table/table_renderer.py +0 -339
- build/lib/build/lib/build/lib/build/lib/clitt/core/tui/tui_application.py +0 -52
- build/lib/build/lib/build/lib/build/lib/clitt/core/tui/tui_component.py +0 -154
- build/lib/build/lib/build/lib/build/lib/clitt/core/tui/tui_preferences.py +0 -103
- build/lib/build/lib/build/lib/build/lib/clitt/utils/__init__.py +0 -11
- build/lib/build/lib/build/lib/build/lib/clitt/utils/git_utils.py +0 -66
- build/lib/build/lib/build/lib/clitt/__classpath__.py +0 -28
- build/lib/build/lib/build/lib/clitt/__init__.py +0 -13
- build/lib/build/lib/build/lib/clitt/__main__.py +0 -139
- build/lib/build/lib/build/lib/clitt/addons/__init__.py +0 -12
- build/lib/build/lib/build/lib/clitt/addons/appman/__init__.py +0 -13
- build/lib/build/lib/build/lib/clitt/addons/appman/appman.py +0 -305
- build/lib/build/lib/build/lib/clitt/addons/appman/appman_enums.py +0 -39
- build/lib/build/lib/build/lib/clitt/addons/appman/templates/__init__.py +0 -11
- build/lib/build/lib/build/lib/clitt/addons/widman/__init__.py +0 -14
- build/lib/build/lib/build/lib/clitt/addons/widman/widget.py +0 -70
- build/lib/build/lib/build/lib/clitt/addons/widman/widget_entry.py +0 -54
- build/lib/build/lib/build/lib/clitt/addons/widman/widgets/__init__.py +0 -14
- build/lib/build/lib/build/lib/clitt/addons/widman/widgets/widget_free.py +0 -110
- build/lib/build/lib/build/lib/clitt/addons/widman/widgets/widget_punch.py +0 -246
- build/lib/build/lib/build/lib/clitt/addons/widman/widgets/widget_send_msg.py +0 -272
- build/lib/build/lib/build/lib/clitt/addons/widman/widgets/widget_time_calc.py +0 -146
- build/lib/build/lib/build/lib/clitt/addons/widman/widman.py +0 -123
- build/lib/build/lib/build/lib/clitt/core/__init__.py +0 -15
- build/lib/build/lib/build/lib/clitt/core/exception/__init__.py +0 -11
- build/lib/build/lib/build/lib/clitt/core/exception/exceptions.py +0 -19
- build/lib/build/lib/build/lib/clitt/core/icons/__init__.py +0 -12
- build/lib/build/lib/build/lib/clitt/core/icons/emojis/__init__.py +0 -12
- build/lib/build/lib/build/lib/clitt/core/icons/emojis/emojis.py +0 -41
- build/lib/build/lib/build/lib/clitt/core/icons/emojis/face_smiling.py +0 -40
- build/lib/build/lib/build/lib/clitt/core/icons/font_awesome/__init__.py +0 -18
- build/lib/build/lib/build/lib/clitt/core/icons/font_awesome/app_icons.py +0 -55
- build/lib/build/lib/build/lib/clitt/core/icons/font_awesome/awesome.py +0 -76
- build/lib/build/lib/build/lib/clitt/core/icons/font_awesome/dashboard_icons.py +0 -93
- build/lib/build/lib/build/lib/clitt/core/icons/font_awesome/form_icons.py +0 -69
- build/lib/build/lib/build/lib/clitt/core/icons/font_awesome/game_icons.py +0 -59
- build/lib/build/lib/build/lib/clitt/core/icons/font_awesome/nav_icons.py +0 -42
- build/lib/build/lib/build/lib/clitt/core/icons/font_awesome/trickplay_icons.py +0 -39
- build/lib/build/lib/build/lib/clitt/core/icons/font_awesome/widget_icons.py +0 -37
- build/lib/build/lib/build/lib/clitt/core/preferences.py +0 -87
- build/lib/build/lib/build/lib/clitt/core/term/__init__.py +0 -14
- build/lib/build/lib/build/lib/clitt/core/term/commons.py +0 -106
- build/lib/build/lib/build/lib/clitt/core/term/cursor.py +0 -174
- build/lib/build/lib/build/lib/clitt/core/term/screen.py +0 -106
- build/lib/build/lib/build/lib/clitt/core/term/terminal.py +0 -202
- build/lib/build/lib/build/lib/clitt/core/tui/__init__.py +0 -20
- build/lib/build/lib/build/lib/clitt/core/tui/line_input/__init__.py +0 -12
- build/lib/build/lib/build/lib/clitt/core/tui/line_input/keyboard_input.py +0 -229
- build/lib/build/lib/build/lib/clitt/core/tui/line_input/line_input.py +0 -31
- build/lib/build/lib/build/lib/clitt/core/tui/mchoose/__init__.py +0 -12
- build/lib/build/lib/build/lib/clitt/core/tui/mchoose/mchoose.py +0 -43
- build/lib/build/lib/build/lib/clitt/core/tui/mchoose/menu_choose.py +0 -192
- build/lib/build/lib/build/lib/clitt/core/tui/mdashboard/__init__.py +0 -14
- build/lib/build/lib/build/lib/clitt/core/tui/mdashboard/dashboard_builder.py +0 -54
- build/lib/build/lib/build/lib/clitt/core/tui/mdashboard/dashboard_item.py +0 -31
- build/lib/build/lib/build/lib/clitt/core/tui/mdashboard/mdashboard.py +0 -26
- build/lib/build/lib/build/lib/clitt/core/tui/mdashboard/menu_dashboard.py +0 -148
- build/lib/build/lib/build/lib/clitt/core/tui/menu/__init__.py +0 -16
- build/lib/build/lib/build/lib/clitt/core/tui/menu/tui_menu.py +0 -111
- build/lib/build/lib/build/lib/clitt/core/tui/menu/tui_menu_action.py +0 -47
- build/lib/build/lib/build/lib/clitt/core/tui/menu/tui_menu_factory.py +0 -117
- build/lib/build/lib/build/lib/clitt/core/tui/menu/tui_menu_item.py +0 -196
- build/lib/build/lib/build/lib/clitt/core/tui/menu/tui_menu_ui.py +0 -98
- build/lib/build/lib/build/lib/clitt/core/tui/menu/tui_menu_view.py +0 -57
- build/lib/build/lib/build/lib/clitt/core/tui/minput/__init__.py +0 -19
- build/lib/build/lib/build/lib/clitt/core/tui/minput/access_type.py +0 -26
- build/lib/build/lib/build/lib/clitt/core/tui/minput/field_builder.py +0 -117
- build/lib/build/lib/build/lib/clitt/core/tui/minput/form_builder.py +0 -72
- build/lib/build/lib/build/lib/clitt/core/tui/minput/form_field.py +0 -180
- build/lib/build/lib/build/lib/clitt/core/tui/minput/input_type.py +0 -30
- build/lib/build/lib/build/lib/clitt/core/tui/minput/input_validator.py +0 -98
- build/lib/build/lib/build/lib/clitt/core/tui/minput/menu_input.py +0 -292
- build/lib/build/lib/build/lib/clitt/core/tui/minput/minput.py +0 -44
- build/lib/build/lib/build/lib/clitt/core/tui/minput/minput_utils.py +0 -156
- build/lib/build/lib/build/lib/clitt/core/tui/mselect/__init__.py +0 -12
- build/lib/build/lib/build/lib/clitt/core/tui/mselect/menu_select.py +0 -170
- build/lib/build/lib/build/lib/clitt/core/tui/mselect/mselect.py +0 -36
- build/lib/build/lib/build/lib/clitt/core/tui/table/__init__.py +0 -12
- build/lib/build/lib/build/lib/clitt/core/tui/table/table_enums.py +0 -47
- build/lib/build/lib/build/lib/clitt/core/tui/table/table_renderer.py +0 -339
- build/lib/build/lib/build/lib/clitt/core/tui/tui_application.py +0 -52
- build/lib/build/lib/build/lib/clitt/core/tui/tui_component.py +0 -154
- build/lib/build/lib/build/lib/clitt/core/tui/tui_preferences.py +0 -103
- build/lib/build/lib/build/lib/clitt/utils/__init__.py +0 -11
- build/lib/build/lib/build/lib/clitt/utils/git_utils.py +0 -66
- build/lib/build/lib/clitt/__classpath__.py +0 -28
- build/lib/build/lib/clitt/__init__.py +0 -13
- build/lib/build/lib/clitt/__main__.py +0 -139
- build/lib/build/lib/clitt/addons/__init__.py +0 -12
- build/lib/build/lib/clitt/addons/appman/__init__.py +0 -13
- build/lib/build/lib/clitt/addons/appman/appman.py +0 -305
- build/lib/build/lib/clitt/addons/appman/appman_enums.py +0 -39
- build/lib/build/lib/clitt/addons/appman/templates/__init__.py +0 -11
- build/lib/build/lib/clitt/addons/widman/__init__.py +0 -14
- build/lib/build/lib/clitt/addons/widman/widget.py +0 -70
- build/lib/build/lib/clitt/addons/widman/widget_entry.py +0 -54
- build/lib/build/lib/clitt/addons/widman/widgets/__init__.py +0 -14
- build/lib/build/lib/clitt/addons/widman/widgets/widget_free.py +0 -110
- build/lib/build/lib/clitt/addons/widman/widgets/widget_punch.py +0 -246
- build/lib/build/lib/clitt/addons/widman/widgets/widget_send_msg.py +0 -272
- build/lib/build/lib/clitt/addons/widman/widgets/widget_time_calc.py +0 -146
- build/lib/build/lib/clitt/addons/widman/widman.py +0 -123
- build/lib/build/lib/clitt/core/__init__.py +0 -15
- build/lib/build/lib/clitt/core/exception/__init__.py +0 -11
- build/lib/build/lib/clitt/core/exception/exceptions.py +0 -19
- build/lib/build/lib/clitt/core/icons/__init__.py +0 -12
- build/lib/build/lib/clitt/core/icons/emojis/__init__.py +0 -12
- build/lib/build/lib/clitt/core/icons/emojis/emojis.py +0 -41
- build/lib/build/lib/clitt/core/icons/emojis/face_smiling.py +0 -40
- build/lib/build/lib/clitt/core/icons/font_awesome/__init__.py +0 -18
- build/lib/build/lib/clitt/core/icons/font_awesome/app_icons.py +0 -55
- build/lib/build/lib/clitt/core/icons/font_awesome/awesome.py +0 -76
- build/lib/build/lib/clitt/core/icons/font_awesome/dashboard_icons.py +0 -93
- build/lib/build/lib/clitt/core/icons/font_awesome/form_icons.py +0 -69
- build/lib/build/lib/clitt/core/icons/font_awesome/game_icons.py +0 -59
- build/lib/build/lib/clitt/core/icons/font_awesome/nav_icons.py +0 -42
- build/lib/build/lib/clitt/core/icons/font_awesome/trickplay_icons.py +0 -39
- build/lib/build/lib/clitt/core/icons/font_awesome/widget_icons.py +0 -37
- build/lib/build/lib/clitt/core/preferences.py +0 -87
- build/lib/build/lib/clitt/core/term/__init__.py +0 -14
- build/lib/build/lib/clitt/core/term/commons.py +0 -106
- build/lib/build/lib/clitt/core/term/cursor.py +0 -174
- build/lib/build/lib/clitt/core/term/screen.py +0 -106
- build/lib/build/lib/clitt/core/term/terminal.py +0 -202
- build/lib/build/lib/clitt/core/tui/__init__.py +0 -20
- build/lib/build/lib/clitt/core/tui/line_input/__init__.py +0 -12
- build/lib/build/lib/clitt/core/tui/line_input/keyboard_input.py +0 -229
- build/lib/build/lib/clitt/core/tui/line_input/line_input.py +0 -31
- build/lib/build/lib/clitt/core/tui/mchoose/__init__.py +0 -12
- build/lib/build/lib/clitt/core/tui/mchoose/mchoose.py +0 -43
- build/lib/build/lib/clitt/core/tui/mchoose/menu_choose.py +0 -192
- build/lib/build/lib/clitt/core/tui/mdashboard/__init__.py +0 -14
- build/lib/build/lib/clitt/core/tui/mdashboard/dashboard_builder.py +0 -54
- build/lib/build/lib/clitt/core/tui/mdashboard/dashboard_item.py +0 -31
- build/lib/build/lib/clitt/core/tui/mdashboard/mdashboard.py +0 -26
- build/lib/build/lib/clitt/core/tui/mdashboard/menu_dashboard.py +0 -148
- build/lib/build/lib/clitt/core/tui/menu/__init__.py +0 -16
- build/lib/build/lib/clitt/core/tui/menu/tui_menu.py +0 -111
- build/lib/build/lib/clitt/core/tui/menu/tui_menu_action.py +0 -47
- build/lib/build/lib/clitt/core/tui/menu/tui_menu_factory.py +0 -117
- build/lib/build/lib/clitt/core/tui/menu/tui_menu_item.py +0 -196
- build/lib/build/lib/clitt/core/tui/menu/tui_menu_ui.py +0 -98
- build/lib/build/lib/clitt/core/tui/menu/tui_menu_view.py +0 -57
- build/lib/build/lib/clitt/core/tui/minput/__init__.py +0 -19
- build/lib/build/lib/clitt/core/tui/minput/access_type.py +0 -26
- build/lib/build/lib/clitt/core/tui/minput/field_builder.py +0 -117
- build/lib/build/lib/clitt/core/tui/minput/form_builder.py +0 -72
- build/lib/build/lib/clitt/core/tui/minput/form_field.py +0 -180
- build/lib/build/lib/clitt/core/tui/minput/input_type.py +0 -30
- build/lib/build/lib/clitt/core/tui/minput/input_validator.py +0 -98
- build/lib/build/lib/clitt/core/tui/minput/menu_input.py +0 -292
- build/lib/build/lib/clitt/core/tui/minput/minput.py +0 -44
- build/lib/build/lib/clitt/core/tui/minput/minput_utils.py +0 -156
- build/lib/build/lib/clitt/core/tui/mselect/__init__.py +0 -12
- build/lib/build/lib/clitt/core/tui/mselect/menu_select.py +0 -170
- build/lib/build/lib/clitt/core/tui/mselect/mselect.py +0 -36
- build/lib/build/lib/clitt/core/tui/table/__init__.py +0 -12
- build/lib/build/lib/clitt/core/tui/table/table_enums.py +0 -47
- build/lib/build/lib/clitt/core/tui/table/table_renderer.py +0 -339
- build/lib/build/lib/clitt/core/tui/tui_application.py +0 -52
- build/lib/build/lib/clitt/core/tui/tui_component.py +0 -154
- build/lib/build/lib/clitt/core/tui/tui_preferences.py +0 -103
- build/lib/build/lib/clitt/utils/__init__.py +0 -11
- build/lib/build/lib/clitt/utils/git_utils.py +0 -66
- build/lib/clitt/__classpath__.py +0 -28
- build/lib/clitt/__init__.py +0 -13
- build/lib/clitt/__main__.py +0 -139
- build/lib/clitt/addons/__init__.py +0 -12
- build/lib/clitt/addons/appman/__init__.py +0 -13
- build/lib/clitt/addons/appman/appman.py +0 -305
- build/lib/clitt/addons/appman/appman_enums.py +0 -39
- build/lib/clitt/addons/appman/templates/__init__.py +0 -11
- build/lib/clitt/addons/widman/__init__.py +0 -14
- build/lib/clitt/addons/widman/widget.py +0 -70
- build/lib/clitt/addons/widman/widget_entry.py +0 -54
- build/lib/clitt/addons/widman/widgets/__init__.py +0 -14
- build/lib/clitt/addons/widman/widgets/widget_free.py +0 -110
- build/lib/clitt/addons/widman/widgets/widget_punch.py +0 -246
- build/lib/clitt/addons/widman/widgets/widget_send_msg.py +0 -272
- build/lib/clitt/addons/widman/widgets/widget_time_calc.py +0 -146
- build/lib/clitt/addons/widman/widman.py +0 -123
- build/lib/clitt/core/__init__.py +0 -15
- build/lib/clitt/core/exception/__init__.py +0 -11
- build/lib/clitt/core/exception/exceptions.py +0 -19
- build/lib/clitt/core/icons/__init__.py +0 -12
- build/lib/clitt/core/icons/emojis/__init__.py +0 -12
- build/lib/clitt/core/icons/emojis/emojis.py +0 -41
- build/lib/clitt/core/icons/emojis/face_smiling.py +0 -40
- build/lib/clitt/core/icons/font_awesome/__init__.py +0 -18
- build/lib/clitt/core/icons/font_awesome/app_icons.py +0 -55
- build/lib/clitt/core/icons/font_awesome/awesome.py +0 -76
- build/lib/clitt/core/icons/font_awesome/dashboard_icons.py +0 -93
- build/lib/clitt/core/icons/font_awesome/form_icons.py +0 -69
- build/lib/clitt/core/icons/font_awesome/game_icons.py +0 -59
- build/lib/clitt/core/icons/font_awesome/nav_icons.py +0 -42
- build/lib/clitt/core/icons/font_awesome/trickplay_icons.py +0 -39
- build/lib/clitt/core/icons/font_awesome/widget_icons.py +0 -37
- build/lib/clitt/core/preferences.py +0 -87
- build/lib/clitt/core/term/__init__.py +0 -14
- build/lib/clitt/core/term/commons.py +0 -106
- build/lib/clitt/core/term/cursor.py +0 -174
- build/lib/clitt/core/term/screen.py +0 -106
- build/lib/clitt/core/term/terminal.py +0 -202
- build/lib/clitt/core/tui/__init__.py +0 -20
- build/lib/clitt/core/tui/line_input/__init__.py +0 -12
- build/lib/clitt/core/tui/line_input/keyboard_input.py +0 -229
- build/lib/clitt/core/tui/line_input/line_input.py +0 -31
- build/lib/clitt/core/tui/mchoose/__init__.py +0 -12
- build/lib/clitt/core/tui/mchoose/mchoose.py +0 -43
- build/lib/clitt/core/tui/mchoose/menu_choose.py +0 -192
- build/lib/clitt/core/tui/mdashboard/__init__.py +0 -14
- build/lib/clitt/core/tui/mdashboard/dashboard_builder.py +0 -54
- build/lib/clitt/core/tui/mdashboard/dashboard_item.py +0 -31
- build/lib/clitt/core/tui/mdashboard/mdashboard.py +0 -26
- build/lib/clitt/core/tui/mdashboard/menu_dashboard.py +0 -148
- build/lib/clitt/core/tui/menu/__init__.py +0 -16
- build/lib/clitt/core/tui/menu/tui_menu.py +0 -111
- build/lib/clitt/core/tui/menu/tui_menu_action.py +0 -47
- build/lib/clitt/core/tui/menu/tui_menu_factory.py +0 -117
- build/lib/clitt/core/tui/menu/tui_menu_item.py +0 -196
- build/lib/clitt/core/tui/menu/tui_menu_ui.py +0 -98
- build/lib/clitt/core/tui/menu/tui_menu_view.py +0 -57
- build/lib/clitt/core/tui/minput/__init__.py +0 -19
- build/lib/clitt/core/tui/minput/access_type.py +0 -26
- build/lib/clitt/core/tui/minput/field_builder.py +0 -117
- build/lib/clitt/core/tui/minput/form_builder.py +0 -72
- build/lib/clitt/core/tui/minput/form_field.py +0 -180
- build/lib/clitt/core/tui/minput/input_type.py +0 -30
- build/lib/clitt/core/tui/minput/input_validator.py +0 -98
- build/lib/clitt/core/tui/minput/menu_input.py +0 -292
- build/lib/clitt/core/tui/minput/minput.py +0 -44
- build/lib/clitt/core/tui/minput/minput_utils.py +0 -156
- build/lib/clitt/core/tui/mselect/__init__.py +0 -12
- build/lib/clitt/core/tui/mselect/menu_select.py +0 -170
- build/lib/clitt/core/tui/mselect/mselect.py +0 -36
- build/lib/clitt/core/tui/table/__init__.py +0 -12
- build/lib/clitt/core/tui/table/table_enums.py +0 -47
- build/lib/clitt/core/tui/table/table_renderer.py +0 -339
- build/lib/clitt/core/tui/tui_application.py +0 -52
- build/lib/clitt/core/tui/tui_component.py +0 -154
- build/lib/clitt/core/tui/tui_preferences.py +0 -103
- build/lib/clitt/utils/__init__.py +0 -11
- build/lib/clitt/utils/git_utils.py +0 -66
- hspylib_clitt-0.9.119.dist-info/RECORD +0 -413
- {hspylib_clitt-0.9.119.dist-info → hspylib_clitt-0.9.121.dist-info}/WHEEL +0 -0
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
# -*- coding: utf-8 -*-
|
|
3
|
-
|
|
4
|
-
"""
|
|
5
|
-
@project: HsPyLib
|
|
6
|
-
@package: clitt.core.tui.minput
|
|
7
|
-
@file: form_builder.py
|
|
8
|
-
@created: Thu, 20 May 2021
|
|
9
|
-
@author: <B>H</B>ugo <B>S</B>aporetti <B>J</B>unior"
|
|
10
|
-
@site: https://github.com/yorevs/hspylib
|
|
11
|
-
@license: MIT - Please refer to <https://opensource.org/licenses/MIT>
|
|
12
|
-
|
|
13
|
-
Copyright·(c)·2024,·HSPyLib
|
|
14
|
-
"""
|
|
15
|
-
from clitt.core.tui.minput.field_builder import FieldBuilder
|
|
16
|
-
from clitt.core.tui.minput.form_field import FormField
|
|
17
|
-
from clitt.core.tui.minput.input_validator import InputValidator
|
|
18
|
-
from hspylib.core.tools.dict_tools import get_or_default
|
|
19
|
-
from typing import Any, List
|
|
20
|
-
|
|
21
|
-
import re
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
class FormBuilder:
|
|
25
|
-
"""MenuInput form builder."""
|
|
26
|
-
|
|
27
|
-
def __init__(self) -> None:
|
|
28
|
-
self.fields = []
|
|
29
|
-
self._fn_validate = None
|
|
30
|
-
|
|
31
|
-
@staticmethod
|
|
32
|
-
def get_attr(parts: List[str], index: int, default_value: Any = None) -> str:
|
|
33
|
-
return get_or_default(parts, index, default_value) or default_value
|
|
34
|
-
|
|
35
|
-
def from_tokenized(self, minput_tokens: List[str], separator: chr = "|") -> "FormBuilder":
|
|
36
|
-
"""Construct the forms based on string tokens.
|
|
37
|
-
|
|
38
|
-
Field tokens (in-order):
|
|
39
|
-
<Label> : The field label. Consisting only of alphanumeric characters and under‐scores.
|
|
40
|
-
[Mode] : The input mode. One of {[text]|password|checkbox|select}.
|
|
41
|
-
[Type] : The input type. One of {letters|numbers|words|[anything]}.
|
|
42
|
-
[Min/Max len] : The minimum and maximum length of characters allowed. Defaults to [0/30].
|
|
43
|
-
[Perm] : The field permissions. One of {r|[rw]}. Where \"r\" for Read Only ; \"rw\" for Read & Write.
|
|
44
|
-
[Value] : The initial value of the field. This field may not be blank if the field is read only.
|
|
45
|
-
"""
|
|
46
|
-
for tk_field in minput_tokens:
|
|
47
|
-
parts = list(map(str.strip, tk_field.split(separator)))
|
|
48
|
-
validator_fn = getattr(InputValidator, self.get_attr(parts, 2, "anything"))
|
|
49
|
-
min_max = list(map(int, map(str.strip, self.get_attr(parts, 3, "5/30").split("/"))))
|
|
50
|
-
access = re.sub("^rw$", "read-write", self.get_attr(parts, 4, "rw"))
|
|
51
|
-
access = re.sub("^r$", "read-only", access)
|
|
52
|
-
# fmt: off
|
|
53
|
-
self.field() \
|
|
54
|
-
.label(self.get_attr(parts, 0, 'Label')) \
|
|
55
|
-
.itype(self.get_attr(parts, 1, 'text')) \
|
|
56
|
-
.min_max_length(
|
|
57
|
-
get_or_default(min_max, 0, 5),
|
|
58
|
-
get_or_default(min_max, 1, 30)
|
|
59
|
-
) \
|
|
60
|
-
.access_type(access) \
|
|
61
|
-
.validator(validator_fn()) \
|
|
62
|
-
.value(self.get_attr(parts, 5, None)) \
|
|
63
|
-
.build()
|
|
64
|
-
# fmt: on
|
|
65
|
-
|
|
66
|
-
return self
|
|
67
|
-
|
|
68
|
-
def field(self) -> Any:
|
|
69
|
-
return FieldBuilder(self)
|
|
70
|
-
|
|
71
|
-
def build(self) -> List[FormField]:
|
|
72
|
-
return self.fields
|
|
@@ -1,180 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
# -*- coding: utf-8 -*-
|
|
3
|
-
|
|
4
|
-
"""
|
|
5
|
-
@project: HsPyLib
|
|
6
|
-
@package: clitt.core.tui.minput
|
|
7
|
-
@file: form_field.py
|
|
8
|
-
@created: Thu, 20 May 2021
|
|
9
|
-
@author: <B>H</B>ugo <B>S</B>aporetti <B>J</B>unior"
|
|
10
|
-
@site: https://github.com/yorevs/hspylib
|
|
11
|
-
@license: MIT - Please refer to <https://opensource.org/licenses/MIT>
|
|
12
|
-
|
|
13
|
-
Copyright·(c)·2024,·HSPyLib
|
|
14
|
-
"""
|
|
15
|
-
from clitt.core.icons.font_awesome.form_icons import FormIcons
|
|
16
|
-
from clitt.core.tui.minput.access_type import AccessType
|
|
17
|
-
from clitt.core.tui.minput.input_type import InputType
|
|
18
|
-
from clitt.core.tui.minput.input_validator import InputValidator
|
|
19
|
-
from clitt.core.tui.minput.minput_utils import get_selected, MASK_SYMBOLS, toggle_selected, unpack_masked
|
|
20
|
-
from hspylib.core.exception.exceptions import InvalidInputError
|
|
21
|
-
from hspylib.core.tools.text_tools import xstr
|
|
22
|
-
from typing import Any, Callable, Optional, TypeAlias
|
|
23
|
-
|
|
24
|
-
FieldValidator_Fn: TypeAlias = Callable[["FormField"], bool]
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
class FormField:
|
|
28
|
-
"""Represent a MenuInput form field."""
|
|
29
|
-
|
|
30
|
-
def __init__(
|
|
31
|
-
self,
|
|
32
|
-
label: str = None,
|
|
33
|
-
dest: str = None,
|
|
34
|
-
itype: InputType = InputType.TEXT,
|
|
35
|
-
min_length: int = 5,
|
|
36
|
-
max_length: int = 30,
|
|
37
|
-
access_type: AccessType = AccessType.READ_WRITE,
|
|
38
|
-
value: Any = "",
|
|
39
|
-
input_validator: InputValidator = InputValidator.anything(),
|
|
40
|
-
field_validator: FieldValidator_Fn = None,
|
|
41
|
-
tooltip: str = None,
|
|
42
|
-
):
|
|
43
|
-
self._label = label
|
|
44
|
-
self._tooltip = tooltip
|
|
45
|
-
self._dest = dest
|
|
46
|
-
self._itype = itype
|
|
47
|
-
self._min_length = min_length
|
|
48
|
-
self._max_length = max_length
|
|
49
|
-
self._access_type = access_type
|
|
50
|
-
self.input_validator = input_validator
|
|
51
|
-
self.field_validator = field_validator
|
|
52
|
-
self._value = self.assign(value)
|
|
53
|
-
|
|
54
|
-
def __str__(self) -> str:
|
|
55
|
-
return (
|
|
56
|
-
f"[{self.label}, {self.itype.name}({self.min_length}/{self.max_length})"
|
|
57
|
-
f"<{self.access_type}> = '{self.value or ''}']"
|
|
58
|
-
)
|
|
59
|
-
|
|
60
|
-
def __repr__(self):
|
|
61
|
-
return str(self)
|
|
62
|
-
|
|
63
|
-
@property
|
|
64
|
-
def label(self) -> str:
|
|
65
|
-
return self._label
|
|
66
|
-
|
|
67
|
-
@property
|
|
68
|
-
def tooltip(self) -> str:
|
|
69
|
-
return self._tooltip
|
|
70
|
-
|
|
71
|
-
@property
|
|
72
|
-
def dest(self) -> str:
|
|
73
|
-
return self._dest
|
|
74
|
-
|
|
75
|
-
@property
|
|
76
|
-
def itype(self) -> InputType:
|
|
77
|
-
return self._itype
|
|
78
|
-
|
|
79
|
-
@property
|
|
80
|
-
def min_length(self) -> int:
|
|
81
|
-
return self._min_length
|
|
82
|
-
|
|
83
|
-
@property
|
|
84
|
-
def max_length(self) -> int:
|
|
85
|
-
return self._max_length
|
|
86
|
-
|
|
87
|
-
@property
|
|
88
|
-
def access_type(self) -> AccessType:
|
|
89
|
-
return self._access_type
|
|
90
|
-
|
|
91
|
-
@property
|
|
92
|
-
def value(self) -> Optional[Any]:
|
|
93
|
-
return self._value
|
|
94
|
-
|
|
95
|
-
@value.setter
|
|
96
|
-
def value(self, new_value: Any) -> None:
|
|
97
|
-
self._value = self.assign(new_value)
|
|
98
|
-
|
|
99
|
-
@property
|
|
100
|
-
def length(self) -> int:
|
|
101
|
-
"""Get the field real length, depending on the field type."""
|
|
102
|
-
real_value = str(self.value or "")
|
|
103
|
-
match self.itype:
|
|
104
|
-
case InputType.CHECKBOX:
|
|
105
|
-
real_value = "1"
|
|
106
|
-
case InputType.SELECT:
|
|
107
|
-
_, real_value = get_selected(str(self.value))
|
|
108
|
-
case InputType.MASKED:
|
|
109
|
-
real_value, mask = unpack_masked(str(self.value))
|
|
110
|
-
idx = len(real_value)
|
|
111
|
-
while idx < len(mask) and mask[idx] not in MASK_SYMBOLS:
|
|
112
|
-
idx += 1
|
|
113
|
-
return idx
|
|
114
|
-
|
|
115
|
-
return len(real_value)
|
|
116
|
-
|
|
117
|
-
@property
|
|
118
|
-
def icon(self) -> FormIcons:
|
|
119
|
-
if self.access_type == AccessType.READ_ONLY:
|
|
120
|
-
return FormIcons.LOCKED
|
|
121
|
-
match self.itype:
|
|
122
|
-
case InputType.PASSWORD:
|
|
123
|
-
icon = FormIcons.HIDDEN
|
|
124
|
-
case InputType.CHECKBOX:
|
|
125
|
-
icon = FormIcons.MARKED
|
|
126
|
-
case InputType.SELECT:
|
|
127
|
-
icon = FormIcons.SELECTABLE
|
|
128
|
-
case InputType.MASKED:
|
|
129
|
-
icon = FormIcons.MASKED
|
|
130
|
-
case InputType.TEXT:
|
|
131
|
-
if self.input_validator.pattern_type == InputValidator.PatternType.NUMBERS:
|
|
132
|
-
icon = FormIcons.NUMBERS
|
|
133
|
-
elif self.input_validator.pattern_type == InputValidator.PatternType.LETTERS:
|
|
134
|
-
icon = FormIcons.LETTERS
|
|
135
|
-
elif self.input_validator.pattern_type == InputValidator.PatternType.WORDS:
|
|
136
|
-
icon = FormIcons.WORDS
|
|
137
|
-
elif self.input_validator.pattern_type == InputValidator.PatternType.CUSTOM:
|
|
138
|
-
icon = FormIcons.CUSTOM
|
|
139
|
-
else:
|
|
140
|
-
icon = FormIcons.EDITABLE
|
|
141
|
-
case _:
|
|
142
|
-
icon = FormIcons.QUESTION_CIRCLE
|
|
143
|
-
return icon
|
|
144
|
-
|
|
145
|
-
def can_write(self) -> bool:
|
|
146
|
-
"""Whether this field value can be set or not."""
|
|
147
|
-
return self.access_type == AccessType.READ_WRITE
|
|
148
|
-
|
|
149
|
-
def assign(self, value: Any) -> Any:
|
|
150
|
-
"""Assign a value for this field. Must match the input validator, otherwise an exception will be thrown.
|
|
151
|
-
:param value: TODO
|
|
152
|
-
"""
|
|
153
|
-
valid = True
|
|
154
|
-
if value is not None and self.input_validator:
|
|
155
|
-
match self.itype:
|
|
156
|
-
case InputType.MASKED:
|
|
157
|
-
unpack_masked(value)
|
|
158
|
-
case InputType.SELECT:
|
|
159
|
-
toggle_selected(value)
|
|
160
|
-
case InputType.CHECKBOX:
|
|
161
|
-
valid = isinstance(value, bool)
|
|
162
|
-
case _:
|
|
163
|
-
valid = all(self.validate_input(val) for val in xstr(value))
|
|
164
|
-
|
|
165
|
-
if not valid:
|
|
166
|
-
raise InvalidInputError(f"Value {value} is invalid!")
|
|
167
|
-
|
|
168
|
-
self._value = value
|
|
169
|
-
|
|
170
|
-
return self._value
|
|
171
|
-
|
|
172
|
-
def validate_input(self, value: Any = None) -> bool:
|
|
173
|
-
"""Validate the input using the assigned validator.
|
|
174
|
-
:param value: the value to validate against.
|
|
175
|
-
"""
|
|
176
|
-
return self.input_validator(str(value)) if self.input_validator else True
|
|
177
|
-
|
|
178
|
-
def validate_field(self) -> bool:
|
|
179
|
-
"""Validate the field using the assigned validator function."""
|
|
180
|
-
return self.field_validator(self) if self.field_validator else False
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
# -*- coding: utf-8 -*-
|
|
3
|
-
|
|
4
|
-
"""
|
|
5
|
-
@project: HsPyLib
|
|
6
|
-
@package: clitt.core.tui.minput
|
|
7
|
-
@file: input_type.py
|
|
8
|
-
@created: Thu, 20 May 2021
|
|
9
|
-
@author: <B>H</B>ugo <B>S</B>aporetti <B>J</B>unior"
|
|
10
|
-
@site: https://github.com/yorevs/hspylib
|
|
11
|
-
@license: MIT - Please refer to <https://opensource.org/licenses/MIT>
|
|
12
|
-
|
|
13
|
-
Copyright·(c)·2024,·HSPyLib
|
|
14
|
-
"""
|
|
15
|
-
from hspylib.core.enums.enumeration import Enumeration
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
class InputType(Enumeration):
|
|
19
|
-
"""MenuInput input field types."""
|
|
20
|
-
|
|
21
|
-
# fmt: off
|
|
22
|
-
TEXT = "text"
|
|
23
|
-
PASSWORD = "password"
|
|
24
|
-
CHECKBOX = "checkbox"
|
|
25
|
-
SELECT = "select"
|
|
26
|
-
MASKED = "masked"
|
|
27
|
-
# fmt: on
|
|
28
|
-
|
|
29
|
-
def __repr__(self):
|
|
30
|
-
return str(self)
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
# -*- coding: utf-8 -*-
|
|
3
|
-
|
|
4
|
-
"""
|
|
5
|
-
@project: HsPyLib
|
|
6
|
-
@package: clitt.core.tui.minput
|
|
7
|
-
@file: input_validator.py
|
|
8
|
-
@created: Thu, 20 May 2021
|
|
9
|
-
@author: <B>H</B>ugo <B>S</B>aporetti <B>J</B>unior"
|
|
10
|
-
@site: https://github.com/yorevs/hspylib
|
|
11
|
-
@license: MIT - Please refer to <https://opensource.org/licenses/MIT>
|
|
12
|
-
|
|
13
|
-
Copyright·(c)·2024,·HSPyLib
|
|
14
|
-
"""
|
|
15
|
-
|
|
16
|
-
from hspylib.core.enums.enumeration import Enumeration
|
|
17
|
-
from hspylib.core.tools.validator import Validator
|
|
18
|
-
|
|
19
|
-
import re
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
class InputValidator(Validator):
|
|
23
|
-
"""MenuInput 'input' validator."""
|
|
24
|
-
|
|
25
|
-
class PatternType(Enumeration):
|
|
26
|
-
# fmt: off
|
|
27
|
-
CUSTOM = r'' # It will be set later
|
|
28
|
-
ANYTHING = r'.'
|
|
29
|
-
LETTERS = r'[a-zA-Z]'
|
|
30
|
-
WORDS = r'[a-zA-Z0-9 _]'
|
|
31
|
-
NUMBERS = r'[0-9\.\,]'
|
|
32
|
-
MASKED = r'[a-zA-Z0-9]'
|
|
33
|
-
# fmt: on
|
|
34
|
-
|
|
35
|
-
@classmethod
|
|
36
|
-
def custom(cls, pattern: str) -> "InputValidator":
|
|
37
|
-
"""Return a custom validator that allows customize the input rules.
|
|
38
|
-
:param pattern: the custom validator pattern.
|
|
39
|
-
"""
|
|
40
|
-
pattern_type = cls.PatternType.CUSTOM
|
|
41
|
-
validator = InputValidator(pattern_type=pattern_type)
|
|
42
|
-
validator.pattern = pattern
|
|
43
|
-
return validator
|
|
44
|
-
|
|
45
|
-
@classmethod
|
|
46
|
-
def letters(cls) -> "InputValidator":
|
|
47
|
-
"""Return a validator that allows only letters."""
|
|
48
|
-
return InputValidator(cls.PatternType.LETTERS)
|
|
49
|
-
|
|
50
|
-
@classmethod
|
|
51
|
-
def numbers(cls) -> "InputValidator":
|
|
52
|
-
"""Return a validator that allows only numbers."""
|
|
53
|
-
return InputValidator(cls.PatternType.NUMBERS)
|
|
54
|
-
|
|
55
|
-
@classmethod
|
|
56
|
-
def words(cls) -> "InputValidator":
|
|
57
|
-
"""Return a validator that allows only words (space, numbers or letters)."""
|
|
58
|
-
return InputValidator(cls.PatternType.WORDS)
|
|
59
|
-
|
|
60
|
-
@classmethod
|
|
61
|
-
def anything(cls) -> "InputValidator":
|
|
62
|
-
"""Return a validator that allows any input value."""
|
|
63
|
-
return InputValidator(cls.PatternType.ANYTHING)
|
|
64
|
-
|
|
65
|
-
@classmethod
|
|
66
|
-
def masked(cls) -> "InputValidator":
|
|
67
|
-
"""Return a validator that allows masked inputs."""
|
|
68
|
-
return InputValidator(cls.PatternType.MASKED)
|
|
69
|
-
|
|
70
|
-
def __init__(self, pattern_type: PatternType = PatternType.ANYTHING):
|
|
71
|
-
self._pattern_type = pattern_type
|
|
72
|
-
self._pattern = pattern_type.value
|
|
73
|
-
|
|
74
|
-
def __str__(self) -> str:
|
|
75
|
-
return f'r"{self.pattern}"' if self.pattern_type == self.PatternType.CUSTOM else self.pattern_type.name
|
|
76
|
-
|
|
77
|
-
def __repr__(self):
|
|
78
|
-
return str(self)
|
|
79
|
-
|
|
80
|
-
def __call__(self, *args, **kwargs) -> bool:
|
|
81
|
-
return all(self.validate(value) for value in args)
|
|
82
|
-
|
|
83
|
-
def validate(self, value: str) -> bool:
|
|
84
|
-
"""Validate the value against the validator pattern."""
|
|
85
|
-
unmasked_value = re.split("[|,;]", value)[0] if value else ""
|
|
86
|
-
return bool(re.match(self.pattern, unmasked_value))
|
|
87
|
-
|
|
88
|
-
@property
|
|
89
|
-
def pattern(self) -> str:
|
|
90
|
-
return str(self._pattern)
|
|
91
|
-
|
|
92
|
-
@pattern.setter
|
|
93
|
-
def pattern(self, pattern: str) -> None:
|
|
94
|
-
self._pattern = rf"{pattern}"
|
|
95
|
-
|
|
96
|
-
@property
|
|
97
|
-
def pattern_type(self) -> PatternType:
|
|
98
|
-
return self._pattern_type
|
|
@@ -1,292 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
# -*- coding: utf-8 -*-
|
|
3
|
-
|
|
4
|
-
"""
|
|
5
|
-
@project: HsPyLib
|
|
6
|
-
@package: clitt.core.tui.minput
|
|
7
|
-
@file: menu_input.py
|
|
8
|
-
@created: Wed, 17 May 2023
|
|
9
|
-
@author: <B>H</B>ugo <B>S</B>aporetti <B>J</B>unior"
|
|
10
|
-
@site: https://github.com/yorevs/hspylib
|
|
11
|
-
@license: MIT - Please refer to <https://opensource.org/licenses/MIT>
|
|
12
|
-
|
|
13
|
-
Copyright·(c)·2024,·HSPyLib
|
|
14
|
-
"""
|
|
15
|
-
from clitt.core.icons.font_awesome.form_icons import FormIcons
|
|
16
|
-
from clitt.core.icons.font_awesome.nav_icons import NavIcons
|
|
17
|
-
from clitt.core.term.commons import Direction, get_cursor_position
|
|
18
|
-
from clitt.core.term.terminal import Terminal
|
|
19
|
-
from clitt.core.tui.minput import minput_utils as mu
|
|
20
|
-
from clitt.core.tui.minput.form_builder import FormBuilder
|
|
21
|
-
from clitt.core.tui.minput.form_field import FormField
|
|
22
|
-
from clitt.core.tui.minput.input_type import InputType
|
|
23
|
-
from clitt.core.tui.minput.minput_utils import MASK_SYMBOLS, VALUE_SEPARATORS
|
|
24
|
-
from clitt.core.tui.tui_component import TUIComponent
|
|
25
|
-
from functools import reduce
|
|
26
|
-
from hspylib.core.exception.exceptions import InvalidInputError, InvalidStateError
|
|
27
|
-
from hspylib.core.namespace import Namespace
|
|
28
|
-
from hspylib.core.tools.text_tools import xstr
|
|
29
|
-
from hspylib.modules.cli.keyboard import Keyboard
|
|
30
|
-
from operator import add
|
|
31
|
-
from time import sleep
|
|
32
|
-
from typing import List, Optional
|
|
33
|
-
|
|
34
|
-
import pyperclip
|
|
35
|
-
import re
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
class MenuInput(TUIComponent):
|
|
39
|
-
"""Provide a form input for terminal UIs."""
|
|
40
|
-
|
|
41
|
-
NAV_ICONS = NavIcons.compose(NavIcons.UP, NavIcons.DOWN)
|
|
42
|
-
|
|
43
|
-
@classmethod
|
|
44
|
-
def builder(cls) -> FormBuilder:
|
|
45
|
-
return FormBuilder()
|
|
46
|
-
|
|
47
|
-
def __init__(self, title: str, fields: List[FormField]):
|
|
48
|
-
super().__init__(title)
|
|
49
|
-
self.fields = fields
|
|
50
|
-
self.positions = [(0, 0) for _ in fields]
|
|
51
|
-
self.cur_field = self._done = None
|
|
52
|
-
self.cur_row = self.cur_col = self.tab_index = 0
|
|
53
|
-
self.max_label_length = max(len(field.label) for field in fields)
|
|
54
|
-
self.max_value_length = max(field.max_length for field in fields)
|
|
55
|
-
self.max_detail_length = max(mu.detail_len(field) for field in fields)
|
|
56
|
-
|
|
57
|
-
def execute(self) -> Optional[Namespace]:
|
|
58
|
-
if len(self.fields) == 0:
|
|
59
|
-
return None
|
|
60
|
-
|
|
61
|
-
self._prepare_render()
|
|
62
|
-
keypress = self._loop()
|
|
63
|
-
|
|
64
|
-
if keypress == Keyboard.VK_ENTER:
|
|
65
|
-
form_fields = Namespace("FormFields")
|
|
66
|
-
for field in self.fields:
|
|
67
|
-
form_fields.setattr(field.dest, field.value)
|
|
68
|
-
return form_fields
|
|
69
|
-
|
|
70
|
-
return None
|
|
71
|
-
|
|
72
|
-
def render(self) -> None:
|
|
73
|
-
|
|
74
|
-
Terminal.set_show_cursor(False)
|
|
75
|
-
self.cursor.restore()
|
|
76
|
-
self.writeln(f"{self.prefs.title_color.placeholder}{self.title}%EOL%%NC%")
|
|
77
|
-
|
|
78
|
-
for idx, field in enumerate(self.fields):
|
|
79
|
-
field_length = field.length
|
|
80
|
-
if self.tab_index == idx:
|
|
81
|
-
mu.mi_print(
|
|
82
|
-
self.screen, f" {field.label}", self.prefs.sel_bg_color.placeholder, self.max_label_length + 2
|
|
83
|
-
)
|
|
84
|
-
self.cur_field = field
|
|
85
|
-
else:
|
|
86
|
-
mu.mi_print(self.screen, f" {field.label}", field_len=self.max_label_length + 2)
|
|
87
|
-
self._buffer_positions(idx, field_length)
|
|
88
|
-
self._render_field(field)
|
|
89
|
-
self._render_details(field, field_length)
|
|
90
|
-
|
|
91
|
-
self.cursor.erase(Direction.DOWN)
|
|
92
|
-
self.draw_navbar(self.navbar())
|
|
93
|
-
self._set_cursor_pos()
|
|
94
|
-
self._re_render = False
|
|
95
|
-
Terminal.set_show_cursor()
|
|
96
|
-
|
|
97
|
-
def navbar(self, **kwargs) -> str:
|
|
98
|
-
|
|
99
|
-
return (
|
|
100
|
-
f"%EOL%{NavIcons.POINTER} %GREEN%{self.cur_field.tooltip or f'the {self.cur_field.label.lower()}'}%NC%"
|
|
101
|
-
f"%EOL%{self.prefs.navbar_color.placeholder}%EOL%"
|
|
102
|
-
f"[Enter] Submit [{self.NAV_ICONS}] "
|
|
103
|
-
f"Navigate [{NavIcons.TAB}] Next [Space] Toggle [^P] Paste [Esc] Quit %NC%"
|
|
104
|
-
)
|
|
105
|
-
|
|
106
|
-
def handle_keypress(self) -> Keyboard:
|
|
107
|
-
length = len(self.fields)
|
|
108
|
-
|
|
109
|
-
if keypress := Keyboard.wait_keystroke():
|
|
110
|
-
match keypress:
|
|
111
|
-
case Keyboard.VK_ESC:
|
|
112
|
-
self._done = True
|
|
113
|
-
case _ as key if key in [Keyboard.VK_TAB, Keyboard.VK_DOWN]:
|
|
114
|
-
self.tab_index = min(length - 1, self.tab_index + 1)
|
|
115
|
-
case _ as key if key in [Keyboard.VK_SHIFT_TAB, Keyboard.VK_UP]:
|
|
116
|
-
self.tab_index = max(0, self.tab_index - 1)
|
|
117
|
-
case Keyboard.VK_BACKSPACE:
|
|
118
|
-
if not self.cur_field.can_write():
|
|
119
|
-
self._display_error("This field is read only !")
|
|
120
|
-
else:
|
|
121
|
-
self._handle_backspace()
|
|
122
|
-
case Keyboard.VK_CTRL_P:
|
|
123
|
-
self._handle_ctrl_p()
|
|
124
|
-
case Keyboard.VK_ENTER:
|
|
125
|
-
return self._handle_enter()
|
|
126
|
-
case _ as key if key.isalnum() or key.ispunct() or key == Keyboard.VK_SPACE:
|
|
127
|
-
if not self.cur_field.can_write():
|
|
128
|
-
self._display_error("This field is read only !")
|
|
129
|
-
else:
|
|
130
|
-
self._handle_input(keypress)
|
|
131
|
-
|
|
132
|
-
self._re_render = True
|
|
133
|
-
|
|
134
|
-
return keypress
|
|
135
|
-
|
|
136
|
-
def _handle_enter(self) -> Optional[Keyboard]:
|
|
137
|
-
"""Handle 'enter' press. Validate & Save form and exit."""
|
|
138
|
-
invalid = next((field for field in self.fields if not field.validate_field()), None)
|
|
139
|
-
if invalid:
|
|
140
|
-
idx = self.fields.index(invalid)
|
|
141
|
-
pos = self.positions[idx]
|
|
142
|
-
self.cur_row = pos[0]
|
|
143
|
-
self.tab_index = idx
|
|
144
|
-
self._display_error("Form field is not valid: " + str(invalid))
|
|
145
|
-
return None
|
|
146
|
-
|
|
147
|
-
for idx, field in enumerate(self.fields):
|
|
148
|
-
match field.itype:
|
|
149
|
-
case InputType.MASKED:
|
|
150
|
-
field.value = re.split(VALUE_SEPARATORS, field.value)[0]
|
|
151
|
-
case InputType.CHECKBOX:
|
|
152
|
-
field.value = bool(field.value)
|
|
153
|
-
case InputType.SELECT:
|
|
154
|
-
_, field.value = mu.get_selected(field.value)
|
|
155
|
-
self._done = True
|
|
156
|
-
return Keyboard.VK_ENTER
|
|
157
|
-
|
|
158
|
-
def _handle_input(self, keypress: Keyboard) -> None:
|
|
159
|
-
"""Handle a form input.
|
|
160
|
-
:param keypress: the input provided by the keypress.
|
|
161
|
-
"""
|
|
162
|
-
|
|
163
|
-
match self.cur_field.itype:
|
|
164
|
-
case InputType.CHECKBOX:
|
|
165
|
-
if keypress == Keyboard.VK_SPACE:
|
|
166
|
-
self.cur_field.value = not self.cur_field.value
|
|
167
|
-
case InputType.SELECT:
|
|
168
|
-
if keypress == Keyboard.VK_SPACE:
|
|
169
|
-
if self.cur_field.value:
|
|
170
|
-
self.cur_field.value = mu.toggle_selected(xstr(self.cur_field.value))
|
|
171
|
-
case InputType.MASKED:
|
|
172
|
-
value, mask = mu.unpack_masked(xstr(self.cur_field.value))
|
|
173
|
-
try:
|
|
174
|
-
self.cur_field.value = mu.append_masked(value, mask, keypress.value)
|
|
175
|
-
except InvalidInputError as err:
|
|
176
|
-
self._display_error(str(err))
|
|
177
|
-
case _:
|
|
178
|
-
if len(xstr(self.cur_field.value)) < self.cur_field.max_length:
|
|
179
|
-
if self.cur_field.validate_input(keypress.value):
|
|
180
|
-
self.cur_field.value = (str(self.cur_field.value) if self.cur_field.value else "") + str(
|
|
181
|
-
keypress.value
|
|
182
|
-
)
|
|
183
|
-
else:
|
|
184
|
-
self._display_error(
|
|
185
|
-
f"Input '{keypress.value}' is invalid. "
|
|
186
|
-
f"This field takes only {self.cur_field.input_validator}!"
|
|
187
|
-
)
|
|
188
|
-
|
|
189
|
-
def _handle_backspace(self) -> None:
|
|
190
|
-
"""Handle 'backspace' press. Delete previous input."""
|
|
191
|
-
|
|
192
|
-
if self.cur_field.itype == InputType.MASKED:
|
|
193
|
-
value, mask = mu.unpack_masked(str(self.cur_field.value))
|
|
194
|
-
value = value[:-1]
|
|
195
|
-
while mask[len(value) - 1] not in MASK_SYMBOLS:
|
|
196
|
-
value = value[:-1]
|
|
197
|
-
self.cur_field.value = f"{value}|{mask}"
|
|
198
|
-
elif self.cur_field.itype not in [InputType.CHECKBOX, InputType.SELECT]:
|
|
199
|
-
if self.cur_field.can_write() and len(str(self.cur_field.value)) >= 1:
|
|
200
|
-
self.cur_field.value = str(self.cur_field.value)[:-1]
|
|
201
|
-
elif not self.cur_field.can_write():
|
|
202
|
-
self._display_error("This field is read only !")
|
|
203
|
-
|
|
204
|
-
def _handle_ctrl_p(self) -> None:
|
|
205
|
-
"""Handle 'ctrl + p' press. Paste content from clipboard."""
|
|
206
|
-
for c in pyperclip.paste():
|
|
207
|
-
self._handle_input(Keyboard.of_value(c))
|
|
208
|
-
|
|
209
|
-
def _set_cursor_pos(self) -> None:
|
|
210
|
-
"""Set the cursor at the right position according to the ATB index."""
|
|
211
|
-
pos = self.positions[self.tab_index]
|
|
212
|
-
self.screen.cursor.move_to(pos[0], pos[1] + self.cur_field.length)
|
|
213
|
-
|
|
214
|
-
def _render_field(self, field: FormField) -> None:
|
|
215
|
-
"""Render the specified form field.
|
|
216
|
-
:param field: the form field to render.
|
|
217
|
-
"""
|
|
218
|
-
match field.itype:
|
|
219
|
-
case InputType.TEXT:
|
|
220
|
-
mu.mi_print(self.screen, xstr(field.value), field_len=self.max_value_length)
|
|
221
|
-
case InputType.PASSWORD:
|
|
222
|
-
mu.mi_print(self.screen, "*" * field.length, field_len=self.max_value_length)
|
|
223
|
-
case InputType.CHECKBOX:
|
|
224
|
-
mu.mi_print(
|
|
225
|
-
self.screen,
|
|
226
|
-
" ",
|
|
227
|
-
FormIcons.CHECK_SQUARE.unicode if field.value else FormIcons.UNCHECK_SQUARE.unicode,
|
|
228
|
-
field_len=self.max_value_length - 1,
|
|
229
|
-
)
|
|
230
|
-
case InputType.SELECT:
|
|
231
|
-
if field.value:
|
|
232
|
-
mat = re.search(rf".*({VALUE_SEPARATORS})?<(.+)>({VALUE_SEPARATORS})?.*", str(field.value))
|
|
233
|
-
sel_value = mat.group(2) if mat else re.split(VALUE_SEPARATORS, str(field.value))[0]
|
|
234
|
-
mu.mi_print(self.screen, f"{sel_value}", field_len=self.max_value_length)
|
|
235
|
-
case InputType.MASKED:
|
|
236
|
-
value, mask = mu.unpack_masked(str(field.value))
|
|
237
|
-
mu.mi_print(self.screen, mu.over_masked(value, mask), field_len=self.max_value_length)
|
|
238
|
-
case _:
|
|
239
|
-
raise InvalidStateError(f"Invalid form field type: {field.itype}")
|
|
240
|
-
|
|
241
|
-
def _render_details(self, field: FormField, field_details: int) -> None:
|
|
242
|
-
"""Render details about total/remaining field characters.
|
|
243
|
-
:param field: the form field to render.
|
|
244
|
-
:param field_details: details about the form field (total / remaining) size.
|
|
245
|
-
"""
|
|
246
|
-
padding = 1 - len(str(self.max_detail_length / 2))
|
|
247
|
-
fmt = "{:<3}{:>" + str(padding) + "}/{:<" + str(padding) + "} %NC%"
|
|
248
|
-
if field.itype == InputType.SELECT:
|
|
249
|
-
idx, _ = mu.get_selected(field.value)
|
|
250
|
-
count = len(re.split(VALUE_SEPARATORS, field.value))
|
|
251
|
-
self.writeln(fmt.format(field.icon, idx + 1 if idx >= 0 else 1, count))
|
|
252
|
-
elif field.itype == InputType.MASKED:
|
|
253
|
-
value, mask = mu.unpack_masked(xstr(field.value))
|
|
254
|
-
self.writeln(
|
|
255
|
-
fmt.format(
|
|
256
|
-
field.icon,
|
|
257
|
-
reduce(add, list(map(mask[: len(value)].count, MASK_SYMBOLS))),
|
|
258
|
-
reduce(add, list(map(mask.count, MASK_SYMBOLS))),
|
|
259
|
-
)
|
|
260
|
-
)
|
|
261
|
-
else:
|
|
262
|
-
self.writeln(fmt.format(field.icon, field_details, field.max_length))
|
|
263
|
-
|
|
264
|
-
def _buffer_positions(self, field_index: int, field_size: int) -> None:
|
|
265
|
-
"""Buffer all cursor positions to avoid calling get_cursor_pos over and over because it is a very
|
|
266
|
-
expensive call.
|
|
267
|
-
:param field_index: the current form field index.
|
|
268
|
-
:param field_size: the form field length.
|
|
269
|
-
"""
|
|
270
|
-
if f_pos := get_cursor_position() if self.positions[field_index] == (0, 0) else self.positions[field_index]:
|
|
271
|
-
self.positions[field_index] = f_pos
|
|
272
|
-
if self.tab_index == field_index:
|
|
273
|
-
self.cur_row, self.cur_col = f_pos[0], f_pos[1] + field_size
|
|
274
|
-
|
|
275
|
-
def _display_error(self, err_msg: str) -> None:
|
|
276
|
-
"""Display a form filling or submitting error.
|
|
277
|
-
:param err_msg: the error message.
|
|
278
|
-
"""
|
|
279
|
-
Terminal.set_enable_echo(False)
|
|
280
|
-
Terminal.set_show_cursor(False)
|
|
281
|
-
offset = 15 # Sum of minput used characters that are not related to the field.
|
|
282
|
-
err_pos = offset + self.max_label_length + self.max_value_length + self.max_detail_length
|
|
283
|
-
self.cursor.move_to(self.cur_row, err_pos)
|
|
284
|
-
mu.mi_print_err(self.screen, f"{FormIcons.ARROW_LEFT} {err_msg}")
|
|
285
|
-
# This calculation gives a good delay amount based on the size of the message.
|
|
286
|
-
sleep(max(2.0, int(len(err_msg) / 21)))
|
|
287
|
-
Terminal.set_enable_echo()
|
|
288
|
-
# Erase the message after the timeout
|
|
289
|
-
self.cursor.move_to(self.cur_row, err_pos)
|
|
290
|
-
self.cursor.erase(Direction.RIGHT)
|
|
291
|
-
Terminal.set_show_cursor()
|
|
292
|
-
self._re_render = True
|