Compare commits

...

10 Commits
v1.1 ... master

Author SHA1 Message Date
39f55c1b37 Fix for logging 2022-10-02 01:53:32 +03:00
8cd4e59918 Add asyncio support 2022-10-01 13:41:08 +03:00
069a7d9356 Minor fixes 2022-10-01 13:40:54 +03:00
santaspeen
56c4212391 del sonar files 2022-02-27 21:07:16 +03:00
santaspeen
156fba7a88 Add preview 2022-02-27 21:05:46 +03:00
santaspeen
3892657558 Ignore Sonar 2022-02-27 18:51:00 +03:00
santaspeen
12408f841b Update README 2022-02-24 16:07:35 +03:00
santaspeen
3533c7ebbf Update README 2022-02-24 16:02:11 +03:00
SantaSpeen
88138b6cb5 Update README 2022-02-23 00:46:09 +03:00
SantaSpeen
575879459d Update README 2022-02-23 00:41:32 +03:00
7 changed files with 161 additions and 56 deletions

6
.gitignore vendored
View File

@ -128,4 +128,10 @@ dmypy.json
# Pyre type checker
.pyre/
# Ignore .idea
.idea/
# ignore Sonar
codecov
.scannerwork/

View File

@ -1,4 +1,11 @@
# CLI in Python
<p align="center">
<img src="https://img.shields.io/github/license/SantaSpeen/CLI-in-Python?style=for-the-badge" alt="license" title="license: MIT">
<img src="https://img.shields.io/github/issues/SantaSpeen/CLI-in-Python?style=for-the-badge" alt="issues">
<img src="./assets/magic_logo.svg" alt="magic">
<br/>
<img src="./assets/preview.png" alt="preview">
</p>
##### Версия для русских: [здесь](./README_RU.md)
@ -52,7 +59,7 @@ cli.write("cli.write")
# ]: cli.write
```
* With logging output usage
* With `logging` output usage
```python
from console import Console
@ -75,7 +82,7 @@ logging.info("Info log")
# ]: 2022-02-20 23:22:49,731 - root - INFO - Info log
```
* with `print()` and `console.log` output usage
* With `print()` and `console.log` output usage
```python
from console import Console
@ -113,3 +120,4 @@ Copy all from `builtins_fix.pyi` and insert into `builtins.pyi` at line `131` be
Used in:
* [Python-CLI-Game-Engine](https://github.com/SantaSpeen/Python-CLI-Game-Engine)
* [CLI-Remote-in-Python](https://github.com/SantaSpeen/CLI-Remote-in-Python)

View File

@ -1,4 +1,11 @@
# CLI in Python
<p align="center">
<img src="https://img.shields.io/github/license/SantaSpeen/CLI-in-Python?style=for-the-badge" alt="license" title="license: MIT">
<img src="https://img.shields.io/github/issues/SantaSpeen/CLI-in-Python?style=for-the-badge" alt="issues">
<img src="./assets/magic_logo.svg" alt="magic">
<br/>
<img src="./assets/preview.png" alt="preview">
</p>
## Консольная оболочка для программ на Python3
@ -50,7 +57,7 @@ cli.write("cli.write")
# ]: cli.write
```
* Использование вывода с logging
* Использование вывода с `logging`
```python
from console import Console
@ -73,7 +80,7 @@ logging.info("Info log")
# ]: 2022-02-20 23:22:49,731 - root - INFO - Info log
```
* Использование вывода с`print()` и `console.log`
* Использование вывода с `print()` и `console.log`
```python
from console import Console
@ -101,13 +108,14 @@ console << "<< log"
# ]: << log
```
Если вы используете IDE, можно обновить `builtins.pyi` используя `scr/builtins_fix.pyi`. <br/>
Скопируйте всё из `builtins_fix.pyi` и вставте в `builtins.pyi` на `131` линию, до `class type(object)`.
Если вы используете IDE, можно обновить `builtins.pyi`, что бы она не ругалась на отсутствие `console.*` используя `scr/builtins_fix.pyi`. <br/>
Скопируйте всё из `builtins_fix.pyi` и вставте в `builtins.pyi` на `131` линию, перед `class type(object)`.
## Ссылки
* [Мой Telegram](https://t.me/SantaSpeen "SantaSpeen"): https://t.me/SantaSpeen
Используемые в поектах:
Используемые в проектах:
* [Python-CLI-Game-Engine](https://github.com/SantaSpeen/Python-CLI-Game-Engine)
* [CLI-Remote-in-Python](https://github.com/SantaSpeen/CLI-Remote-in-Python)

40
assets/magic_logo.svg Normal file
View File

@ -0,0 +1,40 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="180.5" height="28" role="img" aria-label="MADE WITH: MAGIC">
<title>MADE WITH: MAGIC</title>
<g shape-rendering="crispEdges">
<rect width="100.25" height="28" fill="#555"/>
<rect x="100.25" width="80.25" height="28" fill="#fe7d37"/>
</g>
<g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="100">
<svg x="3"
y="4"
id="Capa_1"
height="20"
viewBox="0 0 512 512"
width="20"
xmlns="http://www.w3.org/2000/svg">
<g>
<path d="m395.82 182.616-188.72 188.72-12.91 1.72-9.35 20.54-34.31 34.31-11.01-.73-11.25 22.99-56.48 56.48c-2.93 2.93-6.77 4.39-10.61 4.39s-7.68-1.46-10.61-4.39l-22.62-22.62h-.01l-22.62-22.63c-5.86-5.86-5.86-15.36 0-21.22l77.63-77.63 16.6-7.03 5.66-15.23 34.31-34.31 14.84-4.92 7.42-17.34 167.57-167.57 33.24 33.24z" fill="#f66"/>
<path d="m395.82 116.146v66.47l-188.72 188.72-12.91 1.72-9.35 20.54-34.31 34.31-11.01-.73-11.25 22.99-56.48 56.48c-2.93 2.93-6.77 4.39-10.61 4.39s-7.68-1.46-10.61-4.39l-22.62-22.62 334.64-334.64z" fill="#e62e6b"/>
<path d="m506.61 209.006-69.14-69.13 43.05-88.38c2.8-5.75 1.65-12.65-2.88-17.17-4.52-4.53-11.42-5.68-17.17-2.88l-88.38 43.05-69.13-69.14c-4.35-4.35-10.92-5.6-16.56-3.16-5.65 2.45-9.23 8.09-9.04 14.24l2.86 90.45-85.37 57.83c-4.91 3.32-7.4 9.22-6.36 15.04 1.04 5.83 5.4 10.51 11.15 11.94l96.62 24.01 24.01 96.62c1.43 5.75 6.11 10.11 11.94 11.15.87.16 1.75.23 2.62.23 4.92 0 9.6-2.42 12.42-6.59l57.83-85.37 90.45 2.86c6.14.19 11.79-3.39 14.24-9.04 2.44-5.64 1.19-12.21-3.16-16.56z" fill="#fabe2c"/>
<path d="m296.26 215.706 24.01 96.62c1.43 5.75 6.11 10.11 11.94 11.15.87.16 1.75.23 2.62.23 4.92 0 9.6-2.42 12.42-6.59l57.83-85.37 90.45 2.86c6.14.19 11.79-3.39 14.24-9.04 2.44-5.64 1.19-12.21-3.16-16.56l-69.14-69.13 43.05-88.38c2.8-5.75 1.65-12.65-2.88-17.17z" fill="#fd9025"/>
<path d="m465 416.966c-25.92 0-47 21.08-47 47s21.08 47 47 47 47-21.08 47-47-21.08-47-47-47z" fill="#fabe2c"/>
<path d="m104 28.966h-13v-13c0-8.284-6.716-15-15-15s-15 6.716-15 15v13h-13c-8.284 0-15 6.716-15 15s6.716 15 15 15h13v13c0 8.284 6.716 15 15 15s15-6.716 15-15v-13h13c8.284 0 15-6.716 15-15s-6.716-15-15-15z" fill="#fed843"/>
<path d="m207.1 371.336-22.26 22.26-45.32-87.62 22.26-22.26z" fill="#fed843"/>
<path d="m184.84 393.596 22.26-22.26-22.66-43.81-22.265 22.265z" fill="#fabe2c"/>
<path d="m150.53 427.906-22.26 22.26-45.32-87.62 22.26-22.26z" fill="#fed843"/>
<path d="m128.27 450.166 22.26-22.26-22.655-43.815-22.26 22.26z" fill="#fabe2c"/>
<circle cx="15" cy="119.969" fill="#5ed8d3" r="15"/>
<circle cx="128" cy="199.969" fill="#d599ed" r="15"/>
<circle cx="192" cy="63.964" fill="#f66" r="15"/>
<circle cx="328" cy="415.967" fill="#31bebe" r="15"/>
<circle cx="440" cy="327.967" fill="#ad77e3" r="14.999"/>
</g>
</svg>
<text transform="scale(.1)" x="600.25" y="175" textLength="590.5" fill="#fff">
MAGIC BY
</text>
<text transform="scale(.1)" x="1400.75" y="175" textLength="700.5" fill="#fff" font-weight="bold">
SantaSpeen
</text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.4 KiB

BIN
assets/preview.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 177 KiB

View File

@ -2,17 +2,23 @@
# Developed by Ahegao Devs
# Written by: SantaSpeen
# Version 1.1
# Version 2.1
# Licence: MIT
# (c) ahegao.ovh 2022
# (c) ahegao.su 2022
import builtins
import logging
import sys
import traceback
import asyncio
from builtins import RecursionError
from typing import AnyStr
try:
from aioconsole import ainput
except ImportError:
ainput = None
class ConsoleIO:
@ -33,11 +39,12 @@ class ConsoleIO:
class Console:
def __init__(self,
prompt_in: str = ">",
prompt_out: str = "]:",
not_found: str = "Command \"%s\" not found in alias.",
file: str or None = ConsoleIO,
debug: bool = False) -> None:
prompt_in=">",
prompt_out="]:",
not_found="Command \"%s\" not found in alias.",
file=ConsoleIO,
debug=False,
async_loop=None) -> None:
"""
def __init__(self,
prompt_in: str = ">",
@ -66,6 +73,8 @@ class Console:
self.is_run = False
self.async_loop = async_loop
self.get_IO = ConsoleIO
def __debug(self, *x):
@ -78,13 +87,14 @@ class Console:
print(item)
def __get_max_len(self, arg) -> int:
@staticmethod
def __get_max_len(arg) -> int:
i = 0
arg = list(arg)
for a in arg:
l = len(str(a))
if l > i:
i = l
ln = len(str(a))
if ln > i:
i = ln
return i
def __create_man_message(self, argv: list) -> AnyStr:
@ -101,6 +111,7 @@ class Console:
""" Print help message and alias of console commands"""
self.__debug("creating help message")
raw = False
max_len_v = 0
if "--raw" in argv:
max_len_v = self.__get_max_len(self.__alias.values())
print()
@ -114,17 +125,15 @@ class Console:
if not raw:
message += f"%{max_len}s : Help message\n" % "Command"
else:
message += f"%-{max_len - len(self.__prompt_out)-1}s; %-{max_len_v}s; __doc__\n" % ("Key", "Object")
message += f"%-{max_len - len(self.__prompt_out) - 1}s; %-{max_len_v}s; __doc__\n" % ("Key", "Object")
for k, v in self.__alias.items():
doc = v['f'].__doc__
if raw:
message += f"%-{max_len}s; %-{max_len_v}s; %s\n" % (k, v, doc)
else:
if doc is None:
doc = " No help message found"
message += f" %{max_len}s :%s\n" % (k, doc)
@ -206,11 +215,14 @@ class Console:
def emit(cls, record):
try:
msg = cls.format(record)
if cls.stream.name == "<stderr>":
ConsoleIO.write(self.__create_message(msg))
else:
cls.stream.write(msg + cls.terminator)
cls.flush()
except RecursionError:
raise
except Exception:
except Exception as e:
cls.handleError(record)
logging.StreamHandler.emit = emit
@ -227,25 +239,8 @@ class Console:
builtins.print = self.__builtins_print
def run(self) -> None:
"""
def run(self) -> None:
:return: None
"""
self.is_run = True
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:
def _cli_logic(self, cmd_in):
try:
ConsoleIO.write("\r" + self.__prompt_in + " ")
cmd_in = ConsoleIO.read()
cmd = cmd_in.split(" ")[0]
if cmd == "":
pass
@ -266,3 +261,48 @@ class Console:
ConsoleIO.write_err("\rDuring the execution of the command, an error occurred:\n\n" +
str(traceback.format_exc()) +
"\nType Enter to continue.")
def run(self) -> None:
"""
def run(self) -> None:
:return: None
"""
self.is_run = True
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:
ConsoleIO.write("\r" + self.__prompt_in + " ")
self._cli_logic(ConsoleIO.read())
async def async_run(self) -> None:
"""
def async_run(self) -> None:
:return: None
"""
self.is_run = True
await self.async_run_while(True)
async def async_run_while(self, whl) -> None:
"""
async def async_run_while(self, whl) -> None:
:param whl: run while what?
:return: None
"""
if ainput is None:
print("Install aioconsole for async! pip install aioconsole")
exit(1)
if self.async_loop is None:
self.async_loop = asyncio.get_event_loop()
self.__debug(f"async run while {whl}")
reader = asyncio.StreamReader()
while whl:
ConsoleIO.write("\r" + self.__prompt_in + " ")
res = await ainput()
self._cli_logic(res)

View File

@ -6,8 +6,8 @@
# (c) ahegao.ovh 2022
from _typeshed import SupportsWrite
from builtins import function
from typing import AnyStr
from asyncio import AbstractEventLoop
from typing import AnyStr, NoReturn
class ConsoleIO:
@ -29,7 +29,8 @@ class Console(object):
prompt_out: str = "]:",
not_found: str = "Command \"%s\" not found in alias.",
file: SupportsWrite[str] or None = Console,
debug: bool = False) -> None:
debug: bool = False,
async_loop: AbstractEventLoop = None) -> NoReturn:
self.get_IO: ConsoleIO = ConsoleIO
self.is_run: bool = False
@ -38,11 +39,13 @@ class Console(object):
@property
def alias(self) -> dict: ...
def add(self, key: str, func, argv: bool = False, man: str = "No have manual message") -> dict:...
def log(self, s: AnyStr, r='\r') -> None: ...
def __lshift__(self, s: AnyStr) -> None:
def log(self, s: AnyStr, r='\r') -> NoReturn: ...
def __lshift__(self, s: AnyStr) -> NoReturn:
self.write(s)
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:...
def write(self, s: AnyStr, r='\r') -> NoReturn: ...
def logger_hook(self) -> NoReturn: ...
def builtins_hook(self) -> NoReturn: ...
def run(self) -> NoReturn: ...
def run_while(self, whl) -> NoReturn:...
async def async_run(self) -> NoReturn: ...
async def async_run_while(self, whl) -> NoReturn: ...