From 2e7e3ca82bbc7778cbe3a347c7c79c559200e99f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82?= Date: Sun, 14 Nov 2021 14:25:09 +0300 Subject: [PATCH 1/7] feat: preparing for PyPI publication & single command configuration - add `rich` console - create app_config.py and Config class - add required files for PyPI - rename utils.py --- .gitignore | 6 +++-- app/app_config.py | 36 +++++++++++++++++++++++++++++ app/cli.py | 9 ++++++++ app/console.py | 3 +++ app/handlers/__init__.py | 2 +- app/handlers/{uitls.py => utils.py} | 1 - pyproject.toml | 6 +++++ requirements.txt | 1 + setup.cfg | 29 +++++++++++++++++++++++ 9 files changed, 89 insertions(+), 4 deletions(-) create mode 100644 app/app_config.py create mode 100644 app/cli.py create mode 100644 app/console.py rename app/handlers/{uitls.py => utils.py} (99%) create mode 100644 pyproject.toml create mode 100644 setup.cfg diff --git a/.gitignore b/.gitignore index 2601d62..0b698da 100644 --- a/.gitignore +++ b/.gitignore @@ -3,9 +3,11 @@ venv/ **/__pycache__/ +dist/ +*.egg-info + *.session *.session-journal - data/ - config.py +config.yaml diff --git a/app/app_config.py b/app/app_config.py new file mode 100644 index 0000000..f63b1f6 --- /dev/null +++ b/app/app_config.py @@ -0,0 +1,36 @@ +import os +from typing import Optional + +import yaml + +from app.console import console +from app.utils import get_base_dir + +from pydantic import BaseModel + + +class Config(BaseModel): + api_id: Optional[int] + api_hash: Optional[str] + phone: Optional[str] + + +def load_config(): + config_filename = os.path.join(get_base_dir(), 'config.yaml') + try: + with open(config_filename) as file: + config_dict = yaml.safe_load(file) + except FileNotFoundError: + config_dict = {} + + config = Config(**config_dict) + + if not (config.api_id and config.api_hash and config.phone): + config.api_id = console.input('api_id: ') + config.api_hash = console.input('api_hash: ') + config.phone = console.input('phone: ') + + with open(config_filename, 'w') as file: + yaml.safe_dump(config.dict(), file) + + return config diff --git a/app/cli.py b/app/cli.py new file mode 100644 index 0000000..b60b36f --- /dev/null +++ b/app/cli.py @@ -0,0 +1,9 @@ +import sys + + +def main(): + cmd = sys.argv[1] + if cmd == 'run': + return 'Run' + else: + return 'Unknown command' diff --git a/app/console.py b/app/console.py new file mode 100644 index 0000000..a9463af --- /dev/null +++ b/app/console.py @@ -0,0 +1,3 @@ +from rich.console import Console + +console = Console() diff --git a/app/handlers/__init__.py b/app/handlers/__init__.py index 3e98fcb..3378fe4 100644 --- a/app/handlers/__init__.py +++ b/app/handlers/__init__.py @@ -2,7 +2,7 @@ from telethon.tl.custom import Message from app import client, message_design -from app.handlers.uitls import _handle_errors, outgoing_messages_filter +from app.handlers.utils import _handle_errors, outgoing_messages_filter from app.run_code.parse_code import parse_code from app.run_code import eval_message, get_kwargs diff --git a/app/handlers/uitls.py b/app/handlers/utils.py similarity index 99% rename from app/handlers/uitls.py rename to app/handlers/utils.py index 394106a..43ca749 100644 --- a/app/handlers/uitls.py +++ b/app/handlers/utils.py @@ -18,4 +18,3 @@ async def result(message: Message): def outgoing_messages_filter(m: Message): return m.out and not m.forward and not m.via_bot - diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..374b58c --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,6 @@ +[build-system] +requires = [ + "setuptools>=42", + "wheel" +] +build-backend = "setuptools.build_meta" diff --git a/requirements.txt b/requirements.txt index 61c88d0..559cacc 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,3 +3,4 @@ cryptg==0.2.post4 PyYAML==6.0 pydantic==1.8.2 aiorun==2021.10.1 +rich~=10.12.0 \ No newline at end of file diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..865b22b --- /dev/null +++ b/setup.cfg @@ -0,0 +1,29 @@ +[metadata] +name = tgpy +version = 0.1.0 +description = Run Python code right in your Telegram messages +long_description = file: README.md +long_description_content_type = text/markdown +url = https://github.com/tm-a-t/TGPy/ +project_urls = + Guide = https://tgpy.tmat.me/ +classifiers = + Programming Language :: Python :: 3 + License :: OSI Approved :: MIT License + Operating System :: OS Independent + +[options] +packages = app +python_requires = >=3.9 +install_requires= + Telethon~=1.23.0 + cryptg==0.2.post4 + PyYAML==6.0 + pydantic==1.8.2 + aiorun==2021.10.1 + rich~=10.12.0 + + +[options.entry_points] +console_scripts = + tgpy = app.cli:main From ae9bd176e33b9f325beb8949685a1f07b64095b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82?= Date: Sun, 14 Nov 2021 15:00:08 +0300 Subject: [PATCH 2/7] feat: App object and config loading Load config before setting Telethon client. --- app/__init__.py | 31 +++++++++++++++----- app/__main__.py | 6 ++-- app/handlers/__init__.py | 61 ++++++++++++++++++++-------------------- app/hooks.py | 4 +-- app/message_design.py | 4 +-- app/run_code/__init__.py | 6 ++-- 6 files changed, 63 insertions(+), 49 deletions(-) diff --git a/app/__init__.py b/app/__init__.py index 64b2aae..ad93857 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -1,20 +1,37 @@ import getpass import logging +import aiorun from telethon import TelegramClient -import config +from app.app_config import load_config logging.basicConfig(format='{levelname}: {message}', style='{', level=logging.INFO) -client = TelegramClient('TGPy', config.api_id, config.api_hash) -client.parse_mode = 'html' -from app import handlers +class App: + config = None + client = None + + +app = App() + +from app.handlers import set_handlers from app.hooks import HookType, Hook -async def main(): - await client.start(config.phone, password=lambda: getpass.getpass('2FA password: ')) +async def run_client(): + await app.client.start(app.config.phone, password=lambda: getpass.getpass('2FA password: ')) await Hook.run_hooks(HookType.onstart) - await client.run_until_disconnected() + await app.client.run_until_disconnected() + + +def main(): + app.config = load_config() + + app.client = TelegramClient('TGPy', app.config.api_id, app.config.api_hash) + app.client.parse_mode = 'html' + + set_handlers() + + aiorun.run(run_client(), loop=app.client.loop, stop_on_unhandled_errors=True) diff --git a/app/__main__.py b/app/__main__.py index 74f617f..7ddb166 100644 --- a/app/__main__.py +++ b/app/__main__.py @@ -1,5 +1,3 @@ -import aiorun +from app import main -from app import main, client - -aiorun.run(main(), loop=client.loop, stop_on_unhandled_errors=True) +main() \ No newline at end of file diff --git a/app/handlers/__init__.py b/app/handlers/__init__.py index 3378fe4..c74df9b 100644 --- a/app/handlers/__init__.py +++ b/app/handlers/__init__.py @@ -1,7 +1,7 @@ from telethon import events from telethon.tl.custom import Message -from app import client, message_design +from app import app, message_design from app.handlers.utils import _handle_errors, outgoing_messages_filter from app.run_code.parse_code import parse_code from app.run_code import eval_message, get_kwargs @@ -26,36 +26,35 @@ async def handle_message(message: Message) -> None: await eval_message(raw_text, message, uses_orig=res.uses_orig) -@client.on(events.NewMessage(func=outgoing_messages_filter)) -@_handle_errors -async def on_new_message(event: events.NewMessage.Event) -> None: - await handle_message(event.message) - - -@client.on(events.MessageEdited(func=outgoing_messages_filter)) -@_handle_errors -async def on_message_edited(event: events.NewMessage.Event) -> None: - code = message_design.get_code(event.message) - if not code: +def set_handlers(): + @app.client.on(events.NewMessage(func=outgoing_messages_filter)) + @_handle_errors + async def on_new_message(event: events.NewMessage.Event) -> None: await handle_message(event.message) - return - await eval_message(code, event.message, uses_orig=parse_code(code, get_kwargs()).uses_orig) - -@client.on(events.NewMessage(pattern='^(cancel|сфтсуд)$', func=outgoing_messages_filter)) -async def cancel(message: Message): - prev = await message.get_reply_message() - if not prev: - async for msg in client.iter_messages(message.chat_id, max_id=message.id, limit=10): - if msg.out and message_design.get_code(msg): - prev = msg - break - else: + @app.client.on(events.MessageEdited(func=outgoing_messages_filter)) + @_handle_errors + async def on_message_edited(event: events.NewMessage.Event) -> None: + code = message_design.get_code(event.message) + if not code: + await handle_message(event.message) return - # noinspection PyBroadException - try: - await prev.edit(message_design.get_code(prev)) - except Exception: - pass - else: - await message.delete() + await eval_message(code, event.message, uses_orig=parse_code(code, get_kwargs()).uses_orig) + + @app.client.on(events.NewMessage(pattern='^(cancel|сфтсуд)$', func=outgoing_messages_filter)) + async def cancel(message: Message): + prev = await message.get_reply_message() + if not prev: + async for msg in client.iter_messages(message.chat_id, max_id=message.id, limit=10): + if msg.out and message_design.get_code(msg): + prev = msg + break + else: + return + # noinspection PyBroadException + try: + await prev.edit(message_design.get_code(prev)) + except Exception: + pass + else: + await message.delete() diff --git a/app/hooks.py b/app/hooks.py index ca6c07b..95cfcc9 100644 --- a/app/hooks.py +++ b/app/hooks.py @@ -7,7 +7,7 @@ import yaml from pydantic import BaseModel -from app import client +from app import app from app.run_code import meval from app.run_code.variables import variables from app.run_code.utils import format_traceback @@ -88,7 +88,7 @@ async def run(self): self.origin, globals(), variables, - client=client, + client=app.client, msg=None, ctx=variables['ctx'], print=lambda *args, **kwargs: None, diff --git a/app/message_design.py b/app/message_design.py index 6e7a704..e91fb39 100644 --- a/app/message_design.py +++ b/app/message_design.py @@ -4,7 +4,7 @@ from telethon.tl.custom import Message from telethon.tl.types import MessageEntityTextUrl, MessageEntityCode, MessageEntityBold -from app import client +from app import app TITLE = 'TGPy>' TITLE_URL = 'https://github.com/tm-a-t/TGPy' @@ -49,4 +49,4 @@ async def send_error(chat) -> None: exc = ''.join(tb.format_exception(*sys.exc_info())) if len(exc) > 4000: exc = exc[:4000] + '…' - await client.send_message(chat, f'{ERROR_TITLE_FORMATTED}\n\n{exc}', link_preview=False) + await app.client.send_message(chat, f'{ERROR_TITLE_FORMATTED}\n\n{exc}', link_preview=False) diff --git a/app/run_code/__init__.py b/app/run_code/__init__.py index e601968..ccfc4b8 100644 --- a/app/run_code/__init__.py +++ b/app/run_code/__init__.py @@ -1,7 +1,7 @@ from telethon.errors import MessageIdInvalidError from telethon.tl.custom import Message -from app import client +from app import app from app import message_design from app.run_code.meval import meval from app.run_code.utils import Output, convert_result, filename_prefix, format_traceback @@ -31,7 +31,7 @@ async def eval_message(code: str, message: Message, uses_orig=False) -> None: f'{filename_prefix}message/{message.chat_id}/{message.id}', globals(), variables, - client=client, + client=app.client, msg=message, ctx=variables['ctx'], print=output.print, @@ -51,4 +51,4 @@ async def eval_message(code: str, message: Message, uses_orig=False) -> None: pass -import app.run_code.builtin_functions +from app.run_code import builtin_functions From f440ea42e2e98a16442f6c5b563f5d37ad11e771 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82?= Date: Sun, 14 Nov 2021 16:19:55 +0300 Subject: [PATCH 3/7] feat: pretty cli setup and logs --- app/__init__.py | 11 ++++++++--- app/app_config.py | 30 +++++++++++++++++++++++++----- app/console.py | 5 +++-- 3 files changed, 36 insertions(+), 10 deletions(-) diff --git a/app/__init__.py b/app/__init__.py index ad93857..6c477c5 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -1,12 +1,15 @@ -import getpass import logging import aiorun from telethon import TelegramClient from app.app_config import load_config +from app.console import console +from rich.logging import RichHandler -logging.basicConfig(format='{levelname}: {message}', style='{', level=logging.INFO) + +logging.basicConfig(level=logging.INFO, format='%(message)s', datefmt="[%X]", handlers=[RichHandler()]) +log = logging.getLogger('rich') class App: @@ -21,7 +24,9 @@ class App: async def run_client(): - await app.client.start(app.config.phone, password=lambda: getpass.getpass('2FA password: ')) + log.info('Starting TGPy...') + await app.client.start(app.config.phone, password=lambda: console.input('2FA password: ', password=True)) + log.info('[bold]TGPy is running!', extra={'markup': True}) await Hook.run_hooks(HookType.onstart) await app.client.run_until_disconnected() diff --git a/app/app_config.py b/app/app_config.py index f63b1f6..1376e51 100644 --- a/app/app_config.py +++ b/app/app_config.py @@ -1,3 +1,4 @@ +import logging import os from typing import Optional @@ -6,7 +7,7 @@ from app.console import console from app.utils import get_base_dir -from pydantic import BaseModel +from pydantic import BaseModel, ValidationError class Config(BaseModel): @@ -23,12 +24,31 @@ def load_config(): except FileNotFoundError: config_dict = {} - config = Config(**config_dict) + try: + config = Config(**config_dict) + except ValidationError: + config = Config() if not (config.api_id and config.api_hash and config.phone): - config.api_id = console.input('api_id: ') - config.api_hash = console.input('api_hash: ') - config.phone = console.input('phone: ') + console.print('[bold on bright_cyan] Welcome to TGPy ') + console.print('Starting setup...') + console.print() + console.print('[bold on white] Step 1 of 2 ') + console.print( + '│ TGPy uses Telegram API, so you\'ll need to register your Telegram app.\n' + '│ [cyan]1.[/] Go to https://my.telegram.org\n' + '│ [cyan]2.[/] Login with your Telegram account\n' + '│ [cyan]3.[/] Go to "API development tools"\n' + '│ [cyan]4.[/] Create your app. Choose any app title and short_title. You can leave other fields empty.\n' + '│ You will get api_id and api_hash.' + ) + config.api_id = console.input('│ Please enter api_id: ') + config.api_hash = console.input('│ ...and api_hash: ') + console.print() + console.print('[bold on white] Step 2 of 2 ') + console.print('│ Now login to Telegram.') + config.phone = console.input('│ Please enter your phone: ') + console.print() with open(config_filename, 'w') as file: yaml.safe_dump(config.dict(), file) diff --git a/app/console.py b/app/console.py index a9463af..9e30387 100644 --- a/app/console.py +++ b/app/console.py @@ -1,3 +1,4 @@ -from rich.console import Console +from rich.console import Console, Theme -console = Console() +theme = Theme(inherit=False) +console = Console(theme=theme) From 10e028596f45fb67fac70f7a23fa34a9003884c0 Mon Sep 17 00:00:00 2001 From: vanutp Date: Sun, 21 Nov 2021 20:05:40 +0300 Subject: [PATCH 4/7] fix: convert old config --- app/app_config.py | 8 +++----- app/utils.py | 19 +++++++++++++++++-- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/app/app_config.py b/app/app_config.py index 5699598..ba03110 100644 --- a/app/app_config.py +++ b/app/app_config.py @@ -1,11 +1,10 @@ -import os from typing import Optional import yaml from pydantic import BaseModel, ValidationError from app.console import console -from app.utils import BASE_DIR +from app.utils import CONFIG_FILENAME class Config(BaseModel): @@ -15,9 +14,8 @@ class Config(BaseModel): def load_config(): - config_filename = os.path.join(BASE_DIR, 'config.yaml') try: - with open(config_filename) as file: + with open(CONFIG_FILENAME) as file: config_dict = yaml.safe_load(file) except FileNotFoundError: config_dict = {} @@ -48,7 +46,7 @@ def load_config(): config.phone = console.input('│ Please enter your phone: ') console.print() - with open(config_filename, 'w') as file: + with open(CONFIG_FILENAME, 'w') as file: yaml.safe_dump(config.dict(), file) return config diff --git a/app/utils.py b/app/utils.py index e42a26a..4334332 100644 --- a/app/utils.py +++ b/app/utils.py @@ -4,6 +4,8 @@ from pathlib import Path from subprocess import Popen, PIPE +import yaml +from pydantic import ValidationError from yaml.representer import SafeRepresenter BASE_DIR = Path(__file__).parent.parent @@ -13,12 +15,25 @@ HOOKS_DIR.mkdir(exist_ok=True) WORKDIR = DATA_DIR / 'workdir' WORKDIR.mkdir(exist_ok=True) +CONFIG_FILENAME = BASE_DIR / 'config.yaml' def migrate_from_old_versions(): + from app.app_config import Config + old_session_file = BASE_DIR / 'TGPy.session' if old_session_file.exists(): old_session_file.rename(DATA_DIR / 'TGPy.session') + old_config_file = BASE_DIR / 'config.py' + if old_config_file.exists(): + try: + config_mod = importlib.import_module('config') + config = Config(api_id=config_mod.api_id, api_hash=config_mod.api_hash, phone=config_mod.phone) + with open(CONFIG_FILENAME, 'w') as file: + yaml.safe_dump(config.dict(), file) + except (ValidationError, AttributeError, ImportError): + pass + old_config_file.unlink() def _multiline_presenter(dumper, data): @@ -72,5 +87,5 @@ def get_version(): return 'unknown' -__all__ = ['BASE_DIR', 'DATA_DIR', 'HOOKS_DIR', 'WORKDIR', 'yaml_multiline_str', 'run_cmd', 'get_version', - 'migrate_from_old_versions'] +__all__ = ['BASE_DIR', 'DATA_DIR', 'HOOKS_DIR', 'WORKDIR', 'CONFIG_FILENAME', 'yaml_multiline_str', 'run_cmd', + 'get_version', 'migrate_from_old_versions'] From 753369cf7f7e49a22403951a53b61df249d45def Mon Sep 17 00:00:00 2001 From: vanutp Date: Sun, 21 Nov 2021 21:46:30 +0300 Subject: [PATCH 5/7] continue working on setup script --- app/__init__.py | 33 ++-------------- app/__main__.py | 85 +++++++++++++++++++++++++++++++++++++++- app/app_config.py | 54 +++++++------------------ app/handlers/__init__.py | 71 ++++++++++++++++++--------------- app/utils.py | 15 +++---- 5 files changed, 148 insertions(+), 110 deletions(-) diff --git a/app/__init__.py b/app/__init__.py index 3b6f0be..559d599 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -1,44 +1,17 @@ import logging -import aiorun from rich.logging import RichHandler from telethon import TelegramClient -from app.app_config import load_config +from app.app_config import Config from app.console import console -from app.utils import DATA_DIR, migrate_from_old_versions logging.basicConfig(level=logging.INFO, format='%(message)s', datefmt="[%X]", handlers=[RichHandler()]) -log = logging.getLogger('rich') class App: - config = None - client = None + config: Config = None + client: TelegramClient = None app = App() - -from app.handlers import set_handlers -from app.hooks import HookType, Hook - - -async def run_client(): - log.info('Starting TGPy...') - await app.client.start(app.config.phone, password=lambda: console.input('2FA password: ', password=True)) - log.info('[bold]TGPy is running!', extra={'markup': True}) - await Hook.run_hooks(HookType.onstart) - await app.client.run_until_disconnected() - - -def main(): - migrate_from_old_versions() - - app.config = load_config() - - app.client = TelegramClient(str(DATA_DIR / 'TGPy'), app.config.api_id, app.config.api_hash) - app.client.parse_mode = 'html' - - set_handlers() - - aiorun.run(run_client(), loop=app.client.loop, stop_on_unhandled_errors=True) diff --git a/app/__main__.py b/app/__main__.py index 7ddb166..16e17cf 100644 --- a/app/__main__.py +++ b/app/__main__.py @@ -1,3 +1,84 @@ -from app import main +import logging -main() \ No newline at end of file +import aiorun +from telethon import TelegramClient, errors + +from app import app, Config +from app.console import console +from app.handlers import add_handlers +from app.hooks import HookType, Hook +from app.utils import migrate_from_old_versions, SESSION_FILENAME + +log = logging.getLogger(__name__) + + +def create_client(): + client = TelegramClient(str(SESSION_FILENAME), app.config.api_id, app.config.api_hash) + client.parse_mode = 'html' + return client + + +async def start_client(): + await app.client.start( + phone=lambda: console.input('| Please enter your phone number: '), + code_callback=lambda: console.input('| Please enter the code you received: '), + password=lambda: console.input('| Please enter your 2FA password: ', password=True), + ) + + +async def initial_setup(): + console.print('[bold on bright_cyan] Welcome to TGPy ') + console.print('Starting setup...') + console.print() + console.print('[bold black on white] Step 1 of 2 ') + console.print( + '│ TGPy uses Telegram API, so you\'ll need to register your Telegram app.\n' + '│ [cyan]1.[/] Go to https://my.telegram.org\n' + '│ [cyan]2.[/] Login with your Telegram account\n' + '│ [cyan]3.[/] Go to "API development tools"\n' + '│ [cyan]4.[/] Create your app. Choose any app title and short_title. You can leave other fields empty.\n' + '│ You will get api_id and api_hash.' + ) + success = False + while not success: + app.config.api_id = console.input('│ Please enter api_id: ') + app.config.api_hash = console.input('│ ...and api_hash: ') + try: + app.client = create_client() + console.print() + console.print('[bold black on white] Step 2 of 2 ') + console.print('│ Now login to Telegram.') + await app.client.connect() + await start_client() + success = True + except (errors.ApiIdInvalidError, errors.ApiIdPublishedFloodError, ValueError): + console.print('│ [bold on red]Incorrect api_id/api_hash, try again') + finally: + if app.client: + await app.client.disconnect() + console.print('│ Login successful!') + app.config.save() + + +async def run_client(): + log.info('Starting TGPy...') + await start_client() + log.info('[bold]TGPy is running!', extra={'markup': True}) + await Hook.run_hooks(HookType.onstart) + await app.client.run_until_disconnected() + + +async def main(): + migrate_from_old_versions() + + app.config = Config.load() + if not (app.config.api_id and app.config.api_hash): + await initial_setup() + else: + app.client = create_client() + + add_handlers() + await run_client() + + +aiorun.run(main(), stop_on_unhandled_errors=True) diff --git a/app/app_config.py b/app/app_config.py index ba03110..55a5ed9 100644 --- a/app/app_config.py +++ b/app/app_config.py @@ -3,50 +3,26 @@ import yaml from pydantic import BaseModel, ValidationError -from app.console import console from app.utils import CONFIG_FILENAME class Config(BaseModel): api_id: Optional[int] api_hash: Optional[str] - phone: Optional[str] - - -def load_config(): - try: - with open(CONFIG_FILENAME) as file: - config_dict = yaml.safe_load(file) - except FileNotFoundError: - config_dict = {} - - try: - config = Config(**config_dict) - except ValidationError: - config = Config() - - if not (config.api_id and config.api_hash and config.phone): - console.print('[bold on bright_cyan] Welcome to TGPy ') - console.print('Starting setup...') - console.print() - console.print('[bold on white] Step 1 of 2 ') - console.print( - '│ TGPy uses Telegram API, so you\'ll need to register your Telegram app.\n' - '│ [cyan]1.[/] Go to https://my.telegram.org\n' - '│ [cyan]2.[/] Login with your Telegram account\n' - '│ [cyan]3.[/] Go to "API development tools"\n' - '│ [cyan]4.[/] Create your app. Choose any app title and short_title. You can leave other fields empty.\n' - '│ You will get api_id and api_hash.' - ) - config.api_id = console.input('│ Please enter api_id: ') - config.api_hash = console.input('│ ...and api_hash: ') - console.print() - console.print('[bold on white] Step 2 of 2 ') - console.print('│ Now login to Telegram.') - config.phone = console.input('│ Please enter your phone: ') - console.print() + @classmethod + def load(cls): + try: + with open(CONFIG_FILENAME) as file: + config_dict = yaml.safe_load(file) + except FileNotFoundError: + config_dict = {} + try: + config = cls(**config_dict) + except ValidationError: + config = cls() + return config + + def save(self): with open(CONFIG_FILENAME, 'w') as file: - yaml.safe_dump(config.dict(), file) - - return config + yaml.safe_dump(self.dict(), file) diff --git a/app/handlers/__init__.py b/app/handlers/__init__.py index fa63357..b254a52 100644 --- a/app/handlers/__init__.py +++ b/app/handlers/__init__.py @@ -4,8 +4,8 @@ from app import app, message_design from app.handlers.utils import _handle_errors, outgoing_messages_filter -from app.run_code.parse_code import parse_code from app.run_code import eval_message, get_kwargs +from app.run_code.parse_code import parse_code async def handle_message(message: Message) -> None: @@ -27,37 +27,44 @@ async def handle_message(message: Message) -> None: await eval_message(raw_text, message, uses_orig=res.uses_orig) -def set_handlers(): - @app.client.on(events.NewMessage(func=outgoing_messages_filter)) - @_handle_errors - async def on_new_message(event: events.NewMessage.Event) -> None: +@events.register(events.NewMessage(func=outgoing_messages_filter)) +@_handle_errors +async def on_new_message(event: events.NewMessage.Event) -> None: + await handle_message(event.message) + + +@events.register(events.MessageEdited(func=outgoing_messages_filter)) +@_handle_errors +async def on_message_edited(event: events.NewMessage.Event) -> None: + if isinstance(event.message.chat, Channel) and event.message.chat.broadcast: + return + code = message_design.get_code(event.message) + if not code: await handle_message(event.message) + return + await eval_message(code, event.message, uses_orig=parse_code(code, get_kwargs()).uses_orig) - @app.client.on(events.MessageEdited(func=outgoing_messages_filter)) - @_handle_errors - async def on_message_edited(event: events.NewMessage.Event) -> None: - if isinstance(event.message.chat, Channel) and event.message.chat.broadcast: - return - code = message_design.get_code(event.message) - if not code: - await handle_message(event.message) - return - await eval_message(code, event.message, uses_orig=parse_code(code, get_kwargs()).uses_orig) - - @app.client.on(events.NewMessage(pattern='(?i)^(cancel|сфтсуд)$', func=outgoing_messages_filter)) - async def cancel(message: Message): - prev = await message.get_reply_message() - if not prev: - async for msg in client.iter_messages(message.chat_id, max_id=message.id, limit=10): - if msg.out and message_design.get_code(msg): - prev = msg - break - else: - return - # noinspection PyBroadException - try: - await prev.edit(message_design.get_code(prev)) - except Exception: - pass + +@events.register(events.NewMessage(pattern='(?i)^(cancel|сфтсуд)$', func=outgoing_messages_filter)) +async def cancel(message: Message): + prev = await message.get_reply_message() + if not prev: + async for msg in app.client.iter_messages(message.chat_id, max_id=message.id, limit=10): + if msg.out and message_design.get_code(msg): + prev = msg + break else: - await message.delete() + return + # noinspection PyBroadException + try: + await prev.edit(message_design.get_code(prev)) + except Exception: + pass + else: + await message.delete() + + +def add_handlers(): + app.client.add_event_handler(on_new_message) + app.client.add_event_handler(on_message_edited) + app.client.add_event_handler(cancel) diff --git a/app/utils.py b/app/utils.py index 4334332..6a34e8d 100644 --- a/app/utils.py +++ b/app/utils.py @@ -15,20 +15,21 @@ HOOKS_DIR.mkdir(exist_ok=True) WORKDIR = DATA_DIR / 'workdir' WORKDIR.mkdir(exist_ok=True) -CONFIG_FILENAME = BASE_DIR / 'config.yaml' +CONFIG_FILENAME = DATA_DIR / 'config.yml' +SESSION_FILENAME = DATA_DIR / 'TGPy.session' def migrate_from_old_versions(): from app.app_config import Config old_session_file = BASE_DIR / 'TGPy.session' - if old_session_file.exists(): - old_session_file.rename(DATA_DIR / 'TGPy.session') + if old_session_file.exists() and not SESSION_FILENAME.exists(): + old_session_file.rename(SESSION_FILENAME) old_config_file = BASE_DIR / 'config.py' - if old_config_file.exists(): + if old_config_file.exists() and not CONFIG_FILENAME.exists(): try: config_mod = importlib.import_module('config') - config = Config(api_id=config_mod.api_id, api_hash=config_mod.api_hash, phone=config_mod.phone) + config = Config(api_id=config_mod.api_id, api_hash=config_mod.api_hash) with open(CONFIG_FILENAME, 'w') as file: yaml.safe_dump(config.dict(), file) except (ValidationError, AttributeError, ImportError): @@ -87,5 +88,5 @@ def get_version(): return 'unknown' -__all__ = ['BASE_DIR', 'DATA_DIR', 'HOOKS_DIR', 'WORKDIR', 'CONFIG_FILENAME', 'yaml_multiline_str', 'run_cmd', - 'get_version', 'migrate_from_old_versions'] +__all__ = ['BASE_DIR', 'DATA_DIR', 'HOOKS_DIR', 'WORKDIR', 'CONFIG_FILENAME', 'SESSION_FILENAME', + 'yaml_multiline_str', 'run_cmd', 'get_version', 'migrate_from_old_versions'] From 263bbcca39b02f38d340262fcd5f34a648a5598c Mon Sep 17 00:00:00 2001 From: vanutp Date: Sat, 25 Dec 2021 22:11:03 +0300 Subject: [PATCH 6/7] build: switch to poetry, reanme package to tgpy, fix readme images --- README.md | 6 +- app/cli.py | 9 - guide/docs/installation.md | 2 +- poetry.lock | 365 ++++++++++++++++++++ pyproject.toml | 34 +- setup.cfg | 29 -- {app => tgpy}/__init__.py | 7 +- tgpy/__main__.py | 3 + {app => tgpy}/app_config.py | 2 +- {app => tgpy}/console.py | 0 {app => tgpy}/handlers/__init__.py | 8 +- {app => tgpy}/handlers/utils.py | 2 +- {app => tgpy}/hooks.py | 10 +- app/__main__.py => tgpy/main.py | 18 +- {app => tgpy}/message_design.py | 2 +- {app => tgpy}/run_code/__init__.py | 12 +- {app => tgpy}/run_code/builtin_functions.py | 14 +- {app => tgpy}/run_code/meval.py | 0 {app => tgpy}/run_code/parse_code.py | 0 {app => tgpy}/run_code/utils.py | 2 +- {app => tgpy}/run_code/variables.py | 0 {app => tgpy}/utils.py | 2 +- 22 files changed, 442 insertions(+), 85 deletions(-) delete mode 100644 app/cli.py create mode 100644 poetry.lock delete mode 100644 setup.cfg rename {app => tgpy}/__init__.py (74%) create mode 100644 tgpy/__main__.py rename {app => tgpy}/app_config.py (94%) rename {app => tgpy}/console.py (100%) rename {app => tgpy}/handlers/__init__.py (90%) rename {app => tgpy}/handlers/utils.py (93%) rename {app => tgpy}/hooks.py (93%) rename app/__main__.py => tgpy/main.py (89%) rename {app => tgpy}/message_design.py (98%) rename {app => tgpy}/run_code/__init__.py (82%) rename {app => tgpy}/run_code/builtin_functions.py (86%) rename {app => tgpy}/run_code/meval.py (100%) rename {app => tgpy}/run_code/parse_code.py (100%) rename {app => tgpy}/run_code/utils.py (95%) rename {app => tgpy}/run_code/variables.py (100%) rename {app => tgpy}/utils.py (98%) diff --git a/README.md b/README.md index a68ee79..05c3ac3 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -![TGPy](readme_assets/TGPy.png) +![TGPy](https://raw.githubusercontent.com/tm-a-t/TGPy/master/readme_assets/TGPy.png) ## Run Python code right in your Telegram messages @@ -8,7 +8,7 @@ Made with Telethon library, TGPy is a tool for evaluating expressions and Telegr - Interact with your messages and chats - Automate sending messages and more -![Example](readme_assets/example.gif) +![Example](https://raw.githubusercontent.com/tm-a-t/TGPy/master/readme_assets/example.gif) Just send Python code to any chat, and it will be executed. Change your message to change the result. @@ -92,7 +92,7 @@ async def delete(): 4. Install the requirements and run TGPy: ```shell > pip install -r requirements.txt - > python -m app + > python -m tgpy ``` 5. For the first time, you'll need to log in with a confirmation code from Telegram. diff --git a/app/cli.py b/app/cli.py deleted file mode 100644 index b60b36f..0000000 --- a/app/cli.py +++ /dev/null @@ -1,9 +0,0 @@ -import sys - - -def main(): - cmd = sys.argv[1] - if cmd == 'run': - return 'Run' - else: - return 'Unknown command' diff --git a/guide/docs/installation.md b/guide/docs/installation.md index 1c7823b..7fdc098 100644 --- a/guide/docs/installation.md +++ b/guide/docs/installation.md @@ -19,7 +19,7 @@ phone = ... 4. Install the requirements and run TGPy: ```shell $ pip install -r requirements.txt -$ python -m app +$ python -m tgpy ``` 5. For the first time, you'll have to log in with a confirmation code from Telegram. diff --git a/poetry.lock b/poetry.lock new file mode 100644 index 0000000..90f9ac4 --- /dev/null +++ b/poetry.lock @@ -0,0 +1,365 @@ +[[package]] +name = "aiorun" +version = "2021.10.1" +description = "Boilerplate for asyncio applications" +category = "main" +optional = false +python-versions = ">=3.5" + +[package.extras] +dev = ["pytest", "pytest-cov"] + +[[package]] +name = "cffi" +version = "1.15.0" +description = "Foreign Function Interface for Python calling C code." +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +pycparser = "*" + +[[package]] +name = "colorama" +version = "0.4.4" +description = "Cross-platform colored terminal text." +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[[package]] +name = "commonmark" +version = "0.9.1" +description = "Python parser for the CommonMark Markdown spec" +category = "main" +optional = false +python-versions = "*" + +[package.extras] +test = ["flake8 (==3.7.8)", "hypothesis (==3.55.3)"] + +[[package]] +name = "cryptg" +version = "0.2.post4" +description = "Cryptographic utilities for Telegram." +category = "main" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +cffi = ">=1.0.0" +pycparser = "*" + +[[package]] +name = "pyaes" +version = "1.6.1" +description = "Pure-Python Implementation of the AES block-cipher and common modes of operation" +category = "main" +optional = false +python-versions = "*" + +[[package]] +name = "pyasn1" +version = "0.4.8" +description = "ASN.1 types and codecs" +category = "main" +optional = false +python-versions = "*" + +[[package]] +name = "pycparser" +version = "2.21" +description = "C parser in Python" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[[package]] +name = "pydantic" +version = "1.8.2" +description = "Data validation and settings management using python 3.6 type hinting" +category = "main" +optional = false +python-versions = ">=3.6.1" + +[package.dependencies] +typing-extensions = ">=3.7.4.3" + +[package.extras] +dotenv = ["python-dotenv (>=0.10.4)"] +email = ["email-validator (>=1.0.3)"] + +[[package]] +name = "pygments" +version = "2.10.0" +description = "Pygments is a syntax highlighting package written in Python." +category = "main" +optional = false +python-versions = ">=3.5" + +[[package]] +name = "pyyaml" +version = "6.0" +description = "YAML parser and emitter for Python" +category = "main" +optional = false +python-versions = ">=3.6" + +[[package]] +name = "rich" +version = "10.16.1" +description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" +category = "main" +optional = false +python-versions = ">=3.6.2,<4.0.0" + +[package.dependencies] +colorama = ">=0.4.0,<0.5.0" +commonmark = ">=0.9.0,<0.10.0" +pygments = ">=2.6.0,<3.0.0" + +[package.extras] +jupyter = ["ipywidgets (>=7.5.1,<8.0.0)"] + +[[package]] +name = "rsa" +version = "4.8" +description = "Pure-Python RSA implementation" +category = "main" +optional = false +python-versions = ">=3.6,<4" + +[package.dependencies] +pyasn1 = ">=0.1.3" + +[[package]] +name = "telethon" +version = "1.24.0" +description = "Full-featured Telegram client library for Python 3" +category = "main" +optional = false +python-versions = ">=3.5" + +[package.dependencies] +pyaes = "*" +rsa = "*" + +[package.extras] +cryptg = ["cryptg"] + +[[package]] +name = "typing-extensions" +version = "4.0.1" +description = "Backported and Experimental Type Hints for Python 3.6+" +category = "main" +optional = false +python-versions = ">=3.6" + +[metadata] +lock-version = "1.1" +python-versions = "^3.9" +content-hash = "0a00ccf15f0d214e85b7a7df54d6584faf57601f1f313df041b904b368cf5432" + +[metadata.files] +aiorun = [ + {file = "aiorun-2021.10.1-py3-none-any.whl", hash = "sha256:49c3b0ca9aa4c8ace443691d31d3114ad7a3abe7af19abb13725309dec2e3c2c"}, + {file = "aiorun-2021.10.1.tar.gz", hash = "sha256:bb621493e008cd072a9b19de09a615513be2f48b594ee16ee726da5255fa4267"}, +] +cffi = [ + {file = "cffi-1.15.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:c2502a1a03b6312837279c8c1bd3ebedf6c12c4228ddbad40912d671ccc8a962"}, + {file = "cffi-1.15.0-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:23cfe892bd5dd8941608f93348c0737e369e51c100d03718f108bf1add7bd6d0"}, + {file = "cffi-1.15.0-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:41d45de54cd277a7878919867c0f08b0cf817605e4eb94093e7516505d3c8d14"}, + {file = "cffi-1.15.0-cp27-cp27m-win32.whl", hash = "sha256:4a306fa632e8f0928956a41fa8e1d6243c71e7eb59ffbd165fc0b41e316b2474"}, + {file = "cffi-1.15.0-cp27-cp27m-win_amd64.whl", hash = "sha256:e7022a66d9b55e93e1a845d8c9eba2a1bebd4966cd8bfc25d9cd07d515b33fa6"}, + {file = "cffi-1.15.0-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:14cd121ea63ecdae71efa69c15c5543a4b5fbcd0bbe2aad864baca0063cecf27"}, + {file = "cffi-1.15.0-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:d4d692a89c5cf08a8557fdeb329b82e7bf609aadfaed6c0d79f5a449a3c7c023"}, + {file = "cffi-1.15.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0104fb5ae2391d46a4cb082abdd5c69ea4eab79d8d44eaaf79f1b1fd806ee4c2"}, + {file = "cffi-1.15.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:91ec59c33514b7c7559a6acda53bbfe1b283949c34fe7440bcf917f96ac0723e"}, + {file = "cffi-1.15.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:f5c7150ad32ba43a07c4479f40241756145a1f03b43480e058cfd862bf5041c7"}, + {file = "cffi-1.15.0-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:00c878c90cb53ccfaae6b8bc18ad05d2036553e6d9d1d9dbcf323bbe83854ca3"}, + {file = "cffi-1.15.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:abb9a20a72ac4e0fdb50dae135ba5e77880518e742077ced47eb1499e29a443c"}, + {file = "cffi-1.15.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a5263e363c27b653a90078143adb3d076c1a748ec9ecc78ea2fb916f9b861962"}, + {file = "cffi-1.15.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f54a64f8b0c8ff0b64d18aa76675262e1700f3995182267998c31ae974fbc382"}, + {file = "cffi-1.15.0-cp310-cp310-win32.whl", hash = "sha256:c21c9e3896c23007803a875460fb786118f0cdd4434359577ea25eb556e34c55"}, + {file = "cffi-1.15.0-cp310-cp310-win_amd64.whl", hash = "sha256:5e069f72d497312b24fcc02073d70cb989045d1c91cbd53979366077959933e0"}, + {file = "cffi-1.15.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:64d4ec9f448dfe041705426000cc13e34e6e5bb13736e9fd62e34a0b0c41566e"}, + {file = "cffi-1.15.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2756c88cbb94231c7a147402476be2c4df2f6078099a6f4a480d239a8817ae39"}, + {file = "cffi-1.15.0-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b96a311ac60a3f6be21d2572e46ce67f09abcf4d09344c49274eb9e0bf345fc"}, + {file = "cffi-1.15.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75e4024375654472cc27e91cbe9eaa08567f7fbdf822638be2814ce059f58032"}, + {file = "cffi-1.15.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:59888172256cac5629e60e72e86598027aca6bf01fa2465bdb676d37636573e8"}, + {file = "cffi-1.15.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:27c219baf94952ae9d50ec19651a687b826792055353d07648a5695413e0c605"}, + {file = "cffi-1.15.0-cp36-cp36m-win32.whl", hash = "sha256:4958391dbd6249d7ad855b9ca88fae690783a6be9e86df65865058ed81fc860e"}, + {file = "cffi-1.15.0-cp36-cp36m-win_amd64.whl", hash = "sha256:f6f824dc3bce0edab5f427efcfb1d63ee75b6fcb7282900ccaf925be84efb0fc"}, + {file = "cffi-1.15.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:06c48159c1abed75c2e721b1715c379fa3200c7784271b3c46df01383b593636"}, + {file = "cffi-1.15.0-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:c2051981a968d7de9dd2d7b87bcb9c939c74a34626a6e2f8181455dd49ed69e4"}, + {file = "cffi-1.15.0-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:fd8a250edc26254fe5b33be00402e6d287f562b6a5b2152dec302fa15bb3e997"}, + {file = "cffi-1.15.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:91d77d2a782be4274da750752bb1650a97bfd8f291022b379bb8e01c66b4e96b"}, + {file = "cffi-1.15.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:45db3a33139e9c8f7c09234b5784a5e33d31fd6907800b316decad50af323ff2"}, + {file = "cffi-1.15.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:263cc3d821c4ab2213cbe8cd8b355a7f72a8324577dc865ef98487c1aeee2bc7"}, + {file = "cffi-1.15.0-cp37-cp37m-win32.whl", hash = "sha256:17771976e82e9f94976180f76468546834d22a7cc404b17c22df2a2c81db0c66"}, + {file = "cffi-1.15.0-cp37-cp37m-win_amd64.whl", hash = "sha256:3415c89f9204ee60cd09b235810be700e993e343a408693e80ce7f6a40108029"}, + {file = "cffi-1.15.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:4238e6dab5d6a8ba812de994bbb0a79bddbdf80994e4ce802b6f6f3142fcc880"}, + {file = "cffi-1.15.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:0808014eb713677ec1292301ea4c81ad277b6cdf2fdd90fd540af98c0b101d20"}, + {file = "cffi-1.15.0-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:57e9ac9ccc3101fac9d6014fba037473e4358ef4e89f8e181f8951a2c0162024"}, + {file = "cffi-1.15.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b6c2ea03845c9f501ed1313e78de148cd3f6cad741a75d43a29b43da27f2e1e"}, + {file = "cffi-1.15.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:10dffb601ccfb65262a27233ac273d552ddc4d8ae1bf93b21c94b8511bffe728"}, + {file = "cffi-1.15.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:786902fb9ba7433aae840e0ed609f45c7bcd4e225ebb9c753aa39725bb3e6ad6"}, + {file = "cffi-1.15.0-cp38-cp38-win32.whl", hash = "sha256:da5db4e883f1ce37f55c667e5c0de439df76ac4cb55964655906306918e7363c"}, + {file = "cffi-1.15.0-cp38-cp38-win_amd64.whl", hash = "sha256:181dee03b1170ff1969489acf1c26533710231c58f95534e3edac87fff06c443"}, + {file = "cffi-1.15.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:45e8636704eacc432a206ac7345a5d3d2c62d95a507ec70d62f23cd91770482a"}, + {file = "cffi-1.15.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:31fb708d9d7c3f49a60f04cf5b119aeefe5644daba1cd2a0fe389b674fd1de37"}, + {file = "cffi-1.15.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:6dc2737a3674b3e344847c8686cf29e500584ccad76204efea14f451d4cc669a"}, + {file = "cffi-1.15.0-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:74fdfdbfdc48d3f47148976f49fab3251e550a8720bebc99bf1483f5bfb5db3e"}, + {file = "cffi-1.15.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffaa5c925128e29efbde7301d8ecaf35c8c60ffbcd6a1ffd3a552177c8e5e796"}, + {file = "cffi-1.15.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3f7d084648d77af029acb79a0ff49a0ad7e9d09057a9bf46596dac9514dc07df"}, + {file = "cffi-1.15.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ef1f279350da2c586a69d32fc8733092fd32cc8ac95139a00377841f59a3f8d8"}, + {file = "cffi-1.15.0-cp39-cp39-win32.whl", hash = "sha256:2a23af14f408d53d5e6cd4e3d9a24ff9e05906ad574822a10563efcef137979a"}, + {file = "cffi-1.15.0-cp39-cp39-win_amd64.whl", hash = "sha256:3773c4d81e6e818df2efbc7dd77325ca0dcb688116050fb2b3011218eda36139"}, + {file = "cffi-1.15.0.tar.gz", hash = "sha256:920f0d66a896c2d99f0adbb391f990a84091179542c205fa53ce5787aff87954"}, +] +colorama = [ + {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"}, + {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"}, +] +commonmark = [ + {file = "commonmark-0.9.1-py2.py3-none-any.whl", hash = "sha256:da2f38c92590f83de410ba1a3cbceafbc74fee9def35f9251ba9a971d6d66fd9"}, + {file = "commonmark-0.9.1.tar.gz", hash = "sha256:452f9dc859be7f06631ddcb328b6919c67984aca654e5fefb3914d54691aed60"}, +] +cryptg = [ + {file = "cryptg-0.2.post4-cp36-cp36m-macosx_10_6_intel.whl", hash = "sha256:b6352555e47f389ed502269bdb537233d0a928b12d9f4caa57e8c707151acd30"}, + {file = "cryptg-0.2.post4-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:7fc8e1893775c6f53dceda1959f19833cc27a67a80492c10e2415dc601b36650"}, + {file = "cryptg-0.2.post4-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:2516557e89803637fa7342de43dbcc5f84bf68ae05b1064a354a62d423447d9f"}, + {file = "cryptg-0.2.post4-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:c09a5b14494532fc3226f5c5f57ef2a651c935ed6a1d2d0f9eff110046725524"}, + {file = "cryptg-0.2.post4-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:eff15f0a1eee678dd9ec747b58ce86edb78b608036ac4e02d8349f5f35202495"}, + {file = "cryptg-0.2.post4-cp36-cp36m-win32.whl", hash = "sha256:72a5485ece10a70160170ceb658b1836db82dccab08a1f7029c54d81cf6b1d43"}, + {file = "cryptg-0.2.post4-cp36-cp36m-win_amd64.whl", hash = "sha256:29001dafd3d6a054365222b1f89b12876723c89cdd10aa0e5885a05dfd034eeb"}, + {file = "cryptg-0.2.post4-cp37-cp37m-macosx_10_6_intel.whl", hash = "sha256:307bf96a6ac9c87b44531d8da5fe3a6c5d856e1dc69b68136ef9c4fb66ad17ac"}, + {file = "cryptg-0.2.post4-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:47ad5916be4558f4d674c12800e8d9663ce938b0046f19cdc869ba3a7ca280ec"}, + {file = "cryptg-0.2.post4-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:6c5d66975fc59adca203fa91e2a104240457114468162d30e9213661239ac1d6"}, + {file = "cryptg-0.2.post4-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:bf00943924cddb0838f8a65f5aae31f6fe2ad64a5d7e6f10a6b900b3f01b0ae0"}, + {file = "cryptg-0.2.post4-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:135688c6fbda90748924c2cb047f63785ebf4397d81acc4a05357950653c5096"}, + {file = "cryptg-0.2.post4-cp37-cp37m-win32.whl", hash = "sha256:46960979542155c9d903656a3a39770061b09a3691a23296f06dc168fe4ff962"}, + {file = "cryptg-0.2.post4-cp37-cp37m-win_amd64.whl", hash = "sha256:ce08c04ebb06ce1ac417597c1bb514a3c1b36cf5c286b8c60f23df2e65703bf3"}, + {file = "cryptg-0.2.post4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:695636cca0ee938bd7113658ee60bfaf89afa19708c40ecae5f4a222c2ec544a"}, + {file = "cryptg-0.2.post4-cp38-cp38-manylinux1_i686.whl", hash = "sha256:1fb6c6d4561a54406593197c1f5f23662ab320f4af4ab11834e1583e9d27a49a"}, + {file = "cryptg-0.2.post4-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:bbd05b52d09e78bdc595f229c0481f4f2e1daf3959847322a6b2c1f76119305f"}, + {file = "cryptg-0.2.post4-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:c4812802ce4cd6f08189ce0fa8b79e9a96ac941e69e6b3032bb6908baefde2ba"}, + {file = "cryptg-0.2.post4-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:c69c1e19884108e508697919de0cd43e2ca4e9af418962aa235273b3c51a0e37"}, + {file = "cryptg-0.2.post4-cp38-cp38-win32.whl", hash = "sha256:e29b0d944176cf88fe52d1c58f46017b5bddc9cc54ec0fc6fac20043febefc32"}, + {file = "cryptg-0.2.post4-cp38-cp38-win_amd64.whl", hash = "sha256:5faed49d972c7f44ce4d6fa1a64169c85a11209fa1fbe1c8a333fb1454888725"}, + {file = "cryptg-0.2.post4-cp39-cp39-manylinux1_i686.whl", hash = "sha256:b8896394b72ff7dbf38072ad4c2cd59abdd9e388bb55e1c369102beb8e569f9d"}, + {file = "cryptg-0.2.post4-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:e48ab84e0ed364436d5e449c59762c5963f08ad87f6508f4cb7644745b5559a8"}, + {file = "cryptg-0.2.post4-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:0da1b367056e57a5c01d22608da0cd50e597b917c1b2d9631767aa3c0640a99a"}, + {file = "cryptg-0.2.post4-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:31cf7682de69022c9a77739cdcf7116b06522b128b9b51c7593f277f38c38dbf"}, + {file = "cryptg-0.2.post4-cp39-cp39-win32.whl", hash = "sha256:02b31622a75a49a5dcd25e589c85faae54575f018e055bd21a17df97c8bb9095"}, + {file = "cryptg-0.2.post4-cp39-cp39-win_amd64.whl", hash = "sha256:3bc2f372dec3a7753c0c0d72c69fcbe44af5473f870a3406978e07e8560a1aa6"}, + {file = "cryptg-0.2.post4-pp36-pypy36_pp73-manylinux1_x86_64.whl", hash = "sha256:a1fb178702730b59267f1e6c6dfe16c7bb9c1350cee4183221982ad2dba4e7f5"}, + {file = "cryptg-0.2.post4-pp36-pypy36_pp73-manylinux2010_x86_64.whl", hash = "sha256:2cc8115960e49a038091ffb2d09de59e0acbdc76de10d7d415b7671a06bae0a9"}, + {file = "cryptg-0.2.post4-pp36-pypy36_pp73-win32.whl", hash = "sha256:bf15aae0fa01aeec728ab16b920cf4c6b2793099c71f62f30ff100d6fe8c9859"}, + {file = "cryptg-0.2.post4-pp37-pypy37_pp73-manylinux1_x86_64.whl", hash = "sha256:890584db41c8e1e046ae40dee0074614470d36ebd6b7e57bb91303300066601f"}, + {file = "cryptg-0.2.post4-pp37-pypy37_pp73-manylinux2010_x86_64.whl", hash = "sha256:fdd62c2be23eeabb9ebd2ad41bf153f5ec48b968885ef14e676515407cd56339"}, + {file = "cryptg-0.2.post4-pp37-pypy37_pp73-win32.whl", hash = "sha256:2cd8224eb64af756f45cdceab16d048494313db8acec1e38d75d97716082267b"}, + {file = "cryptg-0.2.post4.tar.gz", hash = "sha256:a4de1730ca56aa8a945f176c25586901ed5e9f15ffb70c6459eedf466eb6299b"}, +] +pyaes = [ + {file = "pyaes-1.6.1.tar.gz", hash = "sha256:02c1b1405c38d3c370b085fb952dd8bea3fadcee6411ad99f312cc129c536d8f"}, +] +pyasn1 = [ + {file = "pyasn1-0.4.8-py2.4.egg", hash = "sha256:fec3e9d8e36808a28efb59b489e4528c10ad0f480e57dcc32b4de5c9d8c9fdf3"}, + {file = "pyasn1-0.4.8-py2.5.egg", hash = "sha256:0458773cfe65b153891ac249bcf1b5f8f320b7c2ce462151f8fa74de8934becf"}, + {file = "pyasn1-0.4.8-py2.6.egg", hash = "sha256:5c9414dcfede6e441f7e8f81b43b34e834731003427e5b09e4e00e3172a10f00"}, + {file = "pyasn1-0.4.8-py2.7.egg", hash = "sha256:6e7545f1a61025a4e58bb336952c5061697da694db1cae97b116e9c46abcf7c8"}, + {file = "pyasn1-0.4.8-py2.py3-none-any.whl", hash = "sha256:39c7e2ec30515947ff4e87fb6f456dfc6e84857d34be479c9d4a4ba4bf46aa5d"}, + {file = "pyasn1-0.4.8-py3.1.egg", hash = "sha256:78fa6da68ed2727915c4767bb386ab32cdba863caa7dbe473eaae45f9959da86"}, + {file = "pyasn1-0.4.8-py3.2.egg", hash = "sha256:08c3c53b75eaa48d71cf8c710312316392ed40899cb34710d092e96745a358b7"}, + {file = "pyasn1-0.4.8-py3.3.egg", hash = "sha256:03840c999ba71680a131cfaee6fab142e1ed9bbd9c693e285cc6aca0d555e576"}, + {file = "pyasn1-0.4.8-py3.4.egg", hash = "sha256:7ab8a544af125fb704feadb008c99a88805126fb525280b2270bb25cc1d78a12"}, + {file = "pyasn1-0.4.8-py3.5.egg", hash = "sha256:e89bf84b5437b532b0803ba5c9a5e054d21fec423a89952a74f87fa2c9b7bce2"}, + {file = "pyasn1-0.4.8-py3.6.egg", hash = "sha256:014c0e9976956a08139dc0712ae195324a75e142284d5f87f1a87ee1b068a359"}, + {file = "pyasn1-0.4.8-py3.7.egg", hash = "sha256:99fcc3c8d804d1bc6d9a099921e39d827026409a58f2a720dcdb89374ea0c776"}, + {file = "pyasn1-0.4.8.tar.gz", hash = "sha256:aef77c9fb94a3ac588e87841208bdec464471d9871bd5050a287cc9a475cd0ba"}, +] +pycparser = [ + {file = "pycparser-2.21-py2.py3-none-any.whl", hash = "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9"}, + {file = "pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"}, +] +pydantic = [ + {file = "pydantic-1.8.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:05ddfd37c1720c392f4e0d43c484217b7521558302e7069ce8d318438d297739"}, + {file = "pydantic-1.8.2-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:a7c6002203fe2c5a1b5cbb141bb85060cbff88c2d78eccbc72d97eb7022c43e4"}, + {file = "pydantic-1.8.2-cp36-cp36m-manylinux2014_i686.whl", hash = "sha256:589eb6cd6361e8ac341db97602eb7f354551482368a37f4fd086c0733548308e"}, + {file = "pydantic-1.8.2-cp36-cp36m-manylinux2014_x86_64.whl", hash = "sha256:10e5622224245941efc193ad1d159887872776df7a8fd592ed746aa25d071840"}, + {file = "pydantic-1.8.2-cp36-cp36m-win_amd64.whl", hash = "sha256:99a9fc39470010c45c161a1dc584997f1feb13f689ecf645f59bb4ba623e586b"}, + {file = "pydantic-1.8.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a83db7205f60c6a86f2c44a61791d993dff4b73135df1973ecd9eed5ea0bda20"}, + {file = "pydantic-1.8.2-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:41b542c0b3c42dc17da70554bc6f38cbc30d7066d2c2815a94499b5684582ecb"}, + {file = "pydantic-1.8.2-cp37-cp37m-manylinux2014_i686.whl", hash = "sha256:ea5cb40a3b23b3265f6325727ddfc45141b08ed665458be8c6285e7b85bd73a1"}, + {file = "pydantic-1.8.2-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:18b5ea242dd3e62dbf89b2b0ec9ba6c7b5abaf6af85b95a97b00279f65845a23"}, + {file = "pydantic-1.8.2-cp37-cp37m-win_amd64.whl", hash = "sha256:234a6c19f1c14e25e362cb05c68afb7f183eb931dd3cd4605eafff055ebbf287"}, + {file = "pydantic-1.8.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:021ea0e4133e8c824775a0cfe098677acf6fa5a3cbf9206a376eed3fc09302cd"}, + {file = "pydantic-1.8.2-cp38-cp38-manylinux1_i686.whl", hash = "sha256:e710876437bc07bd414ff453ac8ec63d219e7690128d925c6e82889d674bb505"}, + {file = "pydantic-1.8.2-cp38-cp38-manylinux2014_i686.whl", hash = "sha256:ac8eed4ca3bd3aadc58a13c2aa93cd8a884bcf21cb019f8cfecaae3b6ce3746e"}, + {file = "pydantic-1.8.2-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:4a03cbbe743e9c7247ceae6f0d8898f7a64bb65800a45cbdc52d65e370570820"}, + {file = "pydantic-1.8.2-cp38-cp38-win_amd64.whl", hash = "sha256:8621559dcf5afacf0069ed194278f35c255dc1a1385c28b32dd6c110fd6531b3"}, + {file = "pydantic-1.8.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8b223557f9510cf0bfd8b01316bf6dd281cf41826607eada99662f5e4963f316"}, + {file = "pydantic-1.8.2-cp39-cp39-manylinux1_i686.whl", hash = "sha256:244ad78eeb388a43b0c927e74d3af78008e944074b7d0f4f696ddd5b2af43c62"}, + {file = "pydantic-1.8.2-cp39-cp39-manylinux2014_i686.whl", hash = "sha256:05ef5246a7ffd2ce12a619cbb29f3307b7c4509307b1b49f456657b43529dc6f"}, + {file = "pydantic-1.8.2-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:54cd5121383f4a461ff7644c7ca20c0419d58052db70d8791eacbbe31528916b"}, + {file = "pydantic-1.8.2-cp39-cp39-win_amd64.whl", hash = "sha256:4be75bebf676a5f0f87937c6ddb061fa39cbea067240d98e298508c1bda6f3f3"}, + {file = "pydantic-1.8.2-py3-none-any.whl", hash = "sha256:fec866a0b59f372b7e776f2d7308511784dace622e0992a0b59ea3ccee0ae833"}, + {file = "pydantic-1.8.2.tar.gz", hash = "sha256:26464e57ccaafe72b7ad156fdaa4e9b9ef051f69e175dbbb463283000c05ab7b"}, +] +pygments = [ + {file = "Pygments-2.10.0-py3-none-any.whl", hash = "sha256:b8e67fe6af78f492b3c4b3e2970c0624cbf08beb1e493b2c99b9fa1b67a20380"}, + {file = "Pygments-2.10.0.tar.gz", hash = "sha256:f398865f7eb6874156579fdf36bc840a03cab64d1cde9e93d68f46a425ec52c6"}, +] +pyyaml = [ + {file = "PyYAML-6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53"}, + {file = "PyYAML-6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c"}, + {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc"}, + {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b"}, + {file = "PyYAML-6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5"}, + {file = "PyYAML-6.0-cp310-cp310-win32.whl", hash = "sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513"}, + {file = "PyYAML-6.0-cp310-cp310-win_amd64.whl", hash = "sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a"}, + {file = "PyYAML-6.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86"}, + {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f"}, + {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92"}, + {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4"}, + {file = "PyYAML-6.0-cp36-cp36m-win32.whl", hash = "sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293"}, + {file = "PyYAML-6.0-cp36-cp36m-win_amd64.whl", hash = "sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57"}, + {file = "PyYAML-6.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c"}, + {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0"}, + {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0ce82d761c532fe4ec3f87fc45688bdd3a4c1dc5e0b4a19814b9009a29baefd4"}, + {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:231710d57adfd809ef5d34183b8ed1eeae3f76459c18fb4a0b373ad56bedcdd9"}, + {file = "PyYAML-6.0-cp37-cp37m-win32.whl", hash = "sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737"}, + {file = "PyYAML-6.0-cp37-cp37m-win_amd64.whl", hash = "sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d"}, + {file = "PyYAML-6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0b4624f379dab24d3725ffde76559cff63d9ec94e1736b556dacdfebe5ab6d4b"}, + {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:213c60cd50106436cc818accf5baa1aba61c0189ff610f64f4a3e8c6726218ba"}, + {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34"}, + {file = "PyYAML-6.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287"}, + {file = "PyYAML-6.0-cp38-cp38-win32.whl", hash = "sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78"}, + {file = "PyYAML-6.0-cp38-cp38-win_amd64.whl", hash = "sha256:1e4747bc279b4f613a09eb64bba2ba602d8a6664c6ce6396a4d0cd413a50ce07"}, + {file = "PyYAML-6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b"}, + {file = "PyYAML-6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174"}, + {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803"}, + {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3"}, + {file = "PyYAML-6.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0"}, + {file = "PyYAML-6.0-cp39-cp39-win32.whl", hash = "sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb"}, + {file = "PyYAML-6.0-cp39-cp39-win_amd64.whl", hash = "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c"}, + {file = "PyYAML-6.0.tar.gz", hash = "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2"}, +] +rich = [ + {file = "rich-10.16.1-py3-none-any.whl", hash = "sha256:bbe04dd6ac09e4b00d22cb1051aa127beaf6e16c3d8687b026e96d3fca6aad52"}, + {file = "rich-10.16.1.tar.gz", hash = "sha256:4949e73de321784ef6664ebbc854ac82b20ff60b2865097b93f3b9b41e30da27"}, +] +rsa = [ + {file = "rsa-4.8-py3-none-any.whl", hash = "sha256:95c5d300c4e879ee69708c428ba566c59478fd653cc3a22243eeb8ed846950bb"}, + {file = "rsa-4.8.tar.gz", hash = "sha256:5c6bd9dc7a543b7fe4304a631f8a8a3b674e2bbfc49c2ae96200cdbe55df6b17"}, +] +telethon = [ + {file = "Telethon-1.24.0-py3-none-any.whl", hash = "sha256:04fdc5fa4ed3e886e6ecf4bad79205ab8880c6aefbd42c29c89c689a502aa816"}, + {file = "Telethon-1.24.0.tar.gz", hash = "sha256:818cb61281ed3f75ba4da9b68cb69486bed9474d2db4e0aa16e482053117452c"}, +] +typing-extensions = [ + {file = "typing_extensions-4.0.1-py3-none-any.whl", hash = "sha256:7f001e5ac290a0c0401508864c7ec868be4e701886d5b573a9528ed3973d9d3b"}, + {file = "typing_extensions-4.0.1.tar.gz", hash = "sha256:4ca091dea149f945ec56afb48dae714f21e8692ef22a395223bcd328961b6a0e"}, +] diff --git a/pyproject.toml b/pyproject.toml index 374b58c..40e826b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,30 @@ -[build-system] -requires = [ - "setuptools>=42", - "wheel" +[tool.poetry] +name = "tgpy" +version = "0.1.0.post2" +description = "Run Python code right in your Telegram messages" +authors = ["tmat ", "vanutp ", "ntonee "] +license = "MIT" +documentation = "https://tgpy.tmat.me/" +repository = "https://github.com/tm-a-t/TGPy/" +readme = "README.md" +classifiers = [ + "Operating System :: OS Independent" ] -build-backend = "setuptools.build_meta" + +[tool.poetry.scripts] +tgpy = 'tgpy.main:main' + +[tool.poetry.dependencies] +python = "^3.9" +Telethon = "^1.24.0" +cryptg = "^0.2.post4" +PyYAML = "^6.0" +pydantic = "^1.8.2" +aiorun = "^2021.10.1" +rich = "^10.16.1" + +[tool.poetry.dev-dependencies] + +[build-system] +requires = ["poetry-core>=1.0.0"] +build-backend = "poetry.core.masonry.api" diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 865b22b..0000000 --- a/setup.cfg +++ /dev/null @@ -1,29 +0,0 @@ -[metadata] -name = tgpy -version = 0.1.0 -description = Run Python code right in your Telegram messages -long_description = file: README.md -long_description_content_type = text/markdown -url = https://github.com/tm-a-t/TGPy/ -project_urls = - Guide = https://tgpy.tmat.me/ -classifiers = - Programming Language :: Python :: 3 - License :: OSI Approved :: MIT License - Operating System :: OS Independent - -[options] -packages = app -python_requires = >=3.9 -install_requires= - Telethon~=1.23.0 - cryptg==0.2.post4 - PyYAML==6.0 - pydantic==1.8.2 - aiorun==2021.10.1 - rich~=10.12.0 - - -[options.entry_points] -console_scripts = - tgpy = app.cli:main diff --git a/app/__init__.py b/tgpy/__init__.py similarity index 74% rename from app/__init__.py rename to tgpy/__init__.py index 559d599..2dd8506 100644 --- a/app/__init__.py +++ b/tgpy/__init__.py @@ -3,8 +3,11 @@ from rich.logging import RichHandler from telethon import TelegramClient -from app.app_config import Config -from app.console import console +from tgpy.app_config import Config +from tgpy.console import console + + +__version__ = "0.1.0.post2" logging.basicConfig(level=logging.INFO, format='%(message)s', datefmt="[%X]", handlers=[RichHandler()]) diff --git a/tgpy/__main__.py b/tgpy/__main__.py new file mode 100644 index 0000000..69b16a9 --- /dev/null +++ b/tgpy/__main__.py @@ -0,0 +1,3 @@ +from tgpy.main import main + +main() diff --git a/app/app_config.py b/tgpy/app_config.py similarity index 94% rename from app/app_config.py rename to tgpy/app_config.py index 55a5ed9..f862a4d 100644 --- a/app/app_config.py +++ b/tgpy/app_config.py @@ -3,7 +3,7 @@ import yaml from pydantic import BaseModel, ValidationError -from app.utils import CONFIG_FILENAME +from tgpy.utils import CONFIG_FILENAME class Config(BaseModel): diff --git a/app/console.py b/tgpy/console.py similarity index 100% rename from app/console.py rename to tgpy/console.py diff --git a/app/handlers/__init__.py b/tgpy/handlers/__init__.py similarity index 90% rename from app/handlers/__init__.py rename to tgpy/handlers/__init__.py index b254a52..dbf407d 100644 --- a/app/handlers/__init__.py +++ b/tgpy/handlers/__init__.py @@ -2,10 +2,10 @@ from telethon.tl.custom import Message from telethon.tl.types import Channel -from app import app, message_design -from app.handlers.utils import _handle_errors, outgoing_messages_filter -from app.run_code import eval_message, get_kwargs -from app.run_code.parse_code import parse_code +from tgpy import app, message_design +from tgpy.handlers.utils import _handle_errors, outgoing_messages_filter +from tgpy.run_code import eval_message, get_kwargs +from tgpy.run_code.parse_code import parse_code async def handle_message(message: Message) -> None: diff --git a/app/handlers/utils.py b/tgpy/handlers/utils.py similarity index 93% rename from app/handlers/utils.py rename to tgpy/handlers/utils.py index 43ca749..57ef51e 100644 --- a/app/handlers/utils.py +++ b/tgpy/handlers/utils.py @@ -2,7 +2,7 @@ from telethon.tl.custom import Message -from app import message_design +from tgpy import message_design def _handle_errors(func: Callable): diff --git a/app/hooks.py b/tgpy/hooks.py similarity index 93% rename from app/hooks.py rename to tgpy/hooks.py index 4d1af3b..b9f8881 100644 --- a/app/hooks.py +++ b/tgpy/hooks.py @@ -8,11 +8,11 @@ import yaml from pydantic import BaseModel -from app import app -from app.run_code import meval -from app.run_code.utils import format_traceback -from app.run_code.variables import variables -from app.utils import yaml_multiline_str, HOOKS_DIR +from tgpy import app +from tgpy.run_code import meval +from tgpy.run_code.utils import format_traceback +from tgpy.run_code.variables import variables +from tgpy.utils import yaml_multiline_str, HOOKS_DIR logger = logging.getLogger(__name__) diff --git a/app/__main__.py b/tgpy/main.py similarity index 89% rename from app/__main__.py rename to tgpy/main.py index 16e17cf..0e86f18 100644 --- a/app/__main__.py +++ b/tgpy/main.py @@ -1,13 +1,12 @@ -import logging - import aiorun +import logging from telethon import TelegramClient, errors -from app import app, Config -from app.console import console -from app.handlers import add_handlers -from app.hooks import HookType, Hook -from app.utils import migrate_from_old_versions, SESSION_FILENAME +from tgpy import app, Config +from tgpy.console import console +from tgpy.handlers import add_handlers +from tgpy.hooks import HookType, Hook +from tgpy.utils import migrate_from_old_versions, SESSION_FILENAME log = logging.getLogger(__name__) @@ -68,7 +67,7 @@ async def run_client(): await app.client.run_until_disconnected() -async def main(): +async def _main(): migrate_from_old_versions() app.config = Config.load() @@ -81,4 +80,5 @@ async def main(): await run_client() -aiorun.run(main(), stop_on_unhandled_errors=True) +def main(): + aiorun.run(_main(), stop_on_unhandled_errors=True) diff --git a/app/message_design.py b/tgpy/message_design.py similarity index 98% rename from app/message_design.py rename to tgpy/message_design.py index e91fb39..20cd413 100644 --- a/app/message_design.py +++ b/tgpy/message_design.py @@ -4,7 +4,7 @@ from telethon.tl.custom import Message from telethon.tl.types import MessageEntityTextUrl, MessageEntityCode, MessageEntityBold -from app import app +from tgpy import app TITLE = 'TGPy>' TITLE_URL = 'https://github.com/tm-a-t/TGPy' diff --git a/app/run_code/__init__.py b/tgpy/run_code/__init__.py similarity index 82% rename from app/run_code/__init__.py rename to tgpy/run_code/__init__.py index ccfc4b8..e25a82b 100644 --- a/app/run_code/__init__.py +++ b/tgpy/run_code/__init__.py @@ -1,11 +1,11 @@ from telethon.errors import MessageIdInvalidError from telethon.tl.custom import Message -from app import app -from app import message_design -from app.run_code.meval import meval -from app.run_code.utils import Output, convert_result, filename_prefix, format_traceback -from app.run_code.variables import variables +from tgpy import app +from tgpy import message_design +from tgpy.run_code.meval import meval +from tgpy.run_code.utils import Output, convert_result, filename_prefix, format_traceback +from tgpy.run_code.variables import variables def get_kwargs(include_orig=True): @@ -51,4 +51,4 @@ async def eval_message(code: str, message: Message, uses_orig=False) -> None: pass -from app.run_code import builtin_functions +from tgpy.run_code import builtin_functions diff --git a/app/run_code/builtin_functions.py b/tgpy/run_code/builtin_functions.py similarity index 86% rename from app/run_code/builtin_functions.py rename to tgpy/run_code/builtin_functions.py index 0e48b4b..5bb9b7a 100644 --- a/app/run_code/builtin_functions.py +++ b/tgpy/run_code/builtin_functions.py @@ -7,11 +7,11 @@ import datetime as dt -from app.hooks import Hook, HookType, delete_hook_file, get_sorted_hooks -from app.message_design import get_code -from app.run_code import variables -from app.run_code.utils import Context, filename_prefix, save_function_to_variables -from app.utils import run_cmd, get_version, BASE_DIR +from tgpy.hooks import Hook, HookType, delete_hook_file, get_sorted_hooks +from tgpy.message_design import get_code +from tgpy.run_code import variables +from tgpy.run_code.utils import Context, filename_prefix, save_function_to_variables +from tgpy.utils import run_cmd, get_version, BASE_DIR variables['ctx'] = ctx = Context() @@ -26,7 +26,7 @@ def ping(): @save_function_to_variables def restart(msg: Optional[str] = 'Restarted successfully'): hook_code = dedent(f''' - from app.message_design import edit_message, get_code + from tgpy.message_design import edit_message, get_code msg = await client.get_messages({ctx.msg.chat_id}, ids={ctx.msg.id}) await edit_message(msg, get_code(msg), '{msg}') ''') @@ -41,7 +41,7 @@ def restart(msg: Optional[str] = 'Restarted successfully'): ) hook.save() os.chdir(BASE_DIR) - os.execl(sys.executable, sys.executable, '-m', 'app', *sys.argv[1:]) + os.execl(sys.executable, sys.executable, '-m', 'tgpy', *sys.argv[1:]) @save_function_to_variables diff --git a/app/run_code/meval.py b/tgpy/run_code/meval.py similarity index 100% rename from app/run_code/meval.py rename to tgpy/run_code/meval.py diff --git a/app/run_code/parse_code.py b/tgpy/run_code/parse_code.py similarity index 100% rename from app/run_code/parse_code.py rename to tgpy/run_code/parse_code.py diff --git a/app/run_code/utils.py b/tgpy/run_code/utils.py similarity index 95% rename from app/run_code/utils.py rename to tgpy/run_code/utils.py index e0b7da8..d78ad17 100644 --- a/app/run_code/utils.py +++ b/tgpy/run_code/utils.py @@ -5,7 +5,7 @@ from telethon.tl import TLObject from telethon.tl.custom import Message -from app.run_code.variables import variables +from tgpy.run_code.variables import variables class Context: diff --git a/app/run_code/variables.py b/tgpy/run_code/variables.py similarity index 100% rename from app/run_code/variables.py rename to tgpy/run_code/variables.py diff --git a/app/utils.py b/tgpy/utils.py similarity index 98% rename from app/utils.py rename to tgpy/utils.py index 6a34e8d..6289d95 100644 --- a/app/utils.py +++ b/tgpy/utils.py @@ -20,7 +20,7 @@ def migrate_from_old_versions(): - from app.app_config import Config + from tgpy.app_config import Config old_session_file = BASE_DIR / 'TGPy.session' if old_session_file.exists() and not SESSION_FILENAME.exists(): From 2f3424696bbae77004c08f43fe7271355bdfe779 Mon Sep 17 00:00:00 2001 From: vanutp Date: Sat, 25 Dec 2021 22:11:13 +0300 Subject: [PATCH 7/7] ci: automatic semantic releases --- .github/workflows/main.yml | 65 ++++ poetry.lock | 619 ++++++++++++++++++++++++++++++++++++- pyproject.toml | 15 +- tgpy/__init__.py | 2 +- 4 files changed, 698 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/main.yml diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..d7dea90 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,65 @@ +name: Lint & release project +on: [ push, pull_request ] + +jobs: + Lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-python@v2 + with: + python-version: '3.10' + - name: Install poetry + shell: bash + run: | + pip install poetry + poetry config virtualenvs.in-project true + + - name: Load dependency cache + id: load-cache + uses: actions/cache@v2 + with: + path: .venv + key: venv-${{ runner.os }}-${{ hashFiles('**/poetry.lock') }} + - name: Install dependencies + run: poetry install + if: steps.load-cache.outputs.cache-hit != 'true' + + Release: + concurrency: release + needs: Lint + if: github.event_name == 'push' && github.ref == 'refs/heads/master' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 0 + - uses: actions/setup-python@v2 + with: + python-version: '3.10' + - name: Install poetry + shell: bash + run: | + pip install poetry + poetry config virtualenvs.in-project true + + - name: Load dependency cache + id: load-cache + uses: actions/cache@v2 + with: + path: .venv + key: venv-${{ runner.os }}-${{ hashFiles('**/poetry.lock') }} + + - name: Release + shell: bash + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }} + run: | + source .venv/bin/activate + git config --global user.name "github-actions" + git config --global user.email "action@github.com" + export GH_TOKEN="${GITHUB_TOKEN}" + export REPOSITORY_USERNAME="__token__" + export REPOSITORY_PASSWORD="${PYPI_TOKEN}" + python -m semantic_release publish \ No newline at end of file diff --git a/poetry.lock b/poetry.lock index 90f9ac4..68ad98f 100644 --- a/poetry.lock +++ b/poetry.lock @@ -9,6 +9,27 @@ python-versions = ">=3.5" [package.extras] dev = ["pytest", "pytest-cov"] +[[package]] +name = "bleach" +version = "4.1.0" +description = "An easy safelist-based HTML-sanitizing tool." +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +packaging = "*" +six = ">=1.9.0" +webencodings = "*" + +[[package]] +name = "certifi" +version = "2021.10.8" +description = "Python package for providing Mozilla's CA Bundle." +category = "dev" +optional = false +python-versions = "*" + [[package]] name = "cffi" version = "1.15.0" @@ -20,6 +41,39 @@ python-versions = "*" [package.dependencies] pycparser = "*" +[[package]] +name = "charset-normalizer" +version = "2.0.9" +description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +category = "dev" +optional = false +python-versions = ">=3.5.0" + +[package.extras] +unicode_backport = ["unicodedata2"] + +[[package]] +name = "click" +version = "8.0.3" +description = "Composable command line interface toolkit" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + +[[package]] +name = "click-log" +version = "0.3.2" +description = "Logging integration for Click" +category = "dev" +optional = false +python-versions = "*" + +[package.dependencies] +click = "*" + [[package]] name = "colorama" version = "0.4.4" @@ -51,6 +105,151 @@ python-versions = ">=3.6" cffi = ">=1.0.0" pycparser = "*" +[[package]] +name = "cryptography" +version = "36.0.1" +description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +cffi = ">=1.12" + +[package.extras] +docs = ["sphinx (>=1.6.5,!=1.8.0,!=3.1.0,!=3.1.1)", "sphinx-rtd-theme"] +docstest = ["pyenchant (>=1.6.11)", "twine (>=1.12.0)", "sphinxcontrib-spelling (>=4.0.1)"] +pep8test = ["black", "flake8", "flake8-import-order", "pep8-naming"] +sdist = ["setuptools_rust (>=0.11.4)"] +ssh = ["bcrypt (>=3.1.5)"] +test = ["pytest (>=6.2.0)", "pytest-cov", "pytest-subtests", "pytest-xdist", "pretend", "iso8601", "pytz", "hypothesis (>=1.11.4,!=3.79.2)"] + +[[package]] +name = "docutils" +version = "0.18.1" +description = "Docutils -- Python Documentation Utilities" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[[package]] +name = "dotty-dict" +version = "1.3.0" +description = "Dictionary wrapper for quick access to deeply nested keys." +category = "dev" +optional = false +python-versions = "*" + +[package.dependencies] +setuptools_scm = "*" + +[[package]] +name = "gitdb" +version = "4.0.9" +description = "Git Object Database" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +smmap = ">=3.0.1,<6" + +[[package]] +name = "gitpython" +version = "3.1.24" +description = "GitPython is a python library used to interact with Git repositories" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +gitdb = ">=4.0.1,<5" +typing-extensions = {version = ">=3.7.4.3", markers = "python_version < \"3.10\""} + +[[package]] +name = "idna" +version = "3.3" +description = "Internationalized Domain Names in Applications (IDNA)" +category = "dev" +optional = false +python-versions = ">=3.5" + +[[package]] +name = "importlib-metadata" +version = "4.10.0" +description = "Read metadata from Python packages" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +zipp = ">=0.5" + +[package.extras] +docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] +perf = ["ipython"] +testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "packaging", "pyfakefs", "flufl.flake8", "pytest-perf (>=0.9.2)", "pytest-black (>=0.3.7)", "pytest-mypy", "importlib-resources (>=1.3)"] + +[[package]] +name = "invoke" +version = "1.6.0" +description = "Pythonic task execution" +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "jeepney" +version = "0.7.1" +description = "Low-level, pure Python DBus protocol wrapper." +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.extras] +test = ["pytest", "pytest-trio", "pytest-asyncio", "testpath", "trio", "async-timeout"] +trio = ["trio", "async-generator"] + +[[package]] +name = "keyring" +version = "23.4.0" +description = "Store and access your passwords safely." +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +importlib-metadata = ">=3.6" +jeepney = {version = ">=0.4.2", markers = "sys_platform == \"linux\""} +pywin32-ctypes = {version = "<0.1.0 || >0.1.0,<0.1.1 || >0.1.1", markers = "sys_platform == \"win32\""} +SecretStorage = {version = ">=3.2", markers = "sys_platform == \"linux\""} + +[package.extras] +docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)", "jaraco.tidelift (>=1.4)"] +testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "pytest-black (>=0.3.7)", "pytest-mypy"] + +[[package]] +name = "packaging" +version = "21.3" +description = "Core utilities for Python packages" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +pyparsing = ">=2.0.2,<3.0.5 || >3.0.5" + +[[package]] +name = "pkginfo" +version = "1.8.2" +description = "Query metadatdata from sdists / bdists / installed packages." +category = "dev" +optional = false +python-versions = "*" + +[package.extras] +testing = ["coverage", "nose"] + [[package]] name = "pyaes" version = "1.6.1" @@ -98,6 +297,67 @@ category = "main" optional = false python-versions = ">=3.5" +[[package]] +name = "pyparsing" +version = "3.0.6" +description = "Python parsing module" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.extras] +diagrams = ["jinja2", "railroad-diagrams"] + +[[package]] +name = "python-gitlab" +version = "2.10.1" +description = "Interact with GitLab API" +category = "dev" +optional = false +python-versions = ">=3.6.0" + +[package.dependencies] +requests = ">=2.25.0" +requests-toolbelt = ">=0.9.1" + +[package.extras] +autocompletion = ["argcomplete (>=1.10.0,<2)"] +yaml = ["PyYaml (>=5.2)"] + +[[package]] +name = "python-semantic-release" +version = "7.23.0" +description = "Automatic Semantic Versioning for Python projects" +category = "dev" +optional = false +python-versions = "*" + +[package.dependencies] +click = ">=7,<9" +click-log = ">=0.3,<1" +dotty-dict = ">=1.3.0,<2" +gitpython = ">=3.0.8,<4" +invoke = ">=1.4.1,<2" +python-gitlab = ">=1.10,<3" +requests = ">=2.25,<3" +semver = ">=2.10,<3" +tomlkit = "0.7.0" +twine = ">=3,<4" + +[package.extras] +dev = ["tox", "isort", "black"] +docs = ["Sphinx (==1.3.6)"] +mypy = ["mypy", "types-requests"] +test = ["coverage (>=5,<6)", "pytest (>=5,<6)", "pytest-xdist (>=1,<2)", "pytest-mock (>=2,<3)", "responses (==0.13.3)", "mock (==1.3.0)"] + +[[package]] +name = "pywin32-ctypes" +version = "0.2.0" +description = "" +category = "dev" +optional = false +python-versions = "*" + [[package]] name = "pyyaml" version = "6.0" @@ -106,6 +366,62 @@ category = "main" optional = false python-versions = ">=3.6" +[[package]] +name = "readme-renderer" +version = "32.0" +description = "readme_renderer is a library for rendering \"readme\" descriptions for Warehouse" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +bleach = ">=2.1.0" +docutils = ">=0.13.1" +Pygments = ">=2.5.1" + +[package.extras] +md = ["cmarkgfm (>=0.5.0,<0.7.0)"] + +[[package]] +name = "requests" +version = "2.26.0" +description = "Python HTTP for Humans." +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" + +[package.dependencies] +certifi = ">=2017.4.17" +charset-normalizer = {version = ">=2.0.0,<2.1.0", markers = "python_version >= \"3\""} +idna = {version = ">=2.5,<4", markers = "python_version >= \"3\""} +urllib3 = ">=1.21.1,<1.27" + +[package.extras] +socks = ["PySocks (>=1.5.6,!=1.5.7)", "win-inet-pton"] +use_chardet_on_py3 = ["chardet (>=3.0.2,<5)"] + +[[package]] +name = "requests-toolbelt" +version = "0.9.1" +description = "A utility belt for advanced users of python-requests" +category = "dev" +optional = false +python-versions = "*" + +[package.dependencies] +requests = ">=2.0.1,<3.0.0" + +[[package]] +name = "rfc3986" +version = "1.5.0" +description = "Validating URI References per RFC 3986" +category = "dev" +optional = false +python-versions = "*" + +[package.extras] +idna2008 = ["idna"] + [[package]] name = "rich" version = "10.16.1" @@ -133,6 +449,57 @@ python-versions = ">=3.6,<4" [package.dependencies] pyasn1 = ">=0.1.3" +[[package]] +name = "secretstorage" +version = "3.3.1" +description = "Python bindings to FreeDesktop.org Secret Service API" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +cryptography = ">=2.0" +jeepney = ">=0.6" + +[[package]] +name = "semver" +version = "2.13.0" +description = "Python helper for Semantic Versioning (http://semver.org/)" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[[package]] +name = "setuptools-scm" +version = "6.3.2" +description = "the blessed package to manage your versions by scm tags" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +packaging = ">=20.0" +tomli = ">=1.0.0" + +[package.extras] +toml = ["setuptools (>=42)", "tomli (>=1.0.0)"] + +[[package]] +name = "six" +version = "1.16.0" +description = "Python 2 and 3 compatibility utilities" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" + +[[package]] +name = "smmap" +version = "5.0.0" +description = "A pure Python implementation of a sliding window memory map manager" +category = "dev" +optional = false +python-versions = ">=3.6" + [[package]] name = "telethon" version = "1.24.0" @@ -148,6 +515,57 @@ rsa = "*" [package.extras] cryptg = ["cryptg"] +[[package]] +name = "tomli" +version = "2.0.0" +description = "A lil' TOML parser" +category = "dev" +optional = false +python-versions = ">=3.7" + +[[package]] +name = "tomlkit" +version = "0.7.0" +description = "Style preserving TOML library" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[[package]] +name = "tqdm" +version = "4.62.3" +description = "Fast, Extensible Progress Meter" +category = "dev" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + +[package.extras] +dev = ["py-make (>=0.1.0)", "twine", "wheel"] +notebook = ["ipywidgets (>=6)"] +telegram = ["requests"] + +[[package]] +name = "twine" +version = "3.7.1" +description = "Collection of utilities for publishing packages on PyPI" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +colorama = ">=0.4.3" +importlib-metadata = ">=3.6" +keyring = ">=15.1" +pkginfo = ">=1.8.1" +readme-renderer = ">=21.0" +requests = ">=2.20" +requests-toolbelt = ">=0.8.0,<0.9.0 || >0.9.0" +rfc3986 = ">=1.4.0" +tqdm = ">=4.14" + [[package]] name = "typing-extensions" version = "4.0.1" @@ -156,16 +574,57 @@ category = "main" optional = false python-versions = ">=3.6" +[[package]] +name = "urllib3" +version = "1.26.7" +description = "HTTP library with thread-safe connection pooling, file post, and more." +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" + +[package.extras] +brotli = ["brotlipy (>=0.6.0)"] +secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"] +socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] + +[[package]] +name = "webencodings" +version = "0.5.1" +description = "Character encoding aliases for legacy web content" +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "zipp" +version = "3.6.0" +description = "Backport of pathlib-compatible object wrapper for zip files" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.extras] +docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] +testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy"] + [metadata] lock-version = "1.1" python-versions = "^3.9" -content-hash = "0a00ccf15f0d214e85b7a7df54d6584faf57601f1f313df041b904b368cf5432" +content-hash = "aac971d893d4770d90abd2a2063b6f8c9bded2443752c070ebca051954048553" [metadata.files] aiorun = [ {file = "aiorun-2021.10.1-py3-none-any.whl", hash = "sha256:49c3b0ca9aa4c8ace443691d31d3114ad7a3abe7af19abb13725309dec2e3c2c"}, {file = "aiorun-2021.10.1.tar.gz", hash = "sha256:bb621493e008cd072a9b19de09a615513be2f48b594ee16ee726da5255fa4267"}, ] +bleach = [ + {file = "bleach-4.1.0-py2.py3-none-any.whl", hash = "sha256:4d2651ab93271d1129ac9cbc679f524565cc8a1b791909c4a51eac4446a15994"}, + {file = "bleach-4.1.0.tar.gz", hash = "sha256:0900d8b37eba61a802ee40ac0061f8c2b5dee29c1927dd1d233e075ebf5a71da"}, +] +certifi = [ + {file = "certifi-2021.10.8-py2.py3-none-any.whl", hash = "sha256:d62a0163eb4c2344ac042ab2bdf75399a71a2d8c7d47eac2e2ee91b9d6339569"}, + {file = "certifi-2021.10.8.tar.gz", hash = "sha256:78884e7c1d4b00ce3cea67b44566851c4343c120abd683433ce934a68ea58872"}, +] cffi = [ {file = "cffi-1.15.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:c2502a1a03b6312837279c8c1bd3ebedf6c12c4228ddbad40912d671ccc8a962"}, {file = "cffi-1.15.0-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:23cfe892bd5dd8941608f93348c0737e369e51c100d03718f108bf1add7bd6d0"}, @@ -218,6 +677,18 @@ cffi = [ {file = "cffi-1.15.0-cp39-cp39-win_amd64.whl", hash = "sha256:3773c4d81e6e818df2efbc7dd77325ca0dcb688116050fb2b3011218eda36139"}, {file = "cffi-1.15.0.tar.gz", hash = "sha256:920f0d66a896c2d99f0adbb391f990a84091179542c205fa53ce5787aff87954"}, ] +charset-normalizer = [ + {file = "charset-normalizer-2.0.9.tar.gz", hash = "sha256:b0b883e8e874edfdece9c28f314e3dd5badf067342e42fb162203335ae61aa2c"}, + {file = "charset_normalizer-2.0.9-py3-none-any.whl", hash = "sha256:1eecaa09422db5be9e29d7fc65664e6c33bd06f9ced7838578ba40d58bdf3721"}, +] +click = [ + {file = "click-8.0.3-py3-none-any.whl", hash = "sha256:353f466495adaeb40b6b5f592f9f91cb22372351c84caeb068132442a4518ef3"}, + {file = "click-8.0.3.tar.gz", hash = "sha256:410e932b050f5eed773c4cda94de75971c89cdb3155a72a0831139a79e5ecb5b"}, +] +click-log = [ + {file = "click-log-0.3.2.tar.gz", hash = "sha256:16fd1ca3fc6b16c98cea63acf1ab474ea8e676849dc669d86afafb0ed7003124"}, + {file = "click_log-0.3.2-py2.py3-none-any.whl", hash = "sha256:eee14dc37cdf3072158570f00406572f9e03e414accdccfccd4c538df9ae322c"}, +] colorama = [ {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"}, {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"}, @@ -262,6 +733,72 @@ cryptg = [ {file = "cryptg-0.2.post4-pp37-pypy37_pp73-win32.whl", hash = "sha256:2cd8224eb64af756f45cdceab16d048494313db8acec1e38d75d97716082267b"}, {file = "cryptg-0.2.post4.tar.gz", hash = "sha256:a4de1730ca56aa8a945f176c25586901ed5e9f15ffb70c6459eedf466eb6299b"}, ] +cryptography = [ + {file = "cryptography-36.0.1-cp36-abi3-macosx_10_10_universal2.whl", hash = "sha256:73bc2d3f2444bcfeac67dd130ff2ea598ea5f20b40e36d19821b4df8c9c5037b"}, + {file = "cryptography-36.0.1-cp36-abi3-macosx_10_10_x86_64.whl", hash = "sha256:2d87cdcb378d3cfed944dac30596da1968f88fb96d7fc34fdae30a99054b2e31"}, + {file = "cryptography-36.0.1-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:74d6c7e80609c0f4c2434b97b80c7f8fdfaa072ca4baab7e239a15d6d70ed73a"}, + {file = "cryptography-36.0.1-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:6c0c021f35b421ebf5976abf2daacc47e235f8b6082d3396a2fe3ccd537ab173"}, + {file = "cryptography-36.0.1-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d59a9d55027a8b88fd9fd2826c4392bd487d74bf628bb9d39beecc62a644c12"}, + {file = "cryptography-36.0.1-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0a817b961b46894c5ca8a66b599c745b9a3d9f822725221f0e0fe49dc043a3a3"}, + {file = "cryptography-36.0.1-cp36-abi3-manylinux_2_24_x86_64.whl", hash = "sha256:94ae132f0e40fe48f310bba63f477f14a43116f05ddb69d6fa31e93f05848ae2"}, + {file = "cryptography-36.0.1-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:7be0eec337359c155df191d6ae00a5e8bbb63933883f4f5dffc439dac5348c3f"}, + {file = "cryptography-36.0.1-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:e0344c14c9cb89e76eb6a060e67980c9e35b3f36691e15e1b7a9e58a0a6c6dc3"}, + {file = "cryptography-36.0.1-cp36-abi3-win32.whl", hash = "sha256:4caa4b893d8fad33cf1964d3e51842cd78ba87401ab1d2e44556826df849a8ca"}, + {file = "cryptography-36.0.1-cp36-abi3-win_amd64.whl", hash = "sha256:391432971a66cfaf94b21c24ab465a4cc3e8bf4a939c1ca5c3e3a6e0abebdbcf"}, + {file = "cryptography-36.0.1-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:bb5829d027ff82aa872d76158919045a7c1e91fbf241aec32cb07956e9ebd3c9"}, + {file = "cryptography-36.0.1-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ebc15b1c22e55c4d5566e3ca4db8689470a0ca2babef8e3a9ee057a8b82ce4b1"}, + {file = "cryptography-36.0.1-pp37-pypy37_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:596f3cd67e1b950bc372c33f1a28a0692080625592ea6392987dba7f09f17a94"}, + {file = "cryptography-36.0.1-pp38-pypy38_pp73-macosx_10_10_x86_64.whl", hash = "sha256:30ee1eb3ebe1644d1c3f183d115a8c04e4e603ed6ce8e394ed39eea4a98469ac"}, + {file = "cryptography-36.0.1-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ec63da4e7e4a5f924b90af42eddf20b698a70e58d86a72d943857c4c6045b3ee"}, + {file = "cryptography-36.0.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ca238ceb7ba0bdf6ce88c1b74a87bffcee5afbfa1e41e173b1ceb095b39add46"}, + {file = "cryptography-36.0.1-pp38-pypy38_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:ca28641954f767f9822c24e927ad894d45d5a1e501767599647259cbf030b903"}, + {file = "cryptography-36.0.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:39bdf8e70eee6b1c7b289ec6e5d84d49a6bfa11f8b8646b5b3dfe41219153316"}, + {file = "cryptography-36.0.1.tar.gz", hash = "sha256:53e5c1dc3d7a953de055d77bef2ff607ceef7a2aac0353b5d630ab67f7423638"}, +] +docutils = [ + {file = "docutils-0.18.1-py2.py3-none-any.whl", hash = "sha256:23010f129180089fbcd3bc08cfefccb3b890b0050e1ca00c867036e9d161b98c"}, + {file = "docutils-0.18.1.tar.gz", hash = "sha256:679987caf361a7539d76e584cbeddc311e3aee937877c87346f31debc63e9d06"}, +] +dotty-dict = [ + {file = "dotty_dict-1.3.0.tar.gz", hash = "sha256:eb0035a3629ecd84397a68f1f42f1e94abd1c34577a19cd3eacad331ee7cbaf0"}, +] +gitdb = [ + {file = "gitdb-4.0.9-py3-none-any.whl", hash = "sha256:8033ad4e853066ba6ca92050b9df2f89301b8fc8bf7e9324d412a63f8bf1a8fd"}, + {file = "gitdb-4.0.9.tar.gz", hash = "sha256:bac2fd45c0a1c9cf619e63a90d62bdc63892ef92387424b855792a6cabe789aa"}, +] +gitpython = [ + {file = "GitPython-3.1.24-py3-none-any.whl", hash = "sha256:dc0a7f2f697657acc8d7f89033e8b1ea94dd90356b2983bca89dc8d2ab3cc647"}, + {file = "GitPython-3.1.24.tar.gz", hash = "sha256:df83fdf5e684fef7c6ee2c02fc68a5ceb7e7e759d08b694088d0cacb4eba59e5"}, +] +idna = [ + {file = "idna-3.3-py3-none-any.whl", hash = "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff"}, + {file = "idna-3.3.tar.gz", hash = "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d"}, +] +importlib-metadata = [ + {file = "importlib_metadata-4.10.0-py3-none-any.whl", hash = "sha256:b7cf7d3fef75f1e4c80a96ca660efbd51473d7e8f39b5ab9210febc7809012a4"}, + {file = "importlib_metadata-4.10.0.tar.gz", hash = "sha256:92a8b58ce734b2a4494878e0ecf7d79ccd7a128b5fc6014c401e0b61f006f0f6"}, +] +invoke = [ + {file = "invoke-1.6.0-py2-none-any.whl", hash = "sha256:e6c9917a1e3e73e7ea91fdf82d5f151ccfe85bf30cc65cdb892444c02dbb5f74"}, + {file = "invoke-1.6.0-py3-none-any.whl", hash = "sha256:769e90caeb1bd07d484821732f931f1ad8916a38e3f3e618644687fc09cb6317"}, + {file = "invoke-1.6.0.tar.gz", hash = "sha256:374d1e2ecf78981da94bfaf95366216aaec27c2d6a7b7d5818d92da55aa258d3"}, +] +jeepney = [ + {file = "jeepney-0.7.1-py3-none-any.whl", hash = "sha256:1b5a0ea5c0e7b166b2f5895b91a08c14de8915afda4407fb5022a195224958ac"}, + {file = "jeepney-0.7.1.tar.gz", hash = "sha256:fa9e232dfa0c498bd0b8a3a73b8d8a31978304dcef0515adc859d4e096f96f4f"}, +] +keyring = [ + {file = "keyring-23.4.0-py3-none-any.whl", hash = "sha256:3dc0f66062a4f8f6f2ce30d6a516e6e623e6c3c2e76864204ceaf64695408f07"}, + {file = "keyring-23.4.0.tar.gz", hash = "sha256:88f206024295e3c6fb16bb0a60fb4bb7ec1185629dc5a729f12aa7c236d01387"}, +] +packaging = [ + {file = "packaging-21.3-py3-none-any.whl", hash = "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"}, + {file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"}, +] +pkginfo = [ + {file = "pkginfo-1.8.2-py2.py3-none-any.whl", hash = "sha256:c24c487c6a7f72c66e816ab1796b96ac6c3d14d49338293d2141664330b55ffc"}, + {file = "pkginfo-1.8.2.tar.gz", hash = "sha256:542e0d0b6750e2e21c20179803e40ab50598d8066d51097a0e382cba9eb02bff"}, +] pyaes = [ {file = "pyaes-1.6.1.tar.gz", hash = "sha256:02c1b1405c38d3c370b085fb952dd8bea3fadcee6411ad99f312cc129c536d8f"}, ] @@ -312,6 +849,22 @@ pygments = [ {file = "Pygments-2.10.0-py3-none-any.whl", hash = "sha256:b8e67fe6af78f492b3c4b3e2970c0624cbf08beb1e493b2c99b9fa1b67a20380"}, {file = "Pygments-2.10.0.tar.gz", hash = "sha256:f398865f7eb6874156579fdf36bc840a03cab64d1cde9e93d68f46a425ec52c6"}, ] +pyparsing = [ + {file = "pyparsing-3.0.6-py3-none-any.whl", hash = "sha256:04ff808a5b90911829c55c4e26f75fa5ca8a2f5f36aa3a51f68e27033341d3e4"}, + {file = "pyparsing-3.0.6.tar.gz", hash = "sha256:d9bdec0013ef1eb5a84ab39a3b3868911598afa494f5faa038647101504e2b81"}, +] +python-gitlab = [ + {file = "python-gitlab-2.10.1.tar.gz", hash = "sha256:7afa7d7c062fa62c173190452265a30feefb844428efc58ea5244f3b9fc0d40f"}, + {file = "python_gitlab-2.10.1-py3-none-any.whl", hash = "sha256:581a219759515513ea9399e936ed7137437cfb681f52d2641626685c492c999d"}, +] +python-semantic-release = [ + {file = "python-semantic-release-7.23.0.tar.gz", hash = "sha256:48c33bf671dafa1257e7d955543856eb98486a3f976f586053556ae180d725da"}, + {file = "python_semantic_release-7.23.0-py3-none-any.whl", hash = "sha256:5bf7fcdb28e5e9888c9a15a1168afe53302116a6874d818580d4c58db60283ab"}, +] +pywin32-ctypes = [ + {file = "pywin32-ctypes-0.2.0.tar.gz", hash = "sha256:24ffc3b341d457d48e8922352130cf2644024a4ff09762a2261fd34c36ee5942"}, + {file = "pywin32_ctypes-0.2.0-py2.py3-none-any.whl", hash = "sha256:9dc2d991b3479cc2df15930958b674a48a227d5361d413827a4cfd0b5876fc98"}, +] pyyaml = [ {file = "PyYAML-6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53"}, {file = "PyYAML-6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c"}, @@ -347,6 +900,22 @@ pyyaml = [ {file = "PyYAML-6.0-cp39-cp39-win_amd64.whl", hash = "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c"}, {file = "PyYAML-6.0.tar.gz", hash = "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2"}, ] +readme-renderer = [ + {file = "readme_renderer-32.0-py3-none-any.whl", hash = "sha256:a50a0f2123a4c1145ac6f420e1a348aafefcc9211c846e3d51df05fe3d865b7d"}, + {file = "readme_renderer-32.0.tar.gz", hash = "sha256:b512beafa6798260c7d5af3e1b1f097e58bfcd9a575da7c4ddd5e037490a5b85"}, +] +requests = [ + {file = "requests-2.26.0-py2.py3-none-any.whl", hash = "sha256:6c1246513ecd5ecd4528a0906f910e8f0f9c6b8ec72030dc9fd154dc1a6efd24"}, + {file = "requests-2.26.0.tar.gz", hash = "sha256:b8aa58f8cf793ffd8782d3d8cb19e66ef36f7aba4353eec859e74678b01b07a7"}, +] +requests-toolbelt = [ + {file = "requests-toolbelt-0.9.1.tar.gz", hash = "sha256:968089d4584ad4ad7c171454f0a5c6dac23971e9472521ea3b6d49d610aa6fc0"}, + {file = "requests_toolbelt-0.9.1-py2.py3-none-any.whl", hash = "sha256:380606e1d10dc85c3bd47bf5a6095f815ec007be7a8b69c878507068df059e6f"}, +] +rfc3986 = [ + {file = "rfc3986-1.5.0-py2.py3-none-any.whl", hash = "sha256:a86d6e1f5b1dc238b218b012df0aa79409667bb209e58da56d0b94704e712a97"}, + {file = "rfc3986-1.5.0.tar.gz", hash = "sha256:270aaf10d87d0d4e095063c65bf3ddbc6ee3d0b226328ce21e036f946e421835"}, +] rich = [ {file = "rich-10.16.1-py3-none-any.whl", hash = "sha256:bbe04dd6ac09e4b00d22cb1051aa127beaf6e16c3d8687b026e96d3fca6aad52"}, {file = "rich-10.16.1.tar.gz", hash = "sha256:4949e73de321784ef6664ebbc854ac82b20ff60b2865097b93f3b9b41e30da27"}, @@ -355,11 +924,59 @@ rsa = [ {file = "rsa-4.8-py3-none-any.whl", hash = "sha256:95c5d300c4e879ee69708c428ba566c59478fd653cc3a22243eeb8ed846950bb"}, {file = "rsa-4.8.tar.gz", hash = "sha256:5c6bd9dc7a543b7fe4304a631f8a8a3b674e2bbfc49c2ae96200cdbe55df6b17"}, ] +secretstorage = [ + {file = "SecretStorage-3.3.1-py3-none-any.whl", hash = "sha256:422d82c36172d88d6a0ed5afdec956514b189ddbfb72fefab0c8a1cee4eaf71f"}, + {file = "SecretStorage-3.3.1.tar.gz", hash = "sha256:fd666c51a6bf200643495a04abb261f83229dcb6fd8472ec393df7ffc8b6f195"}, +] +semver = [ + {file = "semver-2.13.0-py2.py3-none-any.whl", hash = "sha256:ced8b23dceb22134307c1b8abfa523da14198793d9787ac838e70e29e77458d4"}, + {file = "semver-2.13.0.tar.gz", hash = "sha256:fa0fe2722ee1c3f57eac478820c3a5ae2f624af8264cbdf9000c980ff7f75e3f"}, +] +setuptools-scm = [ + {file = "setuptools_scm-6.3.2-py3-none-any.whl", hash = "sha256:4c64444b1d49c4063ae60bfe1680f611c8b13833d556fd1d6050c0023162a119"}, + {file = "setuptools_scm-6.3.2.tar.gz", hash = "sha256:a49aa8081eeb3514eb9728fa5040f2eaa962d6c6f4ec9c32f6c1fba88f88a0f2"}, +] +six = [ + {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, + {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, +] +smmap = [ + {file = "smmap-5.0.0-py3-none-any.whl", hash = "sha256:2aba19d6a040e78d8b09de5c57e96207b09ed71d8e55ce0959eeee6c8e190d94"}, + {file = "smmap-5.0.0.tar.gz", hash = "sha256:c840e62059cd3be204b0c9c9f74be2c09d5648eddd4580d9314c3ecde0b30936"}, +] telethon = [ {file = "Telethon-1.24.0-py3-none-any.whl", hash = "sha256:04fdc5fa4ed3e886e6ecf4bad79205ab8880c6aefbd42c29c89c689a502aa816"}, {file = "Telethon-1.24.0.tar.gz", hash = "sha256:818cb61281ed3f75ba4da9b68cb69486bed9474d2db4e0aa16e482053117452c"}, ] +tomli = [ + {file = "tomli-2.0.0-py3-none-any.whl", hash = "sha256:b5bde28da1fed24b9bd1d4d2b8cba62300bfb4ec9a6187a957e8ddb9434c5224"}, + {file = "tomli-2.0.0.tar.gz", hash = "sha256:c292c34f58502a1eb2bbb9f5bbc9a5ebc37bee10ffb8c2d6bbdfa8eb13cc14e1"}, +] +tomlkit = [ + {file = "tomlkit-0.7.0-py2.py3-none-any.whl", hash = "sha256:6babbd33b17d5c9691896b0e68159215a9387ebfa938aa3ac42f4a4beeb2b831"}, + {file = "tomlkit-0.7.0.tar.gz", hash = "sha256:ac57f29693fab3e309ea789252fcce3061e19110085aa31af5446ca749325618"}, +] +tqdm = [ + {file = "tqdm-4.62.3-py2.py3-none-any.whl", hash = "sha256:8dd278a422499cd6b727e6ae4061c40b48fce8b76d1ccbf5d34fca9b7f925b0c"}, + {file = "tqdm-4.62.3.tar.gz", hash = "sha256:d359de7217506c9851b7869f3708d8ee53ed70a1b8edbba4dbcb47442592920d"}, +] +twine = [ + {file = "twine-3.7.1-py3-none-any.whl", hash = "sha256:8c120845fc05270f9ee3e9d7ebbed29ea840e41f48cd059e04733f7e1d401345"}, + {file = "twine-3.7.1.tar.gz", hash = "sha256:28460a3db6b4532bde6a5db6755cf2dce6c5020bada8a641bb2c5c7a9b1f35b8"}, +] typing-extensions = [ {file = "typing_extensions-4.0.1-py3-none-any.whl", hash = "sha256:7f001e5ac290a0c0401508864c7ec868be4e701886d5b573a9528ed3973d9d3b"}, {file = "typing_extensions-4.0.1.tar.gz", hash = "sha256:4ca091dea149f945ec56afb48dae714f21e8692ef22a395223bcd328961b6a0e"}, ] +urllib3 = [ + {file = "urllib3-1.26.7-py2.py3-none-any.whl", hash = "sha256:c4fdf4019605b6e5423637e01bc9fe4daef873709a7973e195ceba0a62bbc844"}, + {file = "urllib3-1.26.7.tar.gz", hash = "sha256:4987c65554f7a2dbf30c18fd48778ef124af6fab771a377103da0585e2336ece"}, +] +webencodings = [ + {file = "webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78"}, + {file = "webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923"}, +] +zipp = [ + {file = "zipp-3.6.0-py3-none-any.whl", hash = "sha256:9fe5ea21568a0a70e50f273397638d39b03353731e6cbbb3fd8502a33fec40bc"}, + {file = "zipp-3.6.0.tar.gz", hash = "sha256:71c644c5369f4a6e07636f0aa966270449561fcea2e3d6747b8d23efaa9d7832"}, +] diff --git a/pyproject.toml b/pyproject.toml index 40e826b..629a2ba 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "tgpy" -version = "0.1.0.post2" +version = "0.1.0" description = "Run Python code right in your Telegram messages" authors = ["tmat ", "vanutp ", "ntonee "] license = "MIT" @@ -14,6 +14,18 @@ classifiers = [ [tool.poetry.scripts] tgpy = 'tgpy.main:main' +[tool.semantic_release] +version_variable = [ + "tgpy/__init__.py:__version__", + "pyproject.toml:version" +] +branch = "master" +upload_to_pypi = true +upload_to_release = true +build_command = "poetry build" +commit_subject = 'chore(release): v{version} [skip ci]' +commit_message = '' + [tool.poetry.dependencies] python = "^3.9" Telethon = "^1.24.0" @@ -24,6 +36,7 @@ aiorun = "^2021.10.1" rich = "^10.16.1" [tool.poetry.dev-dependencies] +python-semantic-release = "^7.23.0" [build-system] requires = ["poetry-core>=1.0.0"] diff --git a/tgpy/__init__.py b/tgpy/__init__.py index 2dd8506..ae093d7 100644 --- a/tgpy/__init__.py +++ b/tgpy/__init__.py @@ -7,7 +7,7 @@ from tgpy.console import console -__version__ = "0.1.0.post2" +__version__ = "0.1.0" logging.basicConfig(level=logging.INFO, format='%(message)s', datefmt="[%X]", handlers=[RichHandler()])