diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..13566b8
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/.idea/CLI-in-Python.iml b/.idea/CLI-in-Python.iml
new file mode 100644
index 0000000..3ae5178
--- /dev/null
+++ b/.idea/CLI-in-Python.iml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 0000000..8d7da84
--- /dev/null
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml
new file mode 100644
index 0000000..105ce2d
--- /dev/null
+++ b/.idea/inspectionProfiles/profiles_settings.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..dc9ea49
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..355067e
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..94a25f7
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/README.md b/README.md
index ca37843..7edd507 100644
--- a/README.md
+++ b/README.md
@@ -11,4 +11,6 @@
* [Мой Telegram](https://t.me/SantaSpeen "SantaSpeen"): https://t.me/SantaSpeen
-Используемые библиотеки:
\ No newline at end of file
+Используемые библиотеки:
+
+*
\ No newline at end of file
diff --git a/scr/builtins_fix.pyi b/scr/builtins_fix.pyi
new file mode 100644
index 0000000..87834ef
--- /dev/null
+++ b/scr/builtins_fix.pyi
@@ -0,0 +1,42 @@
+class Console(object):
+
+ def __init__(self,
+ prompt_in: str = ">",
+ prompt_out: str = "]:",
+ not_found: str = "Command \"%s\" not found in alias.") -> None: ...
+
+ def __getitem__(self, item): ...
+ @property
+ def alias(self) -> dict: ...
+ def add(self, key: str, func: function) -> dict: ...
+ def log(self, s: str, r='\r') -> None: ...
+ def write(self, s: str, r='\r') -> None: ...
+ def __lshift__(self, s: AnyStr) -> None: ...
+ def logger_hook(self) -> None: ...
+ def builtins_hook(self) -> None: ...
+ def run(self) -> None: ...
+ def run_while(self, whl) -> None:...
+
+class console(object):
+
+ @staticmethod
+ def alias() -> dict: ...
+ @staticmethod
+ def add(key: str, func: function) -> dict: ...
+
+ @staticmethod
+ def run() -> None: ...
+ @staticmethod
+ def run_while(whl: Any) -> None: ...
+
+ @staticmethod
+ def builtins_hook() -> None: ...
+ @staticmethod
+ def logger_hook() -> None: ...
+
+ @staticmethod
+ def log(s: str) -> None: ...
+ @staticmethod
+ def write(s: str) -> None: ...
+ @staticmethod
+ def __lshift__(s: AnyStr) -> None: ...
diff --git a/scr/console/Console.py b/scr/console/Console.py
new file mode 100644
index 0000000..884dd3f
--- /dev/null
+++ b/scr/console/Console.py
@@ -0,0 +1,215 @@
+# -*- coding: utf-8 -*-
+
+# Developed by Ahegao Devs
+# Written by: SantaSpeen
+# Licence: MIT
+# (c) ahegao.ovh 2022
+
+import builtins
+import logging
+import sys
+import traceback
+from typing import AnyStr
+
+
+class ConsoleIO:
+
+ @staticmethod
+ def write(s: AnyStr):
+ sys.stdout.write(s)
+
+ @staticmethod
+ def write_err(s: AnyStr):
+ sys.stderr.write(s)
+
+ @staticmethod
+ def read():
+ return sys.stdin.readline().strip()
+
+
+# noinspection PyUnusedLocal, PyShadowingBuiltins, PyUnresolvedReferences
+class Console:
+
+ def __init__(self,
+ prompt_in: str = ">",
+ prompt_out: str = "]:",
+ not_found: str = "Command \"%s\" not found in alias.",
+ file: str or None = None,
+ debug: bool = False) -> None:
+ """
+ def __init__(self,
+ prompt_in: str = ">",
+ prompt_out: str = "]:",
+ not_found: str = "Command \"%s\" not found in alias.") -> None:
+ :param prompt_in:
+ :param prompt_out:
+ :param not_found:
+ """
+ self.__prompt_in = prompt_in
+ self.__prompt_out = prompt_out
+ self.__not_found = not_found + "\n"
+ self.__is_debug = debug
+
+ self.__print = print
+
+ self.__file = file
+
+ self.__alias = {
+ "help": self.__create_help_message,
+ }
+
+ self.get_IO = ConsoleIO
+
+ def __debug(self, *x):
+ if self.__is_debug:
+ x = list(x)
+ x.insert(0, "\r CONSOLE DEBUG:")
+ self.__print(*x)
+
+ def __getitem__(self, item):
+
+ print(item)
+
+ @staticmethod
+ def __get_max_len(arg) -> int:
+ arg = list(arg)
+ i = 0
+ for a in arg:
+ l = len(a)
+ if l > i:
+ i = l
+ return i
+
+ # noinspection PyStringFormat
+ def __create_help_message(self, x) -> AnyStr:
+ """ Print help message and alias of console commands"""
+ self.__debug("creating help message")
+
+ max_len = self.__get_max_len(self.__alias.keys())
+ if max_len < 7:
+ max_len = 7
+
+ message = f"%{max_len}s : Help message\n" % "Command"
+ for k, v in self.__alias.items():
+ doc = v.__doc__
+ if doc is None:
+ doc = " No help message found"
+ message += f" %{max_len}s :%s\n" % (k, doc)
+
+ return message
+
+ def __create_message(self, text, r="\r"):
+ self.__debug("create message to output")
+ return r + self.__prompt_out + " " + text + "\n\r" + self.__prompt_in + " "
+
+ @property
+ def alias(self) -> dict:
+ """
+ def alias(self) -> dict:
+ :return: dict of alias
+ """
+ return self.__alias.copy()
+
+ def add(self, key: str, func) -> dict:
+ """
+ def add(self, key: str, func) -> dict:
+ :param key:
+ :param func:
+ :return:
+ """
+
+ key = key.format(" ", "-")
+
+ if not isinstance(key, str):
+ raise TypeError("key must be string")
+ self.__debug(f"added user command: key={key}; func={func}")
+ self.__alias.update({key: func})
+ return self.__alias.copy()
+
+ def write(self, s: AnyStr, r="\r"):
+ s = s.replace("\n\t", "\n" + self.__prompt_out + " ").replace("\t", " ")
+ ConsoleIO.write(self.__create_message(s, r))
+
+ def log(self, s: AnyStr, r='\r') -> None:
+ self.write(s, r)
+
+ def __lshift__(self, s: AnyStr) -> None:
+ self.write(s)
+
+ def __builtins_print(self,
+ *values: object,
+ sep: str or None = " ",
+ end: str or None = None,
+ file: str or None = None,
+ flush: bool = False,
+ loading: bool = False) -> None:
+ val = list(values)
+ if len(val) > 0:
+ val.insert(0, "\r" + self.__prompt_out)
+ if not loading:
+ val.append("\r\n" + self.__prompt_in + " ")
+ end = "" if end is None else end
+ self.__print(*tuple(val), sep=sep, end=end, file=file, flush=flush)
+
+ def logger_hook(self) -> None:
+
+ self.__debug("used logger_hook")
+
+ def emit(cls, record):
+ try:
+ msg = cls.format(record)
+ ConsoleIO.write(self.__create_message(msg))
+ cls.flush()
+ except RecursionError: # See issue 36272
+ raise
+ except Exception:
+ cls.handleError(record)
+
+ logging.StreamHandler.emit = emit
+
+ def builtins_hook(self) -> None:
+ """
+ def builtins_hook(self) -> None:
+ :return: None
+ """
+ self.__debug("used builtins_hook")
+ builtins.Console = Console
+ builtins.console = self
+ builtins.print = self.__builtins_print
+
+ def run(self) -> None:
+ """
+ def run(self) -> None:
+ :return: None
+ """
+ self.run_while(True)
+
+ def run_while(self, whl) -> None:
+ """
+ def run_while(self, whl) -> None:
+ :param whl: run while what?
+ :return: None
+ """
+ self.__debug(f"run while {whl}")
+ while whl:
+ try:
+ ConsoleIO.write("\r" + self.__prompt_in + " ")
+ cmd_in = ConsoleIO.read()
+ cmd = cmd_in.split(" ")[0]
+ if cmd == "":
+ pass
+ else:
+ command = self.__alias.get(cmd)
+ if command:
+ x = cmd_in[len(cmd) + 1:]
+ output = command(x)
+ if isinstance(output, str):
+ self.log(output)
+ else:
+ self.log(self.__not_found % cmd)
+ except Exception as e:
+ if e == KeyboardInterrupt:
+ raise e
+ ConsoleIO.write_err("\rDuring the execution of the command, an error occurred:\n\n" +
+ str(traceback.format_exc()) +
+ "\nType Enter to continue.")
diff --git a/scr/console/Console.pyi b/scr/console/Console.pyi
new file mode 100644
index 0000000..6844891
--- /dev/null
+++ b/scr/console/Console.pyi
@@ -0,0 +1,45 @@
+# -*- coding: utf-8 -*-
+
+# Developed by Ahegao Devs
+# Written by: SantaSpeen
+# Licence: MIT
+# (c) ahegao.ovh 2022
+
+from _typeshed import SupportsWrite
+from builtins import function
+from typing import AnyStr
+
+
+class ConsoleIO:
+
+ @staticmethod
+ def write(s: AnyStr): ...
+
+ @staticmethod
+ def write_err(s: AnyStr): ...
+
+ @staticmethod
+ def read(): ...
+
+
+class Console(object):
+
+ def __init__(self,
+ prompt_in: str = ">",
+ prompt_out: str = "]:",
+ not_found: str = "Command \"%s\" not found in alias.",
+ file: SupportsWrite[str] or None = Console,
+ debug: bool = False) -> None:
+
+ self.get_IO: ConsoleIO
+
+ def __getitem__(self, item): ...
+ @property
+ def alias(self) -> dict: ...
+ def add(self, key: str, func: function) -> dict: ...
+ def log(self, s: AnyStr, r='\r') -> None: ...
+ def write(self, s: AnyStr, r='\r') -> None: ...
+ def logger_hook(self) -> None: ...
+ def builtins_hook(self) -> None: ...
+ def run(self) -> None: ...
+ def run_while(self, whl) -> None:...
\ No newline at end of file
diff --git a/scr/console/__init__.py b/scr/console/__init__.py
new file mode 100644
index 0000000..a298f7d
--- /dev/null
+++ b/scr/console/__init__.py
@@ -0,0 +1 @@
+from .Console import Console, ConsoleIO
diff --git a/scr/main.py b/scr/main.py
new file mode 100644
index 0000000..2d39021
--- /dev/null
+++ b/scr/main.py
@@ -0,0 +1,95 @@
+import logging
+import os
+
+from console import Console, ConsoleIO
+
+# Init modules
+cli = Console() # Console(debug=True)
+logging.basicConfig(level=logging.NOTSET, format="%(asctime)s - %(name)-5s - %(levelname)-7s - %(message)s")
+
+
+def cli_print():
+ """ How can I write text to the console? Read below! """
+ cli.log("cli.og")
+ cli.write("cli.write")
+
+ print("\r...", end="\n\n\n")
+
+
+def logger_preview():
+ """ I use logging and want its output to be in the console! """
+ cli.logger_hook()
+
+ # All calls below will be implemented via Console
+
+ logging.debug("Debug log")
+ logging.warning('Warning log')
+ logging.error("Error log")
+ logging.info("Info log")
+
+ print("\r...", end="\n\n\n")
+
+
+def builtins_preview():
+ """ I want print to be output like cli.log """
+
+ # Output below without hook
+
+ print("No builtins_hook here")
+ print("No builtins_hook here, but file=cli, end=''", file=cli, end="")
+
+ cli.builtins_hook()
+
+ # Output below from the hook
+ # After hook cli = console
+
+ print("builtins_hook here")
+
+ console.write("console.write")
+ console.log("console.log")
+
+ console['[] log']
+ console << "<< log"
+
+ ConsoleIO.write("\r...\n\n") # Or console.get_IO.write("\r...\n\n")
+
+
+def cli_echo(x: str):
+ """ Help message here """
+
+ message = "Echo message: " + x
+
+ return message
+
+
+def cli_error(x):
+ """ Print error message """
+
+ raise Exception("Test error message")
+
+
+def cli_exit():
+ """ Kill process """
+
+ pid = os.getpid()
+ os.system(f"kill {pid}")
+
+
+def cli_mode():
+ print("type help")
+
+ cli.add("echo", cli_echo)
+ cli.add("error", cli_error)
+ cli.add("exit", cli_exit)
+
+ cli.run()
+
+ # Or you may use
+ # cli.run_while(lambda: )
+
+
+if __name__ == '__main__':
+ cli_print()
+ logger_preview()
+ builtins_preview()
+ cli_mode()