omnivybe.py 1.0.0__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.
- omnivybe_py-1.0.0/PKG-INFO +101 -0
- omnivybe_py-1.0.0/README.md +89 -0
- omnivybe_py-1.0.0/omnivybe/__init__.py +130 -0
- omnivybe_py-1.0.0/omnivybe/__main__.py +4 -0
- omnivybe_py-1.0.0/omnivybe/bitfields.py +126 -0
- omnivybe_py-1.0.0/omnivybe/builders.py +176 -0
- omnivybe_py-1.0.0/omnivybe/cdn.py +149 -0
- omnivybe_py-1.0.0/omnivybe/cli.py +65 -0
- omnivybe_py-1.0.0/omnivybe/client.py +119 -0
- omnivybe_py-1.0.0/omnivybe/collectors.py +133 -0
- omnivybe_py-1.0.0/omnivybe/constants.py +61 -0
- omnivybe_py-1.0.0/omnivybe/ext/__init__.py +1 -0
- omnivybe_py-1.0.0/omnivybe/ext/commands/__init__.py +5 -0
- omnivybe_py-1.0.0/omnivybe/ext/commands/bot.py +120 -0
- omnivybe_py-1.0.0/omnivybe/ext/commands/context.py +49 -0
- omnivybe_py-1.0.0/omnivybe/ext/commands/core.py +46 -0
- omnivybe_py-1.0.0/omnivybe/ext/paginator/__init__.py +3 -0
- omnivybe_py-1.0.0/omnivybe/ext/paginator/paginator.py +95 -0
- omnivybe_py-1.0.0/omnivybe/ext/tasks/__init__.py +3 -0
- omnivybe_py-1.0.0/omnivybe/ext/tasks/loop.py +74 -0
- omnivybe_py-1.0.0/omnivybe/gateway.py +179 -0
- omnivybe_py-1.0.0/omnivybe/ratelimit.py +30 -0
- omnivybe_py-1.0.0/omnivybe/rest.py +90 -0
- omnivybe_py-1.0.0/omnivybe/structures.py +260 -0
- omnivybe_py-1.0.0/omnivybe/utils.py +142 -0
- omnivybe_py-1.0.0/omnivybe.py.egg-info/PKG-INFO +101 -0
- omnivybe_py-1.0.0/omnivybe.py.egg-info/SOURCES.txt +31 -0
- omnivybe_py-1.0.0/omnivybe.py.egg-info/dependency_links.txt +1 -0
- omnivybe_py-1.0.0/omnivybe.py.egg-info/entry_points.txt +2 -0
- omnivybe_py-1.0.0/omnivybe.py.egg-info/requires.txt +1 -0
- omnivybe_py-1.0.0/omnivybe.py.egg-info/top_level.txt +1 -0
- omnivybe_py-1.0.0/pyproject.toml +28 -0
- omnivybe_py-1.0.0/setup.cfg +4 -0
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: omnivybe.py
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: The official, fully-featured, and high-performance Python bot SDK for the OmniVybe platform.
|
|
5
|
+
Author: OmniVybe Team
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://omnivybe.com.tr
|
|
8
|
+
Keywords: omnivybe,omni,omnivybe.py,bot,sdk,gateway,rest,chat
|
|
9
|
+
Requires-Python: >=3.9
|
|
10
|
+
Description-Content-Type: text/markdown
|
|
11
|
+
Requires-Dist: aiohttp>=3.9.0
|
|
12
|
+
|
|
13
|
+
# omnivybe.py
|
|
14
|
+
|
|
15
|
+
> The official, fully-featured, and high-performance Python bot SDK for the **OmniVybe** platform (1:1 feature parity with `omnivybe.js` + Next-Gen Python Extensions).
|
|
16
|
+
|
|
17
|
+
[](https://opensource.org/licenses/MIT)
|
|
18
|
+
[](https://www.python.org/)
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## 🚀 Kurulum
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
pip install -e .
|
|
26
|
+
```
|
|
27
|
+
veya doğrudan gereksinimleri yüklemek için:
|
|
28
|
+
```bash
|
|
29
|
+
pip install -r requirements.txt
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## ⚡ Temel & Yaratıcı Özellikler
|
|
35
|
+
|
|
36
|
+
- 🎯 **Tam Bot ve Gateway Yaşam Döngüsü**: Otomatik heartbeat, yeniden bağlanma ve oturum yönetimi.
|
|
37
|
+
- 🛠️ **`omnivybe.ext.commands`**: Prefix tabanlı komut sistemi, akıllı `Context` (`ctx.reply`, `ctx.send`), alias ve dinamik prefix desteği.
|
|
38
|
+
- 🧩 **Sıcak Yeniden Yüklemeli Cog / Extension Desteği**: `bot.load_extension()` ve `bot.reload_extension()` ile botu kapatmadan canlı kod güncelleme.
|
|
39
|
+
- ⏱️ **`omnivybe.ext.tasks`**: `@tasks.loop(seconds=..., minutes=...)` ile kolay arka plan zamanlayıcıları.
|
|
40
|
+
- 📖 **`omnivybe.ext.paginator`**: Reaksiyon butonlu (◀️ ▶️ ⏹️) etkileşimli çok sayfalı Embed gezgini.
|
|
41
|
+
- 🚦 **`RateLimiter`**: Token-bucket tabanlı 429 koruması ve akıllı istek kuyruğu.
|
|
42
|
+
- 💎 **Gelişmiş Yapıcılar**: `EmbedBuilder`, `AttachmentBuilder`, `MessagePayload`.
|
|
43
|
+
- 🔍 **Kolektörler**: `MessageCollector`, `ReactionCollector`.
|
|
44
|
+
- 📂 **Model & Yapılar**: `User`, `GuildMember`, `Role`, `Message`, `TextChannel`, `VoiceChannel`, `CategoryChannel`, `ThreadChannel`, `Guild`.
|
|
45
|
+
- 🛡️ **Bitfield ve Yetki Denetimi**: `PermissionsBitField`, `MessageFlagsBitField`, `UserFlagsBitField`, `GatewayIntentBits`.
|
|
46
|
+
- 🌐 **CDN Yardımcıları**: `cdn_avatar_url`, `cdn_display_avatar_url`, `cdn_banner_url`, `cdn_emoji_url`, `cdn_sticker_url`, `cdn_guild_asset_url`.
|
|
47
|
+
- 🎨 **Emoji & Markdown Araçları**: `parse_emoji`, `format_emoji`, `get_unicode_from_shortcode`, `escape_markdown`, `format_timestamp`, `resolve_color`.
|
|
48
|
+
- 💻 **CLI Bot İskeleti**: `python -m omnivybe init` komutuyla tek tıkla hazır bot şablonu oluşturma.
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## 📖 Hızlı Başlangıç
|
|
53
|
+
|
|
54
|
+
### 1. `commands.Bot` ile Komut & Sayfalayıcı Örneği
|
|
55
|
+
|
|
56
|
+
```python
|
|
57
|
+
import os
|
|
58
|
+
from omnivybe import GatewayIntentBits, EmbedBuilder
|
|
59
|
+
from omnivybe.ext import commands, tasks
|
|
60
|
+
from omnivybe.ext.paginator import Paginator
|
|
61
|
+
|
|
62
|
+
bot = commands.Bot(
|
|
63
|
+
command_prefix="!",
|
|
64
|
+
intents=GatewayIntentBits.Guilds | GatewayIntentBits.GuildMessages | GatewayIntentBits.MessageContent
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
@bot.event
|
|
68
|
+
async def on_ready():
|
|
69
|
+
print(f"🚀 Bot hazır: {bot.user.tag}")
|
|
70
|
+
durum_guncelleyici.start()
|
|
71
|
+
|
|
72
|
+
@bot.command(name="ping")
|
|
73
|
+
async def ping(ctx):
|
|
74
|
+
await ctx.reply("🏓 Pong! OmniVybe Framework çalışıyor.")
|
|
75
|
+
|
|
76
|
+
@bot.command(name="yardim")
|
|
77
|
+
async def yardim(ctx):
|
|
78
|
+
sayfa1 = EmbedBuilder().set_title("Yardım - Sayfa 1").set_description("Komut listesi başlangıcı...").set_color(0x5865F2)
|
|
79
|
+
sayfa2 = EmbedBuilder().set_title("Yardım - Sayfa 2").set_description("Moderasyon komutları...").set_color(0x57F287)
|
|
80
|
+
|
|
81
|
+
paginator = Paginator([sayfa1, sayfa2], timeout=30.0)
|
|
82
|
+
await paginator.start(ctx)
|
|
83
|
+
|
|
84
|
+
@tasks.loop(seconds=60)
|
|
85
|
+
async def durum_guncelleyici():
|
|
86
|
+
print("Durum kontrol ediliyor...")
|
|
87
|
+
|
|
88
|
+
bot.run(os.environ.get("OMNIVYBE_BOT_TOKEN", "YOUR_BOT_TOKEN"))
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### 2. CLI ile Proje Başlatma
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
python -m omnivybe init my_bot
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## 📄 Lisans
|
|
100
|
+
|
|
101
|
+
Bu proje MIT lisansı altındadır.
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# omnivybe.py
|
|
2
|
+
|
|
3
|
+
> The official, fully-featured, and high-performance Python bot SDK for the **OmniVybe** platform (1:1 feature parity with `omnivybe.js` + Next-Gen Python Extensions).
|
|
4
|
+
|
|
5
|
+
[](https://opensource.org/licenses/MIT)
|
|
6
|
+
[](https://www.python.org/)
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## 🚀 Kurulum
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
pip install -e .
|
|
14
|
+
```
|
|
15
|
+
veya doğrudan gereksinimleri yüklemek için:
|
|
16
|
+
```bash
|
|
17
|
+
pip install -r requirements.txt
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## ⚡ Temel & Yaratıcı Özellikler
|
|
23
|
+
|
|
24
|
+
- 🎯 **Tam Bot ve Gateway Yaşam Döngüsü**: Otomatik heartbeat, yeniden bağlanma ve oturum yönetimi.
|
|
25
|
+
- 🛠️ **`omnivybe.ext.commands`**: Prefix tabanlı komut sistemi, akıllı `Context` (`ctx.reply`, `ctx.send`), alias ve dinamik prefix desteği.
|
|
26
|
+
- 🧩 **Sıcak Yeniden Yüklemeli Cog / Extension Desteği**: `bot.load_extension()` ve `bot.reload_extension()` ile botu kapatmadan canlı kod güncelleme.
|
|
27
|
+
- ⏱️ **`omnivybe.ext.tasks`**: `@tasks.loop(seconds=..., minutes=...)` ile kolay arka plan zamanlayıcıları.
|
|
28
|
+
- 📖 **`omnivybe.ext.paginator`**: Reaksiyon butonlu (◀️ ▶️ ⏹️) etkileşimli çok sayfalı Embed gezgini.
|
|
29
|
+
- 🚦 **`RateLimiter`**: Token-bucket tabanlı 429 koruması ve akıllı istek kuyruğu.
|
|
30
|
+
- 💎 **Gelişmiş Yapıcılar**: `EmbedBuilder`, `AttachmentBuilder`, `MessagePayload`.
|
|
31
|
+
- 🔍 **Kolektörler**: `MessageCollector`, `ReactionCollector`.
|
|
32
|
+
- 📂 **Model & Yapılar**: `User`, `GuildMember`, `Role`, `Message`, `TextChannel`, `VoiceChannel`, `CategoryChannel`, `ThreadChannel`, `Guild`.
|
|
33
|
+
- 🛡️ **Bitfield ve Yetki Denetimi**: `PermissionsBitField`, `MessageFlagsBitField`, `UserFlagsBitField`, `GatewayIntentBits`.
|
|
34
|
+
- 🌐 **CDN Yardımcıları**: `cdn_avatar_url`, `cdn_display_avatar_url`, `cdn_banner_url`, `cdn_emoji_url`, `cdn_sticker_url`, `cdn_guild_asset_url`.
|
|
35
|
+
- 🎨 **Emoji & Markdown Araçları**: `parse_emoji`, `format_emoji`, `get_unicode_from_shortcode`, `escape_markdown`, `format_timestamp`, `resolve_color`.
|
|
36
|
+
- 💻 **CLI Bot İskeleti**: `python -m omnivybe init` komutuyla tek tıkla hazır bot şablonu oluşturma.
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## 📖 Hızlı Başlangıç
|
|
41
|
+
|
|
42
|
+
### 1. `commands.Bot` ile Komut & Sayfalayıcı Örneği
|
|
43
|
+
|
|
44
|
+
```python
|
|
45
|
+
import os
|
|
46
|
+
from omnivybe import GatewayIntentBits, EmbedBuilder
|
|
47
|
+
from omnivybe.ext import commands, tasks
|
|
48
|
+
from omnivybe.ext.paginator import Paginator
|
|
49
|
+
|
|
50
|
+
bot = commands.Bot(
|
|
51
|
+
command_prefix="!",
|
|
52
|
+
intents=GatewayIntentBits.Guilds | GatewayIntentBits.GuildMessages | GatewayIntentBits.MessageContent
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
@bot.event
|
|
56
|
+
async def on_ready():
|
|
57
|
+
print(f"🚀 Bot hazır: {bot.user.tag}")
|
|
58
|
+
durum_guncelleyici.start()
|
|
59
|
+
|
|
60
|
+
@bot.command(name="ping")
|
|
61
|
+
async def ping(ctx):
|
|
62
|
+
await ctx.reply("🏓 Pong! OmniVybe Framework çalışıyor.")
|
|
63
|
+
|
|
64
|
+
@bot.command(name="yardim")
|
|
65
|
+
async def yardim(ctx):
|
|
66
|
+
sayfa1 = EmbedBuilder().set_title("Yardım - Sayfa 1").set_description("Komut listesi başlangıcı...").set_color(0x5865F2)
|
|
67
|
+
sayfa2 = EmbedBuilder().set_title("Yardım - Sayfa 2").set_description("Moderasyon komutları...").set_color(0x57F287)
|
|
68
|
+
|
|
69
|
+
paginator = Paginator([sayfa1, sayfa2], timeout=30.0)
|
|
70
|
+
await paginator.start(ctx)
|
|
71
|
+
|
|
72
|
+
@tasks.loop(seconds=60)
|
|
73
|
+
async def durum_guncelleyici():
|
|
74
|
+
print("Durum kontrol ediliyor...")
|
|
75
|
+
|
|
76
|
+
bot.run(os.environ.get("OMNIVYBE_BOT_TOKEN", "YOUR_BOT_TOKEN"))
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### 2. CLI ile Proje Başlatma
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
python -m omnivybe init my_bot
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## 📄 Lisans
|
|
88
|
+
|
|
89
|
+
Bu proje MIT lisansı altındadır.
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
"""
|
|
2
|
+
omnivybe.py
|
|
3
|
+
~~~~~~~~~~~
|
|
4
|
+
The official, high-performance Python bot SDK for the OmniVybe platform.
|
|
5
|
+
Full feature parity with omni.js / omnivybe.js plus next-gen extensions.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from .bitfields import (
|
|
9
|
+
BitField,
|
|
10
|
+
MessageFlags,
|
|
11
|
+
MessageFlagsBitField,
|
|
12
|
+
PermissionFlags,
|
|
13
|
+
PermissionsBitField,
|
|
14
|
+
PublicUserFlags,
|
|
15
|
+
UserFlagsBitField,
|
|
16
|
+
)
|
|
17
|
+
from .builders import AttachmentBuilder, EmbedBuilder, MessagePayload
|
|
18
|
+
from .cdn import (
|
|
19
|
+
CDN_URL,
|
|
20
|
+
STATIC_CDN_URL,
|
|
21
|
+
cdn_avatar_url,
|
|
22
|
+
cdn_banner_url,
|
|
23
|
+
cdn_default_avatar_url,
|
|
24
|
+
cdn_display_avatar_url,
|
|
25
|
+
cdn_emoji_url,
|
|
26
|
+
cdn_guild_asset_url,
|
|
27
|
+
cdn_member_avatar_url,
|
|
28
|
+
cdn_member_banner_url,
|
|
29
|
+
cdn_sticker_url,
|
|
30
|
+
)
|
|
31
|
+
from .client import Client
|
|
32
|
+
from .collectors import BaseCollector, MessageCollector, ReactionCollector
|
|
33
|
+
from .constants import ChannelType, Constants, GatewayIntentBits, GatewayOpcodes
|
|
34
|
+
from .gateway import GatewayManager
|
|
35
|
+
from .ratelimit import RateLimiter
|
|
36
|
+
from .rest import RESTManager
|
|
37
|
+
from .structures import (
|
|
38
|
+
Base,
|
|
39
|
+
CategoryChannel,
|
|
40
|
+
Embed,
|
|
41
|
+
Guild,
|
|
42
|
+
GuildMember,
|
|
43
|
+
Message,
|
|
44
|
+
Role,
|
|
45
|
+
TextChannel,
|
|
46
|
+
ThreadChannel,
|
|
47
|
+
User,
|
|
48
|
+
VoiceChannel,
|
|
49
|
+
)
|
|
50
|
+
from .utils import (
|
|
51
|
+
ParsedEmoji,
|
|
52
|
+
escape_markdown,
|
|
53
|
+
format_color,
|
|
54
|
+
format_emoji,
|
|
55
|
+
format_timestamp,
|
|
56
|
+
get_unicode_from_shortcode,
|
|
57
|
+
parse_emoji,
|
|
58
|
+
parse_role_mention,
|
|
59
|
+
parse_user_mention,
|
|
60
|
+
resolve_color,
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
# Extension namespaces
|
|
64
|
+
from . import ext
|
|
65
|
+
|
|
66
|
+
__version__ = "1.1.0"
|
|
67
|
+
__all__ = [
|
|
68
|
+
# Core
|
|
69
|
+
"Client",
|
|
70
|
+
"GatewayManager",
|
|
71
|
+
"RESTManager",
|
|
72
|
+
"RateLimiter",
|
|
73
|
+
"Constants",
|
|
74
|
+
"GatewayOpcodes",
|
|
75
|
+
"GatewayIntentBits",
|
|
76
|
+
"ChannelType",
|
|
77
|
+
# Structures
|
|
78
|
+
"Base",
|
|
79
|
+
"User",
|
|
80
|
+
"GuildMember",
|
|
81
|
+
"Role",
|
|
82
|
+
"Message",
|
|
83
|
+
"TextChannel",
|
|
84
|
+
"VoiceChannel",
|
|
85
|
+
"CategoryChannel",
|
|
86
|
+
"ThreadChannel",
|
|
87
|
+
"Guild",
|
|
88
|
+
"Embed",
|
|
89
|
+
# Builders & Payloads
|
|
90
|
+
"EmbedBuilder",
|
|
91
|
+
"AttachmentBuilder",
|
|
92
|
+
"MessagePayload",
|
|
93
|
+
# Collectors
|
|
94
|
+
"BaseCollector",
|
|
95
|
+
"MessageCollector",
|
|
96
|
+
"ReactionCollector",
|
|
97
|
+
# BitFields
|
|
98
|
+
"BitField",
|
|
99
|
+
"PermissionFlags",
|
|
100
|
+
"PermissionsBitField",
|
|
101
|
+
"MessageFlags",
|
|
102
|
+
"MessageFlagsBitField",
|
|
103
|
+
"PublicUserFlags",
|
|
104
|
+
"UserFlagsBitField",
|
|
105
|
+
# CDN
|
|
106
|
+
"CDN_URL",
|
|
107
|
+
"STATIC_CDN_URL",
|
|
108
|
+
"cdn_avatar_url",
|
|
109
|
+
"cdn_display_avatar_url",
|
|
110
|
+
"cdn_banner_url",
|
|
111
|
+
"cdn_member_avatar_url",
|
|
112
|
+
"cdn_member_banner_url",
|
|
113
|
+
"cdn_default_avatar_url",
|
|
114
|
+
"cdn_guild_asset_url",
|
|
115
|
+
"cdn_emoji_url",
|
|
116
|
+
"cdn_sticker_url",
|
|
117
|
+
# Utils
|
|
118
|
+
"ParsedEmoji",
|
|
119
|
+
"parse_emoji",
|
|
120
|
+
"format_emoji",
|
|
121
|
+
"get_unicode_from_shortcode",
|
|
122
|
+
"escape_markdown",
|
|
123
|
+
"resolve_color",
|
|
124
|
+
"format_color",
|
|
125
|
+
"format_timestamp",
|
|
126
|
+
"parse_role_mention",
|
|
127
|
+
"parse_user_mention",
|
|
128
|
+
# Extensions
|
|
129
|
+
"ext",
|
|
130
|
+
]
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
from enum import IntFlag
|
|
2
|
+
from typing import Any, List, Set, Union
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class BitField:
|
|
6
|
+
FLAGS: type = IntFlag
|
|
7
|
+
|
|
8
|
+
def __init__(self, bitfield: Union[int, List[Union[int, IntFlag]], IntFlag] = 0):
|
|
9
|
+
if isinstance(bitfield, list):
|
|
10
|
+
self.value = 0
|
|
11
|
+
for b in bitfield:
|
|
12
|
+
self.value |= int(b)
|
|
13
|
+
else:
|
|
14
|
+
self.value = int(bitfield)
|
|
15
|
+
|
|
16
|
+
def has(self, flag: Union[int, IntFlag]) -> bool:
|
|
17
|
+
val = int(flag)
|
|
18
|
+
return (self.value & val) == val
|
|
19
|
+
|
|
20
|
+
def add(self, *flags: Union[int, IntFlag]) -> None:
|
|
21
|
+
for f in flags:
|
|
22
|
+
self.value |= int(f)
|
|
23
|
+
|
|
24
|
+
def remove(self, *flags: Union[int, IntFlag]) -> None:
|
|
25
|
+
for f in flags:
|
|
26
|
+
self.value &= ~int(f)
|
|
27
|
+
|
|
28
|
+
def to_list(self) -> List[str]:
|
|
29
|
+
names: List[str] = []
|
|
30
|
+
for name, member in self.FLAGS.__members__.items():
|
|
31
|
+
if self.has(member.value):
|
|
32
|
+
names.append(name)
|
|
33
|
+
return names
|
|
34
|
+
|
|
35
|
+
def __int__(self) -> int:
|
|
36
|
+
return self.value
|
|
37
|
+
|
|
38
|
+
def __repr__(self) -> str:
|
|
39
|
+
return f"<{self.__class__.__name__} value={self.value}>"
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class PermissionFlags(IntFlag):
|
|
43
|
+
CreateInstantInvite = 1 << 0
|
|
44
|
+
KickMembers = 1 << 1
|
|
45
|
+
BanMembers = 1 << 2
|
|
46
|
+
Administrator = 1 << 3
|
|
47
|
+
ManageChannels = 1 << 4
|
|
48
|
+
ManageGuild = 1 << 5
|
|
49
|
+
AddReactions = 1 << 6
|
|
50
|
+
ViewAuditLog = 1 << 7
|
|
51
|
+
PrioritySpeaker = 1 << 8
|
|
52
|
+
Stream = 1 << 9
|
|
53
|
+
ViewChannel = 1 << 10
|
|
54
|
+
SendMessages = 1 << 11
|
|
55
|
+
SendTTSMessages = 1 << 12
|
|
56
|
+
ManageMessages = 1 << 13
|
|
57
|
+
EmbedLinks = 1 << 14
|
|
58
|
+
AttachFiles = 1 << 15
|
|
59
|
+
ReadMessageHistory = 1 << 16
|
|
60
|
+
MentionEveryone = 1 << 17
|
|
61
|
+
UseExternalEmojis = 1 << 18
|
|
62
|
+
ViewGuildInsights = 1 << 19
|
|
63
|
+
Connect = 1 << 20
|
|
64
|
+
Speak = 1 << 21
|
|
65
|
+
MuteMembers = 1 << 22
|
|
66
|
+
DeafenMembers = 1 << 23
|
|
67
|
+
MoveMembers = 1 << 24
|
|
68
|
+
UseVAD = 1 << 25
|
|
69
|
+
ChangeNickname = 1 << 26
|
|
70
|
+
ManageNicknames = 1 << 27
|
|
71
|
+
ManageRoles = 1 << 28
|
|
72
|
+
ManageWebhooks = 1 << 29
|
|
73
|
+
ManageEmojisAndStickers = 1 << 30
|
|
74
|
+
UseApplicationCommands = 1 << 31
|
|
75
|
+
RequestToSpeak = 1 << 32
|
|
76
|
+
ManageEvents = 1 << 33
|
|
77
|
+
ManageThreads = 1 << 34
|
|
78
|
+
CreatePublicThreads = 1 << 35
|
|
79
|
+
CreatePrivateThreads = 1 << 36
|
|
80
|
+
UseExternalStickers = 1 << 37
|
|
81
|
+
SendMessagesInThreads = 1 << 38
|
|
82
|
+
ModerateMembers = 1 << 40
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
class PermissionsBitField(BitField):
|
|
86
|
+
FLAGS = PermissionFlags
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
class MessageFlags(IntFlag):
|
|
90
|
+
Crossposted = 1 << 0
|
|
91
|
+
IsCrosspost = 1 << 1
|
|
92
|
+
SuppressEmbeds = 1 << 2
|
|
93
|
+
SourceMessageDeleted = 1 << 3
|
|
94
|
+
Urgent = 1 << 4
|
|
95
|
+
HasThread = 1 << 5
|
|
96
|
+
Ephemeral = 1 << 6
|
|
97
|
+
Loading = 1 << 7
|
|
98
|
+
FailedToMentionSomeRolesInThread = 1 << 8
|
|
99
|
+
SuppressNotifications = 1 << 12
|
|
100
|
+
IsVoiceMessage = 1 << 13
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
class MessageFlagsBitField(BitField):
|
|
104
|
+
FLAGS = MessageFlags
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
class PublicUserFlags(IntFlag):
|
|
108
|
+
Staff = 1 << 0
|
|
109
|
+
Partner = 1 << 1
|
|
110
|
+
Hypesquad = 1 << 2
|
|
111
|
+
BugHunterLevel1 = 1 << 3
|
|
112
|
+
HypeSquadOnlineHouse1 = 1 << 6
|
|
113
|
+
HypeSquadOnlineHouse2 = 1 << 7
|
|
114
|
+
HypeSquadOnlineHouse3 = 1 << 8
|
|
115
|
+
PremiumEarlySupporter = 1 << 9
|
|
116
|
+
TeamPseudoUser = 1 << 10
|
|
117
|
+
BugHunterLevel2 = 1 << 14
|
|
118
|
+
VerifiedBot = 1 << 16
|
|
119
|
+
VerifiedDeveloper = 1 << 17
|
|
120
|
+
CertifiedModerator = 1 << 18
|
|
121
|
+
BotHTTPInteractions = 1 << 19
|
|
122
|
+
ActiveDeveloper = 1 << 22
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
class UserFlagsBitField(BitField):
|
|
126
|
+
FLAGS = PublicUserFlags
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
from datetime import datetime
|
|
2
|
+
import io
|
|
3
|
+
import os
|
|
4
|
+
from typing import Any, Dict, List, Optional, Union
|
|
5
|
+
from .utils import resolve_color
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class AttachmentBuilder:
|
|
9
|
+
def __init__(
|
|
10
|
+
self,
|
|
11
|
+
data: Optional[Union[bytes, io.BytesIO, str]] = None,
|
|
12
|
+
*,
|
|
13
|
+
name: Optional[str] = None,
|
|
14
|
+
description: Optional[str] = None
|
|
15
|
+
):
|
|
16
|
+
self.name: str = name or "file"
|
|
17
|
+
self.description: Optional[str] = description
|
|
18
|
+
self._data: Optional[Union[bytes, io.BytesIO, str]] = data
|
|
19
|
+
|
|
20
|
+
def set_name(self, name: str) -> "AttachmentBuilder":
|
|
21
|
+
self.name = name
|
|
22
|
+
return self
|
|
23
|
+
|
|
24
|
+
def set_description(self, description: str) -> "AttachmentBuilder":
|
|
25
|
+
self.description = description
|
|
26
|
+
return self
|
|
27
|
+
|
|
28
|
+
def set_file(self, data: Union[bytes, io.BytesIO, str]) -> "AttachmentBuilder":
|
|
29
|
+
self._data = data
|
|
30
|
+
return self
|
|
31
|
+
|
|
32
|
+
def get_bytes(self) -> bytes:
|
|
33
|
+
if self._data is None:
|
|
34
|
+
return b""
|
|
35
|
+
if isinstance(self._data, bytes):
|
|
36
|
+
return self._data
|
|
37
|
+
if isinstance(self._data, io.BytesIO):
|
|
38
|
+
return self._data.getvalue()
|
|
39
|
+
if isinstance(self._data, str):
|
|
40
|
+
if os.path.exists(self._data):
|
|
41
|
+
with open(self._data, "rb") as f:
|
|
42
|
+
return f.read()
|
|
43
|
+
return self._data.encode("utf-8")
|
|
44
|
+
return b""
|
|
45
|
+
|
|
46
|
+
def to_dict(self, id_val: int = 0) -> Dict[str, Any]:
|
|
47
|
+
d: Dict[str, Any] = {
|
|
48
|
+
"id": id_val,
|
|
49
|
+
"filename": self.name
|
|
50
|
+
}
|
|
51
|
+
if self.description:
|
|
52
|
+
d["description"] = self.description
|
|
53
|
+
return d
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class EmbedBuilder:
|
|
57
|
+
def __init__(self):
|
|
58
|
+
self.title: Optional[str] = None
|
|
59
|
+
self.description: Optional[str] = None
|
|
60
|
+
self.url: Optional[str] = None
|
|
61
|
+
self.color: Optional[int] = None
|
|
62
|
+
self.timestamp: Optional[str] = None
|
|
63
|
+
self.footer: Optional[Dict[str, str]] = None
|
|
64
|
+
self.image: Optional[Dict[str, str]] = None
|
|
65
|
+
self.thumbnail: Optional[Dict[str, str]] = None
|
|
66
|
+
self.author: Optional[Dict[str, str]] = None
|
|
67
|
+
self.fields: List[Dict[str, Any]] = []
|
|
68
|
+
|
|
69
|
+
def set_title(self, title: str) -> "EmbedBuilder":
|
|
70
|
+
self.title = title
|
|
71
|
+
return self
|
|
72
|
+
|
|
73
|
+
def set_description(self, description: str) -> "EmbedBuilder":
|
|
74
|
+
self.description = description
|
|
75
|
+
return self
|
|
76
|
+
|
|
77
|
+
def set_url(self, url: str) -> "EmbedBuilder":
|
|
78
|
+
self.url = url
|
|
79
|
+
return self
|
|
80
|
+
|
|
81
|
+
def set_color(self, color: Union[int, str, List[int], tuple]) -> "EmbedBuilder":
|
|
82
|
+
self.color = resolve_color(color)
|
|
83
|
+
return self
|
|
84
|
+
|
|
85
|
+
def set_timestamp(self, timestamp: Optional[Union[datetime, str]] = None) -> "EmbedBuilder":
|
|
86
|
+
if timestamp is None:
|
|
87
|
+
self.timestamp = datetime.utcnow().isoformat() + "Z"
|
|
88
|
+
elif isinstance(timestamp, datetime):
|
|
89
|
+
self.timestamp = timestamp.isoformat() + "Z"
|
|
90
|
+
else:
|
|
91
|
+
self.timestamp = str(timestamp)
|
|
92
|
+
return self
|
|
93
|
+
|
|
94
|
+
def set_footer(self, *, text: str, icon_url: Optional[str] = None) -> "EmbedBuilder":
|
|
95
|
+
f = {"text": text}
|
|
96
|
+
if icon_url:
|
|
97
|
+
f["icon_url"] = icon_url
|
|
98
|
+
self.footer = f
|
|
99
|
+
return self
|
|
100
|
+
|
|
101
|
+
def set_image(self, url: str) -> "EmbedBuilder":
|
|
102
|
+
self.image = {"url": url}
|
|
103
|
+
return self
|
|
104
|
+
|
|
105
|
+
def set_thumbnail(self, url: str) -> "EmbedBuilder":
|
|
106
|
+
self.thumbnail = {"url": url}
|
|
107
|
+
return self
|
|
108
|
+
|
|
109
|
+
def set_author(self, *, name: str, icon_url: Optional[str] = None, url: Optional[str] = None) -> "EmbedBuilder":
|
|
110
|
+
a = {"name": name}
|
|
111
|
+
if icon_url:
|
|
112
|
+
a["icon_url"] = icon_url
|
|
113
|
+
if url:
|
|
114
|
+
a["url"] = url
|
|
115
|
+
self.author = a
|
|
116
|
+
return self
|
|
117
|
+
|
|
118
|
+
def add_field(self, *, name: str, value: str, inline: bool = False) -> "EmbedBuilder":
|
|
119
|
+
self.fields.append({"name": name, "value": value, "inline": inline})
|
|
120
|
+
return self
|
|
121
|
+
|
|
122
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
123
|
+
data: Dict[str, Any] = {}
|
|
124
|
+
if self.title:
|
|
125
|
+
data["title"] = self.title
|
|
126
|
+
if self.description:
|
|
127
|
+
data["description"] = self.description
|
|
128
|
+
if self.url:
|
|
129
|
+
data["url"] = self.url
|
|
130
|
+
if self.color is not None:
|
|
131
|
+
data["color"] = self.color
|
|
132
|
+
if self.timestamp:
|
|
133
|
+
data["timestamp"] = self.timestamp
|
|
134
|
+
if self.footer:
|
|
135
|
+
data["footer"] = self.footer
|
|
136
|
+
if self.image:
|
|
137
|
+
data["image"] = self.image
|
|
138
|
+
if self.thumbnail:
|
|
139
|
+
data["thumbnail"] = self.thumbnail
|
|
140
|
+
if self.author:
|
|
141
|
+
data["author"] = self.author
|
|
142
|
+
if self.fields:
|
|
143
|
+
data["fields"] = self.fields
|
|
144
|
+
return data
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
class MessagePayload:
|
|
148
|
+
@staticmethod
|
|
149
|
+
def create(
|
|
150
|
+
content: Optional[str] = None,
|
|
151
|
+
*,
|
|
152
|
+
embeds: Optional[List[Union[EmbedBuilder, Dict[str, Any]]]] = None,
|
|
153
|
+
files: Optional[List[AttachmentBuilder]] = None,
|
|
154
|
+
flags: Optional[int] = None,
|
|
155
|
+
reply_to_id: Optional[str] = None,
|
|
156
|
+
channel_id: Optional[str] = None,
|
|
157
|
+
guild_id: Optional[str] = None
|
|
158
|
+
) -> Dict[str, Any]:
|
|
159
|
+
payload: Dict[str, Any] = {}
|
|
160
|
+
if content is not None:
|
|
161
|
+
payload["content"] = str(content)
|
|
162
|
+
|
|
163
|
+
if embeds:
|
|
164
|
+
payload["embeds"] = [e.to_dict() if hasattr(e, "to_dict") else e for e in embeds]
|
|
165
|
+
|
|
166
|
+
if flags is not None:
|
|
167
|
+
payload["flags"] = int(flags)
|
|
168
|
+
|
|
169
|
+
if reply_to_id and channel_id:
|
|
170
|
+
payload["message_reference"] = {
|
|
171
|
+
"message_id": str(reply_to_id),
|
|
172
|
+
"channel_id": str(channel_id),
|
|
173
|
+
"guild_id": str(guild_id) if guild_id else None
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
return payload
|