modifyself 0.3.3__tar.gz → 0.3.5__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.
Files changed (50) hide show
  1. {modifyself-0.3.3 → modifyself-0.3.5}/PKG-INFO +1 -1
  2. {modifyself-0.3.3 → modifyself-0.3.5}/modifyself/__init__.py +1 -1
  3. {modifyself-0.3.3 → modifyself-0.3.5}/modifyself/commands/context.py +22 -4
  4. {modifyself-0.3.3 → modifyself-0.3.5}/modifyself/models/__init__.py +4 -1
  5. {modifyself-0.3.3 → modifyself-0.3.5}/modifyself/models/channel.py +34 -3
  6. {modifyself-0.3.3 → modifyself-0.3.5}/modifyself.egg-info/PKG-INFO +1 -1
  7. {modifyself-0.3.3 → modifyself-0.3.5}/pyproject.toml +1 -1
  8. {modifyself-0.3.3 → modifyself-0.3.5}/LICENSE +0 -0
  9. {modifyself-0.3.3 → modifyself-0.3.5}/README.md +0 -0
  10. {modifyself-0.3.3 → modifyself-0.3.5}/modifyself/activity.py +0 -0
  11. {modifyself-0.3.3 → modifyself-0.3.5}/modifyself/client.py +0 -0
  12. {modifyself-0.3.3 → modifyself-0.3.5}/modifyself/commands/__init__.py +0 -0
  13. {modifyself-0.3.3 → modifyself-0.3.5}/modifyself/commands/checks.py +0 -0
  14. {modifyself-0.3.3 → modifyself-0.3.5}/modifyself/commands/cog.py +0 -0
  15. {modifyself-0.3.3 → modifyself-0.3.5}/modifyself/commands/converters.py +0 -0
  16. {modifyself-0.3.3 → modifyself-0.3.5}/modifyself/commands/core.py +0 -0
  17. {modifyself-0.3.3 → modifyself-0.3.5}/modifyself/components.py +0 -0
  18. {modifyself-0.3.3 → modifyself-0.3.5}/modifyself/core/bitfield.py +0 -0
  19. {modifyself-0.3.3 → modifyself-0.3.5}/modifyself/core/enums.py +0 -0
  20. {modifyself-0.3.3 → modifyself-0.3.5}/modifyself/core/mixins.py +0 -0
  21. {modifyself-0.3.3 → modifyself-0.3.5}/modifyself/core/snowflake.py +0 -0
  22. {modifyself-0.3.3 → modifyself-0.3.5}/modifyself/errors.py +0 -0
  23. {modifyself-0.3.3 → modifyself-0.3.5}/modifyself/gateway/__init__.py +0 -0
  24. {modifyself-0.3.3 → modifyself-0.3.5}/modifyself/gateway/dispatcher.py +0 -0
  25. {modifyself-0.3.3 → modifyself-0.3.5}/modifyself/gateway/heartbeat.py +0 -0
  26. {modifyself-0.3.3 → modifyself-0.3.5}/modifyself/gateway/websocket.py +0 -0
  27. {modifyself-0.3.3 → modifyself-0.3.5}/modifyself/headers.py +0 -0
  28. {modifyself-0.3.3 → modifyself-0.3.5}/modifyself/http/__init__.py +0 -0
  29. {modifyself-0.3.3 → modifyself-0.3.5}/modifyself/http/client.py +0 -0
  30. {modifyself-0.3.3 → modifyself-0.3.5}/modifyself/http/ratelimit.py +0 -0
  31. {modifyself-0.3.3 → modifyself-0.3.5}/modifyself/http/route.py +0 -0
  32. {modifyself-0.3.3 → modifyself-0.3.5}/modifyself/interactions.py +0 -0
  33. {modifyself-0.3.3 → modifyself-0.3.5}/modifyself/models/base.py +0 -0
  34. {modifyself-0.3.3 → modifyself-0.3.5}/modifyself/models/billing.py +0 -0
  35. {modifyself-0.3.3 → modifyself-0.3.5}/modifyself/models/guild.py +0 -0
  36. {modifyself-0.3.3 → modifyself-0.3.5}/modifyself/models/member.py +0 -0
  37. {modifyself-0.3.3 → modifyself-0.3.5}/modifyself/models/message.py +0 -0
  38. {modifyself-0.3.3 → modifyself-0.3.5}/modifyself/models/relationship.py +0 -0
  39. {modifyself-0.3.3 → modifyself-0.3.5}/modifyself/models/settings.py +0 -0
  40. {modifyself-0.3.3 → modifyself-0.3.5}/modifyself/models/user.py +0 -0
  41. {modifyself-0.3.3 → modifyself-0.3.5}/modifyself/models/webhook.py +0 -0
  42. {modifyself-0.3.3 → modifyself-0.3.5}/modifyself/state.py +0 -0
  43. {modifyself-0.3.3 → modifyself-0.3.5}/modifyself/types.py +0 -0
  44. {modifyself-0.3.3 → modifyself-0.3.5}/modifyself/utils.py +0 -0
  45. {modifyself-0.3.3 → modifyself-0.3.5}/modifyself/voice.py +0 -0
  46. {modifyself-0.3.3 → modifyself-0.3.5}/modifyself.egg-info/SOURCES.txt +0 -0
  47. {modifyself-0.3.3 → modifyself-0.3.5}/modifyself.egg-info/dependency_links.txt +0 -0
  48. {modifyself-0.3.3 → modifyself-0.3.5}/modifyself.egg-info/requires.txt +0 -0
  49. {modifyself-0.3.3 → modifyself-0.3.5}/modifyself.egg-info/top_level.txt +0 -0
  50. {modifyself-0.3.3 → modifyself-0.3.5}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: modifyself
3
- Version: 0.3.3
3
+ Version: 0.3.5
4
4
  Summary: A clean, pythonic Discord self-bot library
5
5
  Author-email: modifyself <modifyself@example.com>
6
6
  License-Expression: MIT
@@ -2,7 +2,7 @@
2
2
  modifyself ? a clean, pythonic Discord self-bot library.
3
3
  """
4
4
 
5
- __version__ = "0.3.3"
5
+ __version__ = "0.3.5"
6
6
 
7
7
  from .client import Client
8
8
  from .commands.core import command
@@ -43,7 +43,21 @@ class Context:
43
43
  @property
44
44
  def channel(self) -> "Channel | None":
45
45
  if self._cs_channel is None:
46
- self._cs_channel = self.bot.get_channel(self.message.channel_id)
46
+ # Try to get channel from bot's state using channel_id
47
+ ch = self.bot._state._channels.get(self.message.channel_id)
48
+ if ch is None:
49
+ # Try to fetch it
50
+ import asyncio
51
+ try:
52
+ # Create a new event loop if needed
53
+ loop = asyncio.get_event_loop()
54
+ if loop.is_running():
55
+ # We're already in an async context, fetch directly
56
+ data = asyncio.create_task(self.bot._http.fetch_channel(self.message.channel_id))
57
+ # This won't work directly, we need to handle it differently
58
+ except:
59
+ pass
60
+ self._cs_channel = ch
47
61
  return self._cs_channel
48
62
 
49
63
  @property
@@ -73,9 +87,13 @@ class Context:
73
87
  async def send(self, content: str | None = None, **kwargs):
74
88
  """Send a message to the current channel."""
75
89
  ch = self.channel
76
- if ch:
77
- return await ch.send(content, **kwargs)
78
- raise RuntimeError("Cannot send: no channel available")
90
+ if ch is None:
91
+ # Fallback: use message.channel_id directly
92
+ try:
93
+ return await self.bot._http.send_message(self.message.channel_id, content, **kwargs)
94
+ except Exception as e:
95
+ raise RuntimeError(f"Cannot send: {e}")
96
+ return await ch.send(content, **kwargs)
79
97
 
80
98
  async def reply(self, content: str | None = None, **kwargs):
81
99
  """Reply to the message that invoked this command."""
@@ -1,6 +1,6 @@
1
1
  from .user import User
2
2
  from .guild import Guild
3
- from .channel import Channel, DMChannel, GroupChannel, channel_factory
3
+ from .channel import Channel, TextChannel, DMChannel, GroupChannel, VoiceChannel, CategoryChannel, channel_factory
4
4
  from .message import Message
5
5
  from .member import Member
6
6
  from .base import DiscordObject
@@ -13,8 +13,11 @@ __all__ = [
13
13
  "User",
14
14
  "Guild",
15
15
  "Channel",
16
+ "TextChannel",
16
17
  "DMChannel",
17
18
  "GroupChannel",
19
+ "VoiceChannel",
20
+ "CategoryChannel",
18
21
  "channel_factory",
19
22
  "Message",
20
23
  "Member",
@@ -2,9 +2,10 @@
2
2
  Discord Channel models.
3
3
  """
4
4
 
5
- from typing import TYPE_CHECKING
5
+ from typing import TYPE_CHECKING, Optional, List
6
6
 
7
7
  from .base import DiscordObject
8
+ from .user import User
8
9
  from ..core.enums import ChannelType
9
10
 
10
11
  if TYPE_CHECKING:
@@ -84,7 +85,6 @@ class DMChannel(Channel):
84
85
 
85
86
  def _update(self, data: dict):
86
87
  super()._update(data)
87
- from .user import User
88
88
  self.recipients = [
89
89
  User(state=self._state, data=u) for u in data.get("recipients", [])
90
90
  ]
@@ -100,6 +100,35 @@ class DMChannel(Channel):
100
100
  return f"<DMChannel id={self.id} recipient={self.recipient}>"
101
101
 
102
102
 
103
+ class GroupChannel(Channel):
104
+ """Represents a group DM channel."""
105
+
106
+ __slots__ = ("name", "icon", "recipients", "owner_id", "application_id", "managed")
107
+
108
+ def __init__(self, *, state: "ConnectionState", data: dict):
109
+ super().__init__(state=state, data=data)
110
+
111
+ def _update(self, data: dict):
112
+ super()._update(data)
113
+ self.name = data.get("name")
114
+ self.icon = data.get("icon")
115
+ self.recipients = [
116
+ User(state=self._state, data=u) for u in data.get("recipients", [])
117
+ ]
118
+ self.owner_id = int(data["owner_id"]) if data.get("owner_id") else None
119
+ self.application_id = int(data["application_id"]) if data.get("application_id") else None
120
+ self.managed = data.get("managed", False)
121
+
122
+ @property
123
+ def icon_url(self) -> Optional[str]:
124
+ if self.icon:
125
+ return f"https://cdn.discordapp.com/channel-icons/{self.id}/{self.icon}.png"
126
+ return None
127
+
128
+ def __repr__(self) -> str:
129
+ return f"<GroupChannel id={self.id} name={self.name!r}>"
130
+
131
+
103
132
  class VoiceChannel(Channel):
104
133
  """Represents a guild voice channel."""
105
134
 
@@ -142,9 +171,11 @@ def channel_factory(state: "ConnectionState", data: dict) -> Channel:
142
171
  return TextChannel(state=state, data=data)
143
172
  elif channel_type == ChannelType.DM:
144
173
  return DMChannel(state=state, data=data)
174
+ elif channel_type == ChannelType.GROUP_DM:
175
+ return GroupChannel(state=state, data=data)
145
176
  elif channel_type == ChannelType.GUILD_VOICE:
146
177
  return VoiceChannel(state=state, data=data)
147
178
  elif channel_type == ChannelType.GUILD_CATEGORY:
148
179
  return CategoryChannel(state=state, data=data)
149
180
  else:
150
- return Channel(state=state, data=data)
181
+ return Channel(state=state, data=data)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: modifyself
3
- Version: 0.3.3
3
+ Version: 0.3.5
4
4
  Summary: A clean, pythonic Discord self-bot library
5
5
  Author-email: modifyself <modifyself@example.com>
6
6
  License-Expression: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "modifyself"
7
- version = "0.3.3"
7
+ version = "0.3.5"
8
8
  description = "A clean, pythonic Discord self-bot library"
9
9
  readme = "README.md"
10
10
  license = "MIT"
File without changes
File without changes
File without changes