cli-ih 0.5.2__py3-none-any.whl → 0.5.2.2__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.
@@ -0,0 +1,122 @@
1
+ from typing import Callable
2
+ import logging
3
+
4
+ class HandlerClosed(Exception): ...
5
+ class MissingParameter(Exception): ...
6
+
7
+ class CustomFormatter(logging.Formatter):
8
+ """Custom formatter to add colors to log levels."""
9
+
10
+ LEVEL_COLORS = {
11
+ logging.DEBUG: "\033[34m",
12
+ logging.INFO: "\033[0m",
13
+ logging.WARNING: "\033[33m",
14
+ logging.ERROR: "\033[31m",
15
+ logging.CRITICAL: "\033[37;41m"
16
+ }
17
+
18
+ def format(self, record):
19
+ log_color = self.LEVEL_COLORS.get(record.levelno, "\033[0m")
20
+ log_message = super().format(record)
21
+ return f"{log_color}{log_message}\033[0m"
22
+
23
+ def setup_logging():
24
+ log_format = '[%(asctime)s | %(levelname)s]: %(message)s'
25
+ handler = logging.StreamHandler()
26
+ handler.setFormatter(CustomFormatter(log_format))
27
+ logging.basicConfig(level=logging.INFO, handlers=[handler], datefmt='%B %d %H:%M:%S')
28
+
29
+ class InputHandler:
30
+ #logging.basicConfig(level=logging.INFO, format='[%(asctime)s | %(levelname)s]: %(message)s', datefmt='%B %d %H:%M:%S')
31
+ def __init__(self, thread_mode = True, cursor = ""):
32
+ self.commands = {}
33
+ self.is_running = False
34
+ self.thread_mode = thread_mode
35
+ self.cursor = f"{cursor.strip()} "
36
+ self.thread = None
37
+ self.register_default_commands()
38
+
39
+ def register_command(self, name: str, func: Callable, description: str = ""):
40
+ """Registers a command with its associated function."""
41
+ if not description:
42
+ description = "A command"
43
+ if ' ' in name:
44
+ raise SyntaxError("Command name must not have spaces")
45
+ self.commands[name] = {"cmd": func, "description": description}
46
+
47
+ def start(self):
48
+ """Starts the input handler loop in a separate thread if thread mode is enabled."""
49
+ import threading, inspect
50
+ self.is_running = True
51
+
52
+ def run_command(commands: dict, name: str, args: list):
53
+ """Executes a command from the command dictionary if it exists."""
54
+ command = commands.get(name)
55
+ if command:
56
+ func = command.get("cmd")
57
+ if callable(func):
58
+ if str(inspect.signature(func)) == "()":
59
+ raise MissingParameter(f"Command '{name}' must accept an 'args' parameter")
60
+ try:
61
+ func(args)
62
+ except Exception as e:
63
+ raise e
64
+ else:
65
+ raise ValueError(f"The command '{name}' is not callable.")
66
+ else:
67
+ logging.warning(f"Command '{name}' not found.")
68
+
69
+
70
+ def _thread():
71
+ """Continuously listens for user input and processes commands."""
72
+ while self.is_running:
73
+ try:
74
+ user_input = input(self.cursor).strip()
75
+ if not user_input:
76
+ continue
77
+
78
+ cmdargs = user_input.split(' ')
79
+ command_name = cmdargs[0]
80
+ args = cmdargs[1:]
81
+ if command_name in self.commands:
82
+ run_command(self.commands, command_name, args)
83
+ else:
84
+ logging.warning(f"Unknown command: '{command_name}'")
85
+ except EOFError:
86
+ logging.error("Input ended unexpectedly.")
87
+ break
88
+ except KeyboardInterrupt:
89
+ logging.error("Input interrupted.")
90
+ break
91
+ except HandlerClosed:
92
+ logging.info("Input Handler exited.")
93
+ break
94
+ self.is_running = False
95
+ if self.thread_mode:
96
+ self.thread = threading.Thread(target=_thread, daemon=True)
97
+ self.thread.start()
98
+ else:
99
+ _thread()
100
+
101
+ def register_default_commands(self):
102
+ def help(commands):
103
+ str_out = ""
104
+ for command in commands:
105
+ str_out += f"{command}: {commands[command]['description']}\n"
106
+ print(str_out)
107
+
108
+ def debug_mode(args):
109
+ logger = logging.getLogger()
110
+ if logger.getEffectiveLevel() == logging.DEBUG:
111
+ logger.setLevel(logging.INFO)
112
+ logging.info("Debug mode is now off")
113
+ else:
114
+ logger.setLevel(logging.DEBUG)
115
+ logging.debug("Debug mode is now on")
116
+
117
+ def exit_thread(args):
118
+ raise HandlerClosed
119
+ self.register_command("help", lambda args: help(self.commands), "Displays all the available commands")
120
+ self.register_command("debug", debug_mode, "Changes the logging level to DEBUG.")
121
+ self.register_command("exit", exit_thread, "Exits the Input Handler irreversibly.")
122
+ setup_logging()
InputHandler/__init__.py CHANGED
@@ -1,122 +1 @@
1
- from typing import Callable
2
- import logging
3
-
4
- class HandlerClosed(Exception): ...
5
- class MissingParameter(Exception): ...
6
-
7
- class CustomFormatter(logging.Formatter):
8
- """Custom formatter to add colors to log levels."""
9
-
10
- LEVEL_COLORS = {
11
- logging.DEBUG: "\033[34m",
12
- logging.INFO: "\033[0m",
13
- logging.WARNING: "\033[33m",
14
- logging.ERROR: "\033[31m",
15
- logging.CRITICAL: "\033[37;41m"
16
- }
17
-
18
- def format(self, record):
19
- log_color = self.LEVEL_COLORS.get(record.levelno, "\033[0m")
20
- log_message = super().format(record)
21
- return f"{log_color}{log_message}\033[0m"
22
-
23
- def setup_logging():
24
- log_format = '[%(asctime)s | %(levelname)s]: %(message)s'
25
- handler = logging.StreamHandler()
26
- handler.setFormatter(CustomFormatter(log_format))
27
- logging.basicConfig(level=logging.INFO, handlers=[handler], datefmt='%B %d %H:%M:%S')
28
-
29
- class InputHandler:
30
- #logging.basicConfig(level=logging.INFO, format='[%(asctime)s | %(levelname)s]: %(message)s', datefmt='%B %d %H:%M:%S')
31
- def __init__(self, thread_mode = True, cursor = ""):
32
- self.commands = {}
33
- self.is_running = False
34
- self.thread_mode = thread_mode
35
- self.cursor = f"{cursor.strip()} "
36
- self.thread = None
37
- self.register_default_commands()
38
-
39
- def register_command(self, name: str, func: Callable, description: str = ""):
40
- """Registers a command with its associated function."""
41
- if not description:
42
- description = "A command"
43
- if ' ' in name:
44
- raise SyntaxError("Command name must not have spaces")
45
- self.commands[name] = {"cmd": func, "description": description}
46
-
47
- def start(self):
48
- """Starts the input handler loop in a separate thread if thread mode is enabled."""
49
- import threading, inspect
50
- self.is_running = True
51
-
52
- def run_command(commands: dict, name: str, args: list):
53
- """Executes a command from the command dictionary if it exists."""
54
- command = commands.get(name)
55
- if command:
56
- func = command.get("cmd")
57
- if callable(func):
58
- if str(inspect.signature(func)) == "()":
59
- raise MissingParameter(f"Command '{name}' must accept an 'args' parameter")
60
- try:
61
- func(args)
62
- except Exception as e:
63
- raise e
64
- else:
65
- raise ValueError(f"The command '{name}' is not callable.")
66
- else:
67
- logging.warning(f"Command '{name}' not found.")
68
-
69
-
70
- def _thread():
71
- """Continuously listens for user input and processes commands."""
72
- while self.is_running:
73
- try:
74
- user_input = input(self.cursor).strip()
75
- if not user_input:
76
- continue
77
-
78
- cmdargs = user_input.split(' ')
79
- command_name = cmdargs[0]
80
- args = cmdargs[1:]
81
- if command_name in self.commands:
82
- run_command(self.commands, command_name, args)
83
- else:
84
- logging.warning(f"Unknown command: '{command_name}'")
85
- except EOFError:
86
- logging.error("Input ended unexpectedly.")
87
- break
88
- except KeyboardInterrupt:
89
- logging.error("Input interrupted.")
90
- break
91
- except HandlerClosed:
92
- logging.info("Input Handler exited.")
93
- break
94
- self.is_running = False
95
- if self.thread_mode:
96
- self.thread = threading.Thread(target=_thread, daemon=True)
97
- self.thread.start()
98
- else:
99
- _thread()
100
-
101
- def register_default_commands(self):
102
- def help(commands):
103
- str_out = ""
104
- for command in commands:
105
- str_out += f"{command}: {commands[command]['description']}\n"
106
- print(str_out)
107
-
108
- def debug_mode(args):
109
- logger = logging.getLogger()
110
- if logger.getEffectiveLevel() == logging.DEBUG:
111
- logger.setLevel(logging.INFO)
112
- logging.info("Debug mode is now off")
113
- else:
114
- logger.setLevel(logging.DEBUG)
115
- logging.debug("Debug mode is now on")
116
-
117
- def exit_thread(args):
118
- raise HandlerClosed
119
- self.register_command("help", lambda args: help(self.commands), "Displays all the available commands")
120
- self.register_command("debug", debug_mode, "Changes the logging level to DEBUG.")
121
- self.register_command("exit", exit_thread, "Exits the Input Handler irreversibly.")
122
- setup_logging()
1
+ from . import InputHandler
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: cli_ih
3
- Version: 0.5.2
3
+ Version: 0.5.2.2
4
4
  Summary: A background command handler for python's command line interface.
5
5
  Author-email: Hotment <michatchuplay@gmail.com>
6
6
  Requires-Python: >=3.8
@@ -20,12 +20,12 @@ A lightweight Python library for creating interactive command-line interfaces wi
20
20
 
21
21
  ## Installation
22
22
 
23
- pip install cli-ih
23
+ `pip install cli-ih`
24
24
 
25
25
  ## Quick Start
26
26
 
27
27
  ```python
28
- from cli-ih import InputHandler
28
+ from cli_ih import InputHandler
29
29
 
30
30
  def greet(args):
31
31
  print(f"Hello, {' '.join(args)}!")
@@ -0,0 +1,6 @@
1
+ InputHandler/InputHandler.py,sha256=_OUI_BT6EN1wfWmLtm94bFLlHLvK01TKCzifEg2uNYQ,4932
2
+ InputHandler/__init__.py,sha256=biHQ9fiomeNJ4G6h3KvdJlCca8r7l89mkKlDCrckNUY,26
3
+ cli_ih-0.5.2.2.dist-info/METADATA,sha256=b6KQuipjMh1u27LjVlywzyO4mYkIBFrw6qlntnLQ8Uc,1604
4
+ cli_ih-0.5.2.2.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
5
+ cli_ih-0.5.2.2.dist-info/top_level.txt,sha256=1wOYpDwNGBjhQWhD3dRvyWH1Hh4U6HWbAqJAq-p4Izg,13
6
+ cli_ih-0.5.2.2.dist-info/RECORD,,
@@ -1,5 +0,0 @@
1
- InputHandler/__init__.py,sha256=_OUI_BT6EN1wfWmLtm94bFLlHLvK01TKCzifEg2uNYQ,4932
2
- cli_ih-0.5.2.dist-info/METADATA,sha256=rupWmHvik9X9k0ZhHXOiuL_ZtGqCpkqiqjxgMm6NRwQ,1600
3
- cli_ih-0.5.2.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
4
- cli_ih-0.5.2.dist-info/top_level.txt,sha256=1wOYpDwNGBjhQWhD3dRvyWH1Hh4U6HWbAqJAq-p4Izg,13
5
- cli_ih-0.5.2.dist-info/RECORD,,