maxapi-python 1.1.13__tar.gz → 1.1.14__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {maxapi_python-1.1.13 → maxapi_python-1.1.14}/.github/ISSUE_TEMPLATE/bug_report.md +3 -3
- {maxapi_python-1.1.13 → maxapi_python-1.1.14}/.github/workflows/publish.yml +1 -1
- {maxapi_python-1.1.13 → maxapi_python-1.1.14}/.gitignore +1 -1
- maxapi_python-1.1.14/.pre-commit-config.yaml +41 -0
- {maxapi_python-1.1.13 → maxapi_python-1.1.14}/PKG-INFO +1 -1
- {maxapi_python-1.1.13 → maxapi_python-1.1.14}/assets/icon.svg +0 -1
- {maxapi_python-1.1.13 → maxapi_python-1.1.14}/assets/logo.svg +0 -1
- {maxapi_python-1.1.13 → maxapi_python-1.1.14}/docs/assets/icon.svg +0 -1
- {maxapi_python-1.1.13 → maxapi_python-1.1.14}/docs/client.md +2 -2
- {maxapi_python-1.1.13 → maxapi_python-1.1.14}/docs/examples.md +11 -11
- {maxapi_python-1.1.13 → maxapi_python-1.1.14}/examples/example.py +9 -5
- maxapi_python-1.1.14/examples/telegram_bridge.py +202 -0
- maxapi_python-1.1.14/pyproject.toml +72 -0
- {maxapi_python-1.1.13 → maxapi_python-1.1.14}/ruff.toml +1 -1
- {maxapi_python-1.1.13 → maxapi_python-1.1.14}/src/pymax/__init__.py +7 -5
- {maxapi_python-1.1.13 → maxapi_python-1.1.14}/src/pymax/core.py +20 -54
- {maxapi_python-1.1.13 → maxapi_python-1.1.14}/src/pymax/crud.py +10 -9
- {maxapi_python-1.1.13 → maxapi_python-1.1.14}/src/pymax/exceptions.py +18 -0
- {maxapi_python-1.1.13 → maxapi_python-1.1.14}/src/pymax/files.py +13 -4
- {maxapi_python-1.1.13 → maxapi_python-1.1.14}/src/pymax/filters.py +8 -3
- {maxapi_python-1.1.13 → maxapi_python-1.1.14}/src/pymax/formatting.py +4 -4
- {maxapi_python-1.1.13 → maxapi_python-1.1.14}/src/pymax/interfaces.py +9 -15
- {maxapi_python-1.1.13 → maxapi_python-1.1.14}/src/pymax/mixins/auth.py +23 -5
- maxapi_python-1.1.14/src/pymax/mixins/channel.py +115 -0
- {maxapi_python-1.1.13 → maxapi_python-1.1.14}/src/pymax/mixins/group.py +30 -10
- {maxapi_python-1.1.13 → maxapi_python-1.1.14}/src/pymax/mixins/handler.py +15 -14
- {maxapi_python-1.1.13 → maxapi_python-1.1.14}/src/pymax/mixins/message.py +79 -32
- {maxapi_python-1.1.13 → maxapi_python-1.1.14}/src/pymax/mixins/self.py +4 -2
- {maxapi_python-1.1.13 → maxapi_python-1.1.14}/src/pymax/mixins/socket.py +143 -75
- {maxapi_python-1.1.13 → maxapi_python-1.1.14}/src/pymax/mixins/telemetry.py +11 -6
- {maxapi_python-1.1.13 → maxapi_python-1.1.14}/src/pymax/mixins/user.py +23 -1
- {maxapi_python-1.1.13 → maxapi_python-1.1.14}/src/pymax/mixins/websocket.py +82 -39
- {maxapi_python-1.1.13 → maxapi_python-1.1.14}/src/pymax/navigation.py +3 -1
- {maxapi_python-1.1.13 → maxapi_python-1.1.14}/src/pymax/payloads.py +39 -8
- maxapi_python-1.1.14/src/pymax/static/constant.py +26 -0
- maxapi_python-1.1.13/src/pymax/static.py → maxapi_python-1.1.14/src/pymax/static/enum.py +12 -31
- {maxapi_python-1.1.13 → maxapi_python-1.1.14}/src/pymax/types.py +309 -39
- {maxapi_python-1.1.13 → maxapi_python-1.1.14}/src/pymax/utils.py +11 -3
- maxapi_python-1.1.13/pyproject.toml +0 -50
- maxapi_python-1.1.13/scripts/build.py +0 -47
- maxapi_python-1.1.13/src/pymax/mixins/channel.py +0 -25
- {maxapi_python-1.1.13 → maxapi_python-1.1.14}/.github/FUNDING.yml +0 -0
- {maxapi_python-1.1.13 → maxapi_python-1.1.14}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {maxapi_python-1.1.13 → maxapi_python-1.1.14}/.github/ISSUE_TEMPLATE/refactor.md +0 -0
- {maxapi_python-1.1.13 → maxapi_python-1.1.14}/.github/pull_request_template.md +0 -0
- {maxapi_python-1.1.13 → maxapi_python-1.1.14}/LICENSE +0 -0
- {maxapi_python-1.1.13 → maxapi_python-1.1.14}/README.md +0 -0
- {maxapi_python-1.1.13 → maxapi_python-1.1.14}/docs/api.md +0 -0
- {maxapi_python-1.1.13 → maxapi_python-1.1.14}/docs/index.md +0 -0
- {maxapi_python-1.1.13 → maxapi_python-1.1.14}/docs/methods.md +0 -0
- {maxapi_python-1.1.13 → maxapi_python-1.1.14}/docs/types.md +0 -0
- {maxapi_python-1.1.13 → maxapi_python-1.1.14}/mkdocs.yml +0 -0
- {maxapi_python-1.1.13 → maxapi_python-1.1.14}/src/pymax/mixins/__init__.py +0 -0
- {maxapi_python-1.1.13 → maxapi_python-1.1.14}/src/pymax/models.py +0 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
repos:
|
|
2
|
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
3
|
+
rev: v6.0.0
|
|
4
|
+
hooks:
|
|
5
|
+
- id: check-case-conflict
|
|
6
|
+
- id: check-docstring-first
|
|
7
|
+
- id: check-executables-have-shebangs
|
|
8
|
+
- id: check-shebang-scripts-are-executable
|
|
9
|
+
- id: check-yaml
|
|
10
|
+
- id: end-of-file-fixer
|
|
11
|
+
- id: fix-byte-order-marker
|
|
12
|
+
- id: mixed-line-ending
|
|
13
|
+
- id: name-tests-test
|
|
14
|
+
- id: trailing-whitespace
|
|
15
|
+
- repo: https://github.com/psf/black
|
|
16
|
+
rev: 25.9.0
|
|
17
|
+
hooks:
|
|
18
|
+
- id: black
|
|
19
|
+
- repo: https://github.com/csachs/pyproject-flake8
|
|
20
|
+
rev: v7.0.0
|
|
21
|
+
hooks:
|
|
22
|
+
- id: pyproject-flake8
|
|
23
|
+
- repo: https://github.com/pre-commit/mirrors-mypy
|
|
24
|
+
rev: v1.18.2
|
|
25
|
+
hooks:
|
|
26
|
+
- id: mypy
|
|
27
|
+
additional_dependencies:
|
|
28
|
+
- "aiohttp"
|
|
29
|
+
- "sqlalchemy"
|
|
30
|
+
- "sqlmodel"
|
|
31
|
+
- "types-aiofiles"
|
|
32
|
+
- "types-requests"
|
|
33
|
+
exclude: "^examples/"
|
|
34
|
+
- repo: https://github.com/pycqa/isort
|
|
35
|
+
rev: 7.0.0
|
|
36
|
+
hooks:
|
|
37
|
+
- id: isort
|
|
38
|
+
- repo: https://github.com/PyCQA/bandit
|
|
39
|
+
rev: 1.8.6
|
|
40
|
+
hooks:
|
|
41
|
+
- id: bandit
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
client = MaxClient(
|
|
20
20
|
phone: str,
|
|
21
21
|
uri: str = Constants.WEBSOCKET_URI.value,
|
|
22
|
-
headers: dict[str, Any] | None = Constants.
|
|
22
|
+
headers: dict[str, Any] | None = Constants.DEFAULT_USER_AGENT_PAYLOAD.value,
|
|
23
23
|
token: str | None = None,
|
|
24
24
|
send_fake_telemetry: bool = True,
|
|
25
25
|
host: str = Constants.HOST.value,
|
|
@@ -35,7 +35,7 @@ client = MaxClient(
|
|
|
35
35
|
|----------|-----|----------|---------------|
|
|
36
36
|
| `phone` | `str` | Номер телефона для авторизации | - |
|
|
37
37
|
| `uri` | `str` | URI WebSocket сервера | `Constants.WEBSOCKET_URI.value` |
|
|
38
|
-
| `headers` | `dict[str, Any] \| None` | Заголовки для соединения | `Constants.
|
|
38
|
+
| `headers` | `dict[str, Any] \| None` | Заголовки для соединения | `Constants.DEFAULT_USER_AGENT_PAYLOAD.value` |
|
|
39
39
|
| `token` | `str \| None` | Токен авторизации | `None` |
|
|
40
40
|
| `send_fake_telemetry` | `bool` | Отправка телеметрии | `True` |
|
|
41
41
|
| `host` | `str` | Хост API сервера | `Constants.HOST.value` |
|
|
@@ -8,14 +8,14 @@ from pymax import MaxClient
|
|
|
8
8
|
|
|
9
9
|
async def main():
|
|
10
10
|
client = MaxClient(phone="+79001234567")
|
|
11
|
-
|
|
11
|
+
|
|
12
12
|
@client.on_message
|
|
13
13
|
async def echo_handler(message):
|
|
14
14
|
await client.send_message(
|
|
15
15
|
chat_id=message.chat_id,
|
|
16
16
|
text=f"Эхо: {message.text}"
|
|
17
17
|
)
|
|
18
|
-
|
|
18
|
+
|
|
19
19
|
await client.start()
|
|
20
20
|
|
|
21
21
|
asyncio.run(main())
|
|
@@ -29,7 +29,7 @@ from pymax import MaxClient
|
|
|
29
29
|
|
|
30
30
|
async def main():
|
|
31
31
|
client = MaxClient(phone="+79001234567")
|
|
32
|
-
|
|
32
|
+
|
|
33
33
|
# Словарь ключевых слов и ответов
|
|
34
34
|
auto_replies = {
|
|
35
35
|
'привет': 'Привет! Как дела?',
|
|
@@ -37,11 +37,11 @@ async def main():
|
|
|
37
37
|
'спасибо': 'Пожалуйста!',
|
|
38
38
|
'время': 'Время ответить на ваш вопрос!',
|
|
39
39
|
}
|
|
40
|
-
|
|
40
|
+
|
|
41
41
|
@client.on_message
|
|
42
42
|
async def auto_reply_handler(message):
|
|
43
43
|
text = message.text.lower()
|
|
44
|
-
|
|
44
|
+
|
|
45
45
|
for keyword, reply in auto_replies.items():
|
|
46
46
|
if keyword in text:
|
|
47
47
|
await client.send_message(
|
|
@@ -49,7 +49,7 @@ async def main():
|
|
|
49
49
|
text=reply
|
|
50
50
|
)
|
|
51
51
|
break
|
|
52
|
-
|
|
52
|
+
|
|
53
53
|
await client.start()
|
|
54
54
|
|
|
55
55
|
asyncio.run(main())
|
|
@@ -63,14 +63,14 @@ from pymax import MaxClient
|
|
|
63
63
|
|
|
64
64
|
async def main():
|
|
65
65
|
client = MaxClient(phone="+79001234567")
|
|
66
|
-
|
|
66
|
+
|
|
67
67
|
# Запрещенные слова
|
|
68
68
|
forbidden_words = ['спам', 'реклама', 'взлом']
|
|
69
|
-
|
|
69
|
+
|
|
70
70
|
@client.on_message
|
|
71
71
|
async def moderation_handler(message):
|
|
72
72
|
text = message.text.lower()
|
|
73
|
-
|
|
73
|
+
|
|
74
74
|
for word in forbidden_words:
|
|
75
75
|
if word in text:
|
|
76
76
|
# Удаляем сообщение
|
|
@@ -78,14 +78,14 @@ async def main():
|
|
|
78
78
|
chat_id=message.chat_id,
|
|
79
79
|
message_id=message.id
|
|
80
80
|
)
|
|
81
|
-
|
|
81
|
+
|
|
82
82
|
# Предупреждаем пользователя
|
|
83
83
|
await client.send_message(
|
|
84
84
|
chat_id=message.chat_id,
|
|
85
85
|
text=f"@{message.author.username}, использование запрещенных слов недопустимо!"
|
|
86
86
|
)
|
|
87
87
|
break
|
|
88
|
-
|
|
88
|
+
|
|
89
89
|
await client.start()
|
|
90
90
|
|
|
91
91
|
asyncio.run(main())
|
|
@@ -1,16 +1,13 @@
|
|
|
1
1
|
import asyncio
|
|
2
|
-
import logging
|
|
3
2
|
|
|
4
|
-
from pymax import MaxClient, Message
|
|
5
|
-
from pymax.files import Photo
|
|
3
|
+
from pymax import MaxClient, Message
|
|
6
4
|
from pymax.filters import Filter
|
|
7
|
-
from pymax.static import AttachType
|
|
5
|
+
from pymax.static.enum import AttachType
|
|
8
6
|
|
|
9
7
|
phone = "+1234567890"
|
|
10
8
|
|
|
11
9
|
|
|
12
10
|
client = MaxClient(phone=phone, work_dir="cache")
|
|
13
|
-
# client = SocketMaxClient(phone=phone, work_dir="cache")
|
|
14
11
|
|
|
15
12
|
|
|
16
13
|
@client.on_message(filter=Filter(chat_id=0))
|
|
@@ -31,6 +28,13 @@ async def handle_deleted_message(message: Message) -> None:
|
|
|
31
28
|
@client.on_start
|
|
32
29
|
async def handle_start() -> None:
|
|
33
30
|
print("Client started successfully!")
|
|
31
|
+
history = await client.fetch_history(chat_id=0)
|
|
32
|
+
if history:
|
|
33
|
+
for message in history:
|
|
34
|
+
if message.attaches:
|
|
35
|
+
for attach in message.attaches:
|
|
36
|
+
if attach.type == AttachType.STICKER:
|
|
37
|
+
print(attach.lottie_url)
|
|
34
38
|
# chat = await client.rework_invite_link(chat_id=0)
|
|
35
39
|
# print(chat.link)
|
|
36
40
|
# text = """
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import os
|
|
3
|
+
from io import BytesIO
|
|
4
|
+
|
|
5
|
+
import aiohttp
|
|
6
|
+
from aiogram import Bot, Dispatcher, types
|
|
7
|
+
from dotenv import load_dotenv
|
|
8
|
+
|
|
9
|
+
from pymax import Chat, MaxClient, Message, User
|
|
10
|
+
from pymax.types import FileAttach, PhotoAttach, VideoAttach
|
|
11
|
+
|
|
12
|
+
"""
|
|
13
|
+
Зависимости:
|
|
14
|
+
|
|
15
|
+
pip install maxapi-python==1.1.13 aiogram==3.22.0 python-dotenv
|
|
16
|
+
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
"""
|
|
21
|
+
В .env нужно указать:
|
|
22
|
+
|
|
23
|
+
PHONE = "+7123456789" # Твой номер для Max
|
|
24
|
+
BOT_TOKEN = "23456789:AAH0cJ3SNzZ2zzD0uF8HOqmxtKpwsKwggM" # Твой токен Telegram-бота
|
|
25
|
+
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
chats = { # В формате айди чата в Max: айди чата в Telegram
|
|
29
|
+
-68690734055662: -1003177746657,
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
# Создаём зеркальный массив для отправки из Telegram в Max
|
|
34
|
+
chats_telegram = {value: key for key, value in chats.items()}
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
# Загружаем .env
|
|
38
|
+
load_dotenv(override=True)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
# Настройки из .env
|
|
42
|
+
PHONE = os.getenv("PHONE") # Номер телефона Max
|
|
43
|
+
telegram_bot_TOKEN = os.getenv("BOT_TOKEN") # Токен TG-бота
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
client = MaxClient(phone=PHONE, work_dir="cache")
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
# Инициализация TG-бота
|
|
50
|
+
telegram_bot = Bot(token=telegram_bot_TOKEN)
|
|
51
|
+
dp = Dispatcher()
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
# Обработчик входящих сообщений MAX
|
|
55
|
+
@client.on_message()
|
|
56
|
+
async def handle_message(message: Message) -> None:
|
|
57
|
+
tg_id = chats[message.chat_id]
|
|
58
|
+
|
|
59
|
+
sender = await client.get_user(user_id=message.sender)
|
|
60
|
+
|
|
61
|
+
if message.attaches:
|
|
62
|
+
for attach in message.attaches:
|
|
63
|
+
# Проверка на видео
|
|
64
|
+
if isinstance(attach, VideoAttach):
|
|
65
|
+
async with aiohttp.ClientSession() as session:
|
|
66
|
+
try:
|
|
67
|
+
# Получаем видео по айди
|
|
68
|
+
video = await client.get_video_by_id(
|
|
69
|
+
chat_id=message.chat_id,
|
|
70
|
+
message_id=message.id,
|
|
71
|
+
video_id=attach.video_id,
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
# Загружаем видео по URL
|
|
75
|
+
async with session.get(video.url) as response:
|
|
76
|
+
response.raise_for_status() # Проверка на ошибки HTTP
|
|
77
|
+
video_bytes = BytesIO(await response.read())
|
|
78
|
+
video_bytes.name = response.headers.get("X-File-Name")
|
|
79
|
+
|
|
80
|
+
# Отправляем видео через телеграм бота
|
|
81
|
+
await telegram_bot.send_video(
|
|
82
|
+
chat_id=tg_id,
|
|
83
|
+
caption=f"{sender.names[0].name}: {message.text}",
|
|
84
|
+
video=types.BufferedInputFile(
|
|
85
|
+
video_bytes.getvalue(), filename=video_bytes.name
|
|
86
|
+
),
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
# Очищаем память
|
|
90
|
+
video_bytes.close()
|
|
91
|
+
|
|
92
|
+
except aiohttp.ClientError as e:
|
|
93
|
+
print(f"Ошибка при загрузке видео: {e}")
|
|
94
|
+
except Exception as e:
|
|
95
|
+
print(f"Ошибка при отправке видео: {e}")
|
|
96
|
+
|
|
97
|
+
# Проверка на изображение
|
|
98
|
+
elif isinstance(attach, PhotoAttach):
|
|
99
|
+
async with aiohttp.ClientSession() as session:
|
|
100
|
+
try:
|
|
101
|
+
# Загружаем изображение по URL
|
|
102
|
+
async with session.get(attach.base_url) as response:
|
|
103
|
+
response.raise_for_status() # Проверка на ошибки HTTP
|
|
104
|
+
photo_bytes = BytesIO(await response.read())
|
|
105
|
+
photo_bytes.name = response.headers.get("X-File-Name")
|
|
106
|
+
|
|
107
|
+
# Отправляем фото через телеграм бота
|
|
108
|
+
await telegram_bot.send_photo(
|
|
109
|
+
chat_id=tg_id,
|
|
110
|
+
caption=f"{sender.names[0].name}: {message.text}",
|
|
111
|
+
photo=types.BufferedInputFile(
|
|
112
|
+
photo_bytes.getvalue(), filename=photo_bytes.name
|
|
113
|
+
),
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
# Очищаем память
|
|
117
|
+
photo_bytes.close()
|
|
118
|
+
|
|
119
|
+
except aiohttp.ClientError as e:
|
|
120
|
+
print(f"Ошибка при загрузке изображения: {e}")
|
|
121
|
+
except Exception as e:
|
|
122
|
+
print(f"Ошибка при отправке фото: {e}")
|
|
123
|
+
|
|
124
|
+
# Проверка на файл
|
|
125
|
+
elif isinstance(attach, FileAttach):
|
|
126
|
+
async with aiohttp.ClientSession() as session:
|
|
127
|
+
try:
|
|
128
|
+
# Получаем файл по айди
|
|
129
|
+
file = await client.get_file_by_id(
|
|
130
|
+
chat_id=message.chat_id,
|
|
131
|
+
message_id=message.id,
|
|
132
|
+
file_id=attach.file_id,
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
# Загружаем файл по URL
|
|
136
|
+
async with session.get(file.url) as response:
|
|
137
|
+
response.raise_for_status() # Проверка на ошибки HTTP
|
|
138
|
+
file_bytes = BytesIO(await response.read())
|
|
139
|
+
file_bytes.name = response.headers.get("X-File-Name")
|
|
140
|
+
|
|
141
|
+
# Отправляем файл через телеграм бота
|
|
142
|
+
await telegram_bot.send_document(
|
|
143
|
+
chat_id=tg_id,
|
|
144
|
+
caption=f"{sender.names[0].name}: {message.text}",
|
|
145
|
+
document=types.BufferedInputFile(
|
|
146
|
+
file_bytes.getvalue(), filename=file_bytes.name
|
|
147
|
+
),
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
# Очищаем память
|
|
151
|
+
file_bytes.close()
|
|
152
|
+
|
|
153
|
+
except aiohttp.ClientError as e:
|
|
154
|
+
print(f"Ошибка при загрузке файла: {e}")
|
|
155
|
+
except Exception as e:
|
|
156
|
+
print(f"Ошибка при отправке файла: {e}")
|
|
157
|
+
else:
|
|
158
|
+
await telegram_bot.send_message(
|
|
159
|
+
chat_id=tg_id, text=f"{sender.names[0].name}: {message.text}"
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
# Обработчик запуска клиента, функция выводит все сообщения из чата "Избранное"
|
|
164
|
+
@client.on_start
|
|
165
|
+
async def handle_start() -> None:
|
|
166
|
+
print("Клиент запущен")
|
|
167
|
+
|
|
168
|
+
# Получение истории сообщений
|
|
169
|
+
history = await client.fetch_history(chat_id=0)
|
|
170
|
+
if history:
|
|
171
|
+
for message in history:
|
|
172
|
+
user = await client.get_user(message.sender)
|
|
173
|
+
if user:
|
|
174
|
+
print(f"{user.names[0].name}: {message.text}")
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
# Обработчик сообщений Telegram
|
|
178
|
+
@dp.message()
|
|
179
|
+
async def handle_message(message: types.Message, bot: Bot) -> None:
|
|
180
|
+
max_id = chats_telegram[message.chat.id]
|
|
181
|
+
await client.send_message(chat_id=max_id, text=message.text, notify=True)
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
# Раннер ботов
|
|
185
|
+
async def main() -> None:
|
|
186
|
+
# TG-бот в фоне
|
|
187
|
+
telegram_bot_task = asyncio.create_task(dp.start_polling(telegram_bot))
|
|
188
|
+
|
|
189
|
+
try:
|
|
190
|
+
while True: # Не спрашивайте 😃
|
|
191
|
+
await client.start()
|
|
192
|
+
|
|
193
|
+
finally:
|
|
194
|
+
await client.close()
|
|
195
|
+
telegram_bot_task.cancel()
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
if __name__ == "__main__":
|
|
199
|
+
try:
|
|
200
|
+
asyncio.run(main())
|
|
201
|
+
except KeyboardInterrupt:
|
|
202
|
+
print("Программа остановлена пользователем.")
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "maxapi-python"
|
|
3
|
+
version = "1.1.14"
|
|
4
|
+
description = "Python wrapper для API мессенджера Max"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.10"
|
|
7
|
+
authors = [{ name = "ink", email = "mail@gmail.com" }]
|
|
8
|
+
license = "MIT"
|
|
9
|
+
keywords = ["max", "messenger", "api", "wrapper", "websocket"]
|
|
10
|
+
classifiers = [
|
|
11
|
+
"Programming Language :: Python :: 3",
|
|
12
|
+
"Operating System :: OS Independent",
|
|
13
|
+
]
|
|
14
|
+
dependencies = [
|
|
15
|
+
"sqlmodel>=0.0.24",
|
|
16
|
+
"websockets>=15.0",
|
|
17
|
+
"msgpack>=1.1.1",
|
|
18
|
+
"lz4>=4.4.4",
|
|
19
|
+
"aiohttp>=3.12.15",
|
|
20
|
+
"aiofiles>=24.1.0",
|
|
21
|
+
]
|
|
22
|
+
|
|
23
|
+
[project.urls]
|
|
24
|
+
Homepage = "https://github.com/ink-developer/PyMax"
|
|
25
|
+
Repository = "https://github.com/ink-developer/PyMax"
|
|
26
|
+
Issues = "https://github.com/ink-developer/PyMax/issues"
|
|
27
|
+
|
|
28
|
+
[build-system]
|
|
29
|
+
requires = ["hatchling"]
|
|
30
|
+
build-backend = "hatchling.build"
|
|
31
|
+
|
|
32
|
+
[tool.setuptools.packages.find]
|
|
33
|
+
where = ["src"]
|
|
34
|
+
|
|
35
|
+
[tool.setuptools.package-dir]
|
|
36
|
+
"" = "src"
|
|
37
|
+
|
|
38
|
+
[dependency-groups]
|
|
39
|
+
dev = [
|
|
40
|
+
"mkdocs>=1.6.1",
|
|
41
|
+
"mkdocs-material>=9.6.18",
|
|
42
|
+
"mkdocstrings[python]>=0.30.0",
|
|
43
|
+
"pre-commit>=4.3.0",
|
|
44
|
+
"pydocstring>=0.2.1",
|
|
45
|
+
]
|
|
46
|
+
|
|
47
|
+
[tool.hatch.build.targets.wheel]
|
|
48
|
+
packages = ["src/pymax"]
|
|
49
|
+
|
|
50
|
+
[tool.pyright]
|
|
51
|
+
venv = ".venv"
|
|
52
|
+
venvPath = "."
|
|
53
|
+
|
|
54
|
+
[tool.black]
|
|
55
|
+
line-length = 79
|
|
56
|
+
target-version = ['py313']
|
|
57
|
+
|
|
58
|
+
[tool.flake8]
|
|
59
|
+
max-line-length = 79
|
|
60
|
+
max-complexity = 10
|
|
61
|
+
|
|
62
|
+
[tool.mypy]
|
|
63
|
+
python_version = "3.13"
|
|
64
|
+
warn_return_any = true
|
|
65
|
+
warn_unused_configs = true
|
|
66
|
+
plugins = ["sqlalchemy.ext.mypy.plugin", "pydantic.mypy"]
|
|
67
|
+
|
|
68
|
+
[tool.isort]
|
|
69
|
+
profile = "black"
|
|
70
|
+
line_length = 79
|
|
71
|
+
multi_line_output = 3
|
|
72
|
+
include_trailing_comma = true
|
|
@@ -3,16 +3,18 @@ Python wrapper для API мессенджера Max
|
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
5
|
from .core import (
|
|
6
|
-
InvalidPhoneError,
|
|
7
6
|
MaxClient,
|
|
8
7
|
SocketMaxClient,
|
|
8
|
+
)
|
|
9
|
+
from .exceptions import (
|
|
10
|
+
InvalidPhoneError,
|
|
11
|
+
LoginError,
|
|
9
12
|
WebSocketNotConnectedError,
|
|
10
13
|
)
|
|
11
|
-
from .static import (
|
|
14
|
+
from .static.enum import (
|
|
12
15
|
AccessType,
|
|
13
16
|
AuthType,
|
|
14
17
|
ChatType,
|
|
15
|
-
Constants,
|
|
16
18
|
DeviceType,
|
|
17
19
|
ElementType,
|
|
18
20
|
MessageStatus,
|
|
@@ -38,13 +40,14 @@ __all__ = [
|
|
|
38
40
|
"Channel",
|
|
39
41
|
"Chat",
|
|
40
42
|
"ChatType",
|
|
41
|
-
"Constants",
|
|
42
43
|
"DeviceType",
|
|
43
44
|
"Dialog",
|
|
44
45
|
"Element",
|
|
45
46
|
"ElementType",
|
|
46
47
|
# Исключения
|
|
47
48
|
"InvalidPhoneError",
|
|
49
|
+
"LoginError",
|
|
50
|
+
"WebSocketNotConnectedError",
|
|
48
51
|
# Клиент
|
|
49
52
|
"MaxClient",
|
|
50
53
|
"Message",
|
|
@@ -53,5 +56,4 @@ __all__ = [
|
|
|
53
56
|
"Opcode",
|
|
54
57
|
"SocketMaxClient",
|
|
55
58
|
"User",
|
|
56
|
-
"WebSocketNotConnectedError",
|
|
57
59
|
]
|