maxapi-python 1.1.7__tar.gz → 1.1.8__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.8/.github/ISSUE_TEMPLATE/bug_report.md +25 -0
- maxapi_python-1.1.8/.github/ISSUE_TEMPLATE/feature_request.md +19 -0
- maxapi_python-1.1.8/.github/ISSUE_TEMPLATE/refactor.md +25 -0
- maxapi_python-1.1.8/.github/pull_request_template.md +19 -0
- {maxapi_python-1.1.7 → maxapi_python-1.1.8}/PKG-INFO +10 -4
- {maxapi_python-1.1.7 → maxapi_python-1.1.8}/README.md +9 -3
- maxapi_python-1.1.8/examples/example.py +62 -0
- {maxapi_python-1.1.7 → maxapi_python-1.1.8}/pyproject.toml +1 -1
- {maxapi_python-1.1.7 → maxapi_python-1.1.8}/src/pymax/files.py +1 -1
- {maxapi_python-1.1.7 → maxapi_python-1.1.8}/src/pymax/static.py +1 -0
- {maxapi_python-1.1.7 → maxapi_python-1.1.8}/src/pymax/types.py +29 -1
- maxapi_python-1.1.7/examples/example.py +0 -59
- {maxapi_python-1.1.7 → maxapi_python-1.1.8}/.github/FUNDING.yml +0 -0
- {maxapi_python-1.1.7 → maxapi_python-1.1.8}/.github/workflows/publish.yml +0 -0
- {maxapi_python-1.1.7 → maxapi_python-1.1.8}/.gitignore +0 -0
- {maxapi_python-1.1.7 → maxapi_python-1.1.8}/LICENSE +0 -0
- {maxapi_python-1.1.7 → maxapi_python-1.1.8}/assets/icon.svg +0 -0
- {maxapi_python-1.1.7 → maxapi_python-1.1.8}/assets/logo.svg +0 -0
- {maxapi_python-1.1.7 → maxapi_python-1.1.8}/docs/api.md +0 -0
- {maxapi_python-1.1.7 → maxapi_python-1.1.8}/docs/assets/icon.svg +0 -0
- {maxapi_python-1.1.7 → maxapi_python-1.1.8}/docs/examples.md +0 -0
- {maxapi_python-1.1.7 → maxapi_python-1.1.8}/docs/index.md +0 -0
- {maxapi_python-1.1.7 → maxapi_python-1.1.8}/mkdocs.yml +0 -0
- {maxapi_python-1.1.7 → maxapi_python-1.1.8}/ruff.toml +0 -0
- {maxapi_python-1.1.7 → maxapi_python-1.1.8}/scripts/build.py +0 -0
- {maxapi_python-1.1.7 → maxapi_python-1.1.8}/src/pymax/__init__.py +0 -0
- {maxapi_python-1.1.7 → maxapi_python-1.1.8}/src/pymax/core.py +0 -0
- {maxapi_python-1.1.7 → maxapi_python-1.1.8}/src/pymax/crud.py +0 -0
- {maxapi_python-1.1.7 → maxapi_python-1.1.8}/src/pymax/exceptions.py +0 -0
- {maxapi_python-1.1.7 → maxapi_python-1.1.8}/src/pymax/filters.py +0 -0
- {maxapi_python-1.1.7 → maxapi_python-1.1.8}/src/pymax/interfaces.py +0 -0
- {maxapi_python-1.1.7 → maxapi_python-1.1.8}/src/pymax/mixins/__init__.py +0 -0
- {maxapi_python-1.1.7 → maxapi_python-1.1.8}/src/pymax/mixins/auth.py +0 -0
- {maxapi_python-1.1.7 → maxapi_python-1.1.8}/src/pymax/mixins/channel.py +0 -0
- {maxapi_python-1.1.7 → maxapi_python-1.1.8}/src/pymax/mixins/group.py +0 -0
- {maxapi_python-1.1.7 → maxapi_python-1.1.8}/src/pymax/mixins/handler.py +0 -0
- {maxapi_python-1.1.7 → maxapi_python-1.1.8}/src/pymax/mixins/message.py +0 -0
- {maxapi_python-1.1.7 → maxapi_python-1.1.8}/src/pymax/mixins/self.py +0 -0
- {maxapi_python-1.1.7 → maxapi_python-1.1.8}/src/pymax/mixins/socket.py +0 -0
- {maxapi_python-1.1.7 → maxapi_python-1.1.8}/src/pymax/mixins/telemetry.py +0 -0
- {maxapi_python-1.1.7 → maxapi_python-1.1.8}/src/pymax/mixins/user.py +0 -0
- {maxapi_python-1.1.7 → maxapi_python-1.1.8}/src/pymax/mixins/websocket.py +0 -0
- {maxapi_python-1.1.7 → maxapi_python-1.1.8}/src/pymax/models.py +0 -0
- {maxapi_python-1.1.7 → maxapi_python-1.1.8}/src/pymax/navigation.py +0 -0
- {maxapi_python-1.1.7 → maxapi_python-1.1.8}/src/pymax/payloads.py +0 -0
- {maxapi_python-1.1.7 → maxapi_python-1.1.8}/src/pymax/utils.py +0 -0
@@ -0,0 +1,25 @@
|
|
1
|
+
---
|
2
|
+
name: Bug report
|
3
|
+
about: Сообщить о баге
|
4
|
+
title: ''
|
5
|
+
labels: bug
|
6
|
+
assignees: ''
|
7
|
+
|
8
|
+
---
|
9
|
+
|
10
|
+
**Описание**
|
11
|
+
Что пошло не так?
|
12
|
+
|
13
|
+
**Шаги для воспроизведения**
|
14
|
+
1.
|
15
|
+
2.
|
16
|
+
3.
|
17
|
+
|
18
|
+
**Ожидаемый результат**
|
19
|
+
Что должно было произойти
|
20
|
+
|
21
|
+
**Фактический результат**
|
22
|
+
Что произошло на самом деле
|
23
|
+
|
24
|
+
**Дополнительно**
|
25
|
+
Логи, скриншоты, версия Python/API
|
@@ -0,0 +1,19 @@
|
|
1
|
+
---
|
2
|
+
name: Feature Request
|
3
|
+
about: Предложить новую функциональность
|
4
|
+
title: ''
|
5
|
+
labels: enhancement
|
6
|
+
assignees: ''
|
7
|
+
---
|
8
|
+
|
9
|
+
**Описание**
|
10
|
+
Опишите новую функцию или улучшение.
|
11
|
+
|
12
|
+
**Зачем это нужно**
|
13
|
+
Кратко объясните, какую проблему решает или что улучшает.
|
14
|
+
|
15
|
+
**Пример использования**
|
16
|
+
Как это будет использоваться в коде:
|
17
|
+
|
18
|
+
```python
|
19
|
+
# пример
|
@@ -0,0 +1,25 @@
|
|
1
|
+
---
|
2
|
+
name: Refactor
|
3
|
+
about: Предложение по улучшению кода без изменения функционала
|
4
|
+
title: ''
|
5
|
+
labels: refactor
|
6
|
+
assignees: ''
|
7
|
+
---
|
8
|
+
|
9
|
+
## Описание
|
10
|
+
Опишите часть кода, которую нужно улучшить или рефакторить, без изменения функциональности.
|
11
|
+
|
12
|
+
## Причина
|
13
|
+
Почему требуется рефакторинг? Например:
|
14
|
+
- Улучшение читаемости кода
|
15
|
+
- Повышение производительности
|
16
|
+
- Упрощение поддержки
|
17
|
+
|
18
|
+
## Предлагаемые изменения
|
19
|
+
Опишите, как вы планируете изменить код, чтобы улучшить его структуру или качество.
|
20
|
+
|
21
|
+
## Влияние
|
22
|
+
Какие модули/части библиотеки могут быть затронуты? Нужно убедиться, что функционал остаётся прежним.
|
23
|
+
|
24
|
+
## Дополнительно
|
25
|
+
Любая дополнительная информация, ссылки на документацию, примеры кода.
|
@@ -0,0 +1,19 @@
|
|
1
|
+
## Описание
|
2
|
+
Кратко, что делает этот PR. Например, добавляет новый метод, исправляет баг, улучшает документацию.
|
3
|
+
|
4
|
+
## Тип изменений
|
5
|
+
- [ ] Исправление бага
|
6
|
+
- [ ] Новая функциональность
|
7
|
+
- [ ] Улучшение документации
|
8
|
+
- [ ] Рефакторинг
|
9
|
+
|
10
|
+
## Связанные задачи / Issue
|
11
|
+
Ссылка на issue, если есть: #
|
12
|
+
|
13
|
+
## Тестирование
|
14
|
+
Покажите пример кода, который проверяет изменения:
|
15
|
+
|
16
|
+
```python
|
17
|
+
import pymax
|
18
|
+
|
19
|
+
# пример использования нового функционала
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: maxapi-python
|
3
|
-
Version: 1.1.
|
3
|
+
Version: 1.1.8
|
4
4
|
Summary: Python wrapper для API мессенджера Max
|
5
5
|
Project-URL: Homepage, https://github.com/noxzion/PyMax
|
6
6
|
Project-URL: Repository, https://github.com/noxzion/PyMax
|
@@ -157,7 +157,13 @@ if __name__ == "__main__":
|
|
157
157
|
|
158
158
|
## Авторы
|
159
159
|
|
160
|
-
- **[noxzion](https://github.com/noxzion)** —
|
161
|
-
- **[ink](https://github.com/ink-developer)** —
|
162
|
-
- **[fresh-milkshake](https://github.com/fresh-milkshake)** — контрибьютор и автор лого
|
160
|
+
- **[noxzion](https://github.com/noxzion)** — Оригинальный автор проекта
|
161
|
+
- **[ink](https://github.com/ink-developer)** — Главный разработчик, исследование API и его документация
|
163
162
|
|
163
|
+
## Контрибьюторы
|
164
|
+
|
165
|
+
Спасибо всем за помощь в разработке!
|
166
|
+
|
167
|
+
<a href="https://github.com/ink-developer/PyMax/graphs/contributors">
|
168
|
+
<img src="https://contrib.rocks/image?repo=ink-developer/PyMax" />
|
169
|
+
</a>
|
@@ -135,7 +135,13 @@ if __name__ == "__main__":
|
|
135
135
|
|
136
136
|
## Авторы
|
137
137
|
|
138
|
-
- **[noxzion](https://github.com/noxzion)** —
|
139
|
-
- **[ink](https://github.com/ink-developer)** —
|
140
|
-
- **[fresh-milkshake](https://github.com/fresh-milkshake)** — контрибьютор и автор лого
|
138
|
+
- **[noxzion](https://github.com/noxzion)** — Оригинальный автор проекта
|
139
|
+
- **[ink](https://github.com/ink-developer)** — Главный разработчик, исследование API и его документация
|
141
140
|
|
141
|
+
## Контрибьюторы
|
142
|
+
|
143
|
+
Спасибо всем за помощь в разработке!
|
144
|
+
|
145
|
+
<a href="https://github.com/ink-developer/PyMax/graphs/contributors">
|
146
|
+
<img src="https://contrib.rocks/image?repo=ink-developer/PyMax" />
|
147
|
+
</a>
|
@@ -0,0 +1,62 @@
|
|
1
|
+
import asyncio
|
2
|
+
import logging
|
3
|
+
|
4
|
+
from pymax import MaxClient, Message, SocketMaxClient
|
5
|
+
from pymax.files import Photo
|
6
|
+
from pymax.filters import Filter
|
7
|
+
from pymax.static import AttachType
|
8
|
+
|
9
|
+
phone = "+1234567890"
|
10
|
+
|
11
|
+
|
12
|
+
client = MaxClient(phone=phone, work_dir="cache")
|
13
|
+
# client = SocketMaxClient(phone=phone, work_dir="cache")
|
14
|
+
|
15
|
+
|
16
|
+
@client.on_message(filter=Filter(chat_id=0))
|
17
|
+
async def handle_message(message: Message) -> None:
|
18
|
+
print(str(message.sender) + ": " + message.text)
|
19
|
+
|
20
|
+
|
21
|
+
@client.on_start
|
22
|
+
async def handle_start() -> None:
|
23
|
+
print("Client started successfully!")
|
24
|
+
# print(client.dialogs)
|
25
|
+
history = await client.fetch_history(chat_id=0)
|
26
|
+
if history:
|
27
|
+
for message in history:
|
28
|
+
if message.attaches:
|
29
|
+
for attach in message.attaches:
|
30
|
+
if attach.type == AttachType.CONTROL:
|
31
|
+
print(attach.event)
|
32
|
+
print(attach.extra)
|
33
|
+
# if attach.type == AttachType.VIDEO:
|
34
|
+
# print(message)
|
35
|
+
# vid = await client.get_video_by_id(
|
36
|
+
# chat_id=0,
|
37
|
+
# video_id=attach.video_id,
|
38
|
+
# message_id=message.id,
|
39
|
+
# )
|
40
|
+
# print(vid.url)
|
41
|
+
# elif attach.type == AttachType.FILE:
|
42
|
+
# file = await client.get_file_by_id(
|
43
|
+
# chat_id=0,
|
44
|
+
# file_id=attach.file_id,
|
45
|
+
# message_id=message.id,
|
46
|
+
# )
|
47
|
+
# print(file.url)
|
48
|
+
# print(client.me.names[0].first_name)
|
49
|
+
# user = await client.get_user(client.me.id)
|
50
|
+
|
51
|
+
# print(user.names[0].first_name)
|
52
|
+
|
53
|
+
# photo1 = Photo(path="tests/test.jpeg")
|
54
|
+
# photo2 = Photo(path="tests/test.jpg")
|
55
|
+
|
56
|
+
# await client.send_message(
|
57
|
+
# "Hello with photo!", chat_id=0, photos=[photo1, photo2], notify=True
|
58
|
+
# )
|
59
|
+
|
60
|
+
|
61
|
+
if __name__ == "__main__":
|
62
|
+
asyncio.run(client.start())
|
@@ -56,7 +56,7 @@ class Photo(BaseFile):
|
|
56
56
|
return (extension[1:], ("image/" + extension[1:]).lower())
|
57
57
|
elif self.url:
|
58
58
|
extension = Path(self.url).suffix.lower()
|
59
|
-
if extension in self.ALLOWED_EXTENSIONS:
|
59
|
+
if extension not in self.ALLOWED_EXTENSIONS:
|
60
60
|
raise ValueError(
|
61
61
|
f"Invalid photo extension in URL: {extension}. Allowed: {self.ALLOWED_EXTENSIONS}"
|
62
62
|
)
|
@@ -39,6 +39,32 @@ class Names:
|
|
39
39
|
return self.name
|
40
40
|
|
41
41
|
|
42
|
+
class ControlAttach:
|
43
|
+
def __init__(self, type: AttachType, event: str, **kwargs: dict[str, Any]) -> None:
|
44
|
+
self.type = type
|
45
|
+
self.event = event
|
46
|
+
self.extra = kwargs
|
47
|
+
|
48
|
+
@classmethod
|
49
|
+
def from_dict(cls, data: dict[str, Any]) -> "ControlAttach":
|
50
|
+
data = dict(data)
|
51
|
+
attach_type = AttachType(data.pop("_type"))
|
52
|
+
event = data.pop("event")
|
53
|
+
return cls(
|
54
|
+
type=attach_type,
|
55
|
+
event=event,
|
56
|
+
**data,
|
57
|
+
)
|
58
|
+
|
59
|
+
@override
|
60
|
+
def __repr__(self) -> str:
|
61
|
+
return f"ControlAttach(type={self.type!r}, event={self.event!r}, extra={self.extra!r})"
|
62
|
+
|
63
|
+
@override
|
64
|
+
def __str__(self) -> str:
|
65
|
+
return f"ControlAttach: {self.event}"
|
66
|
+
|
67
|
+
|
42
68
|
class PhotoAttach:
|
43
69
|
def __init__(
|
44
70
|
self,
|
@@ -281,7 +307,7 @@ class Message:
|
|
281
307
|
text: str,
|
282
308
|
status: MessageStatus | str | None,
|
283
309
|
type: MessageType | str,
|
284
|
-
attaches: list[PhotoAttach | VideoAttach | FileAttach],
|
310
|
+
attaches: list[PhotoAttach | VideoAttach | FileAttach | ControlAttach] | None,
|
285
311
|
) -> None:
|
286
312
|
self.chat_id = chat_id
|
287
313
|
self.sender = sender
|
@@ -306,6 +332,8 @@ class Message:
|
|
306
332
|
attaches.append(VideoAttach.from_dict(a))
|
307
333
|
elif a["_type"] == AttachType.FILE:
|
308
334
|
attaches.append(FileAttach.from_dict(a))
|
335
|
+
elif a["_type"] == AttachType.CONTROL:
|
336
|
+
attaches.append(ControlAttach.from_dict(a))
|
309
337
|
return cls(
|
310
338
|
chat_id=data.get("chatId"),
|
311
339
|
sender=message.get("sender"),
|
@@ -1,59 +0,0 @@
|
|
1
|
-
import asyncio
|
2
|
-
import logging
|
3
|
-
|
4
|
-
from pymax import MaxClient, Message, SocketMaxClient
|
5
|
-
from pymax.files import Photo
|
6
|
-
from pymax.filters import Filter
|
7
|
-
from pymax.static import AttachType
|
8
|
-
|
9
|
-
phone = "+1234567890"
|
10
|
-
|
11
|
-
|
12
|
-
client = MaxClient(phone=phone, work_dir="cache")
|
13
|
-
# client = SocketMaxClient(phone=phone, work_dir="cache")
|
14
|
-
|
15
|
-
|
16
|
-
@client.on_message(filter=Filter(chat_id=0))
|
17
|
-
async def handle_message(message: Message) -> None:
|
18
|
-
print(str(message.sender) + ": " + message.text)
|
19
|
-
|
20
|
-
|
21
|
-
@client.on_start
|
22
|
-
async def handle_start() -> None:
|
23
|
-
print("Client started successfully!")
|
24
|
-
# print(client.dialogs)
|
25
|
-
# history = await client.fetch_history(chat_id=0)
|
26
|
-
# if history:
|
27
|
-
# for message in history:
|
28
|
-
# if message.attaches:
|
29
|
-
# for attach in message.attaches:
|
30
|
-
# if attach.type == AttachType.VIDEO:
|
31
|
-
# print(message)
|
32
|
-
# vid = await client.get_video_by_id(
|
33
|
-
# chat_id=0,
|
34
|
-
# video_id=attach.video_id,
|
35
|
-
# message_id=message.id,
|
36
|
-
# )
|
37
|
-
# print(vid.url)
|
38
|
-
# elif attach.type == AttachType.FILE:
|
39
|
-
# file = await client.get_file_by_id(
|
40
|
-
# chat_id=0,
|
41
|
-
# file_id=attach.file_id,
|
42
|
-
# message_id=message.id,
|
43
|
-
# )
|
44
|
-
# print(file.url)
|
45
|
-
# print(client.me.names[0].first_name)
|
46
|
-
# user = await client.get_user(client.me.id)
|
47
|
-
|
48
|
-
# print(user.names[0].first_name)
|
49
|
-
|
50
|
-
# photo1 = Photo(path="tests/test.jpeg")
|
51
|
-
# photo2 = Photo(path="tests/test.jpg")
|
52
|
-
|
53
|
-
# await client.send_message(
|
54
|
-
# "Hello with photo!", chat_id=0, photos=[photo1, photo2], notify=True
|
55
|
-
# )
|
56
|
-
|
57
|
-
|
58
|
-
if __name__ == "__main__":
|
59
|
-
asyncio.run(client.start())
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|