matrix-python 1.4.1a0__py3-none-any.whl → 1.4.4a0__py3-none-any.whl

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.
matrix/__init__.py CHANGED
@@ -15,6 +15,7 @@ from .command import Command
15
15
  from .help import HelpCommand
16
16
  from .checks import cooldown
17
17
  from .room import Room
18
+ from .message import Message
18
19
  from .extension import Extension
19
20
 
20
21
  __all__ = [
@@ -27,5 +28,6 @@ __all__ = [
27
28
  "HelpCommand",
28
29
  "cooldown",
29
30
  "Room",
31
+ "Message",
30
32
  "Extension",
31
33
  ]
matrix/_version.py CHANGED
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
18
18
  commit_id: str | None
19
19
  __commit_id__: str | None
20
20
 
21
- __version__ = version = '1.4.1a0'
22
- __version_tuple__ = version_tuple = (1, 4, 1, 'a0')
21
+ __version__ = version = '1.4.4a0'
22
+ __version_tuple__ = version_tuple = (1, 4, 4, 'a0')
23
23
 
24
24
  __commit_id__ = commit_id = None
matrix/bot.py CHANGED
@@ -3,7 +3,7 @@ import inspect
3
3
  import asyncio
4
4
  import logging
5
5
 
6
- from typing import Union, Optional, Any
6
+ from typing import Optional, Any
7
7
 
8
8
  from nio import AsyncClient, Event, MatrixRoom
9
9
 
@@ -15,7 +15,12 @@ from .extension import Extension
15
15
  from .registry import Registry
16
16
  from .help import HelpCommand, DefaultHelpCommand
17
17
  from .scheduler import Scheduler
18
- from .errors import AlreadyRegisteredError, CommandNotFoundError, CheckError
18
+ from .errors import (
19
+ AlreadyRegisteredError,
20
+ CommandNotFoundError,
21
+ CheckError,
22
+ RoomNotFoundError,
23
+ )
19
24
 
20
25
 
21
26
  class Bot(Registry):
@@ -28,29 +33,36 @@ class Bot(Registry):
28
33
  """
29
34
 
30
35
  def __init__(
31
- self, *, config: Union[Config, str], help: Optional[HelpCommand] = None
36
+ self,
37
+ *,
38
+ help_: Optional[HelpCommand] = None,
32
39
  ) -> None:
33
- if isinstance(config, Config):
34
- self.config = config
35
- elif isinstance(config, str):
36
- self.config = Config(config_path=config)
37
- else:
38
- raise TypeError("config must be a Config instance or a config file path")
40
+ super().__init__(self.__class__.__name__)
39
41
 
40
- super().__init__(self.__class__.__name__, prefix=self.config.prefix)
42
+ self._config: Config | None = None
43
+ self._client: AsyncClient | None = None
44
+ self._synced: asyncio.Event = asyncio.Event()
45
+ self._help: HelpCommand | None = help_
41
46
 
42
- self.client: AsyncClient = AsyncClient(self.config.homeserver)
43
47
  self.extensions: dict[str, Extension] = {}
44
48
  self.scheduler: Scheduler = Scheduler()
45
49
  self.log: logging.Logger = logging.getLogger(__name__)
50
+ self.start_at: float | None = None
46
51
 
47
- self.start_at: float | None = None # unix timestamp
52
+ @property
53
+ def client(self) -> AsyncClient:
54
+ assert self._client is not None, "Bot has not been started."
55
+ return self._client
48
56
 
49
- self.help: HelpCommand = help or DefaultHelpCommand(prefix=self.prefix)
50
- self.register_command(self.help)
57
+ @property
58
+ def config(self) -> Config:
59
+ assert self._config is not None, "Bot has not been started."
60
+ return self._config
51
61
 
52
- self.client.add_event_callback(self._on_matrix_event, Event)
53
- self._auto_register_events()
62
+ @property
63
+ def help(self) -> HelpCommand:
64
+ assert self._help is not None, "Bot has not been started."
65
+ return self._help
54
66
 
55
67
  def _auto_register_events(self) -> None:
56
68
  for attr in dir(self):
@@ -70,10 +82,23 @@ class Bot(Registry):
70
82
  except ValueError:
71
83
  continue
72
84
 
73
- def get_room(self, room_id: str) -> Room:
74
- """Retrieve a Room instance based on the room_id."""
75
- matrix_room = self.client.rooms[room_id]
76
- return Room(matrix_room=matrix_room, client=self.client)
85
+ def get_room(self, room_id: str) -> Room | None:
86
+ """Retrieve a `Room` instance by its Matrix room ID.
87
+
88
+ Returns the `Room` object corresponding to `room_id` if it exists in
89
+ the client's known rooms. Returns `None` if the room cannot be found.
90
+
91
+ ## Example
92
+
93
+ ```python
94
+ room = bot.get_room("!abc123:matrix.org")
95
+ if room:
96
+ print(room.name)
97
+ ```
98
+ """
99
+ if matrix_room := self.client.rooms.get(room_id):
100
+ return Room(matrix_room=matrix_room, client=self.client)
101
+ return None
77
102
 
78
103
  def load_extension(self, extension: Extension) -> None:
79
104
  self.log.debug(f"Loading extension: '{extension.name}'")
@@ -192,7 +217,26 @@ class Bot(Registry):
192
217
 
193
218
  # ENTRYPOINT
194
219
 
195
- def start(self) -> None:
220
+ def _load_config(self, config: Config | str) -> None:
221
+ if self._config is not None:
222
+ raise RuntimeError("Config is already loaded.")
223
+
224
+ if isinstance(config, str):
225
+ config = Config(config_path=config)
226
+ elif not isinstance(config, Config):
227
+ raise TypeError("config must be a Config instance or a config file path")
228
+
229
+ self._config = config
230
+ self._client = AsyncClient(config.homeserver)
231
+ self._help = self._help or DefaultHelpCommand()
232
+
233
+ self.prefix = config.prefix
234
+ self.register_command(self.help)
235
+
236
+ self.client.add_event_callback(self._on_matrix_event, Event)
237
+ self._auto_register_events()
238
+
239
+ def start(self, *, config: Config | str) -> None:
196
240
  """
197
241
  Synchronous entry point for running the bot.
198
242
 
@@ -201,6 +245,9 @@ class Bot(Registry):
201
245
  :func:`asyncio.run`, and ensures the client is closed gracefully
202
246
  on interruption.
203
247
  """
248
+ if config is not None:
249
+ self._load_config(config)
250
+
204
251
  try:
205
252
  asyncio.run(self.run())
206
253
  except KeyboardInterrupt:
@@ -228,17 +275,26 @@ class Bot(Registry):
228
275
  login_resp = await self.client.login(self.config.password)
229
276
  self.log.info("logged in: %s", login_resp)
230
277
 
231
- self.scheduler.start()
278
+ sync_task = asyncio.create_task(self.client.sync_forever(timeout=30_000))
232
279
 
280
+ await self._wait_until_synced()
233
281
  await self._on_ready()
234
- await self.client.sync_forever(timeout=30_000)
282
+
283
+ self.scheduler.start()
284
+ await sync_task
285
+
286
+ async def _wait_until_synced(self) -> None:
287
+ await self._synced.wait()
235
288
 
236
289
  # MATRIX EVENTS
237
290
 
238
- async def on_message(self, room: MatrixRoom, event: Event) -> None:
291
+ async def on_message(self, room: Room, event: Event) -> None:
239
292
  await self._process_commands(room, event)
240
293
 
241
- async def _on_matrix_event(self, room: MatrixRoom, event: Event) -> None:
294
+ async def _on_matrix_event(self, matrix_room: MatrixRoom, event: Event) -> None:
295
+ if not self._synced.is_set():
296
+ self._synced.set()
297
+
242
298
  # ignore bot events
243
299
  if event.sender == self.client.user:
244
300
  return
@@ -248,6 +304,11 @@ class Bot(Registry):
248
304
  return
249
305
 
250
306
  try:
307
+ room = self.get_room(matrix_room.room_id)
308
+
309
+ if not room:
310
+ raise RoomNotFoundError(f"Room '{matrix_room.room_id}' not found.")
311
+
251
312
  await self._dispatch_matrix_event(room, event)
252
313
  except Exception as error:
253
314
  await self._on_error(error)
@@ -257,14 +318,14 @@ class Bot(Registry):
257
318
  for handler in self._hook_handlers.get(event_name, []):
258
319
  await handler(*args, **kwargs)
259
320
 
260
- async def _dispatch_matrix_event(self, room: MatrixRoom, event: Event) -> None:
321
+ async def _dispatch_matrix_event(self, room: Room, event: Event) -> None:
261
322
  """Fire all listeners registered for a named matrix event."""
262
323
  for event_type, funcs in self._event_handlers.items():
263
324
  if isinstance(event, event_type):
264
325
  for func in funcs:
265
326
  await func(room, event)
266
327
 
267
- async def _process_commands(self, room: MatrixRoom, event: Event) -> None:
328
+ async def _process_commands(self, room: Room, event: Event) -> None:
268
329
  """Parse and execute commands"""
269
330
  ctx = await self._build_context(room, event)
270
331
 
@@ -276,8 +337,12 @@ class Bot(Registry):
276
337
  await self._on_command(ctx)
277
338
  await ctx.command(ctx)
278
339
 
279
- async def _build_context(self, matrix_room: MatrixRoom, event: Event) -> Context:
340
+ async def _build_context(self, matrix_room: Room, event: Event) -> Context:
280
341
  room = self.get_room(matrix_room.room_id)
342
+
343
+ if not room:
344
+ raise RoomNotFoundError(f"Room '{matrix_room.room_id}' not found.")
345
+
281
346
  ctx = Context(bot=self, room=room, event=event)
282
347
  prefix = self.prefix or self.config.prefix
283
348
 
matrix/errors.py CHANGED
@@ -13,6 +13,10 @@ class MatrixError(Exception):
13
13
  pass
14
14
 
15
15
 
16
+ class RoomNotFoundError(MatrixError):
17
+ pass
18
+
19
+
16
20
  class RegistryError(MatrixError):
17
21
  pass
18
22
 
matrix/extension.py CHANGED
@@ -17,7 +17,20 @@ class Extension(Registry):
17
17
  self._on_load: Optional[Callable] = None
18
18
  self._on_unload: Optional[Callable] = None
19
19
 
20
- def get_room(self, room_id: str) -> Room:
20
+ def get_room(self, room_id: str) -> Room | None:
21
+ """Retrieve a `Room` instance by its Matrix room ID.
22
+
23
+ Returns the `Room` object corresponding to `room_id` if it exists in
24
+ the client's known rooms. Returns `None` if the room cannot be found.
25
+
26
+ ## Example
27
+
28
+ ```python
29
+ room = extension.get_room("!abc123:matrix.org")
30
+ if room:
31
+ print(room.name)
32
+ ```
33
+ """
21
34
  if self.bot is None:
22
35
  raise RuntimeError("Extension is not loaded")
23
36
  return self.bot.get_room(room_id)
matrix/message.py CHANGED
@@ -1,5 +1,8 @@
1
- from typing import TYPE_CHECKING
2
- from nio import AsyncClient
1
+ from typing import TYPE_CHECKING, Self
2
+
3
+ from nio import AsyncClient, Event
4
+
5
+ from matrix.types import Reaction
3
6
  from matrix.content import ReactionContent, EditContent
4
7
  from matrix.errors import MatrixError
5
8
 
@@ -10,28 +13,35 @@ if TYPE_CHECKING:
10
13
  class Message:
11
14
  """Represents a Matrix message with methods to interact with it."""
12
15
 
13
- def __init__(
14
- self, *, room: "Room", event_id: str, body: str | None, client: AsyncClient
15
- ) -> None:
16
+ def __init__(self, *, room: "Room", event: Event, client: AsyncClient) -> None:
16
17
  self._room = room
17
- self._event_id = event_id
18
- self._body = body
18
+ self._matrix_event: Event = event
19
19
  self._client = client
20
20
 
21
+ self._body = getattr(self._matrix_event, "body", None)
22
+
23
+ def __repr__(self) -> str:
24
+ return f"<Message id={self.event_id!r} body={self.body!r}>"
25
+
21
26
  @property
22
27
  def room(self) -> "Room":
23
28
  """The room this message was sent in."""
24
29
  return self._room
25
30
 
26
31
  @property
27
- def id(self) -> str:
28
- """The event ID of this message."""
29
- return self._event_id
32
+ def event(self) -> Event:
33
+ """The matrix event of this message"""
34
+ return self._matrix_event
35
+
36
+ @property
37
+ def client(self) -> AsyncClient:
38
+ """The Matrix client."""
39
+ return self._client
30
40
 
31
41
  @property
32
42
  def event_id(self) -> str:
33
- """The event ID of this message (alias for id)."""
34
- return self._event_id
43
+ """The event ID of this message."""
44
+ return str(self._matrix_event.event_id)
35
45
 
36
46
  @property
37
47
  def body(self) -> str | None:
@@ -39,9 +49,41 @@ class Message:
39
49
  return self._body
40
50
 
41
51
  @property
42
- def client(self) -> AsyncClient:
43
- """The Matrix client."""
44
- return self._client
52
+ def key(self) -> str | None:
53
+ """The key of this message."""
54
+ return getattr(self._matrix_event, "key", None)
55
+
56
+ async def fetch_reactions(self) -> list[Reaction]:
57
+ """Fetch all reactions for this message.
58
+
59
+ Returns a dict mapping emoji to a list of sender IDs who reacted with it.
60
+
61
+ ## Example
62
+ ```python
63
+ @bot.command()
64
+ async def reactions(ctx: Context):
65
+ reactions = await ctx.message.fetch_reactions()
66
+
67
+ for emoji, senders in reactions.items():
68
+ await ctx.reply(f"{emoji}: {len(senders)} reaction(s)")
69
+ ```
70
+ """
71
+ raw: dict[str, list[str]] = {}
72
+
73
+ try:
74
+ async for event in self.client.room_get_event_relations(
75
+ room_id=self.room.room_id,
76
+ event_id=self.event_id,
77
+ ):
78
+ emoji = getattr(event, "key", None)
79
+ sender = getattr(event, "sender", None)
80
+
81
+ if emoji and sender:
82
+ raw.setdefault(emoji, []).append(sender)
83
+ except Exception as e:
84
+ raise MatrixError(f"Failed to fetch reactions: {e}")
85
+
86
+ return [Reaction(key=emoji, senders=senders) for emoji, senders in raw.items()]
45
87
 
46
88
  async def reply(self, body: str) -> "Message":
47
89
  """Reply to this message.
@@ -57,7 +99,7 @@ class Message:
57
99
  ```
58
100
  """
59
101
  try:
60
- return await self.room.send_text(content=body, reply_to=self.id)
102
+ return await self.room.send_text(content=body, reply_to=self.event_id)
61
103
  except Exception as e:
62
104
  raise MatrixError(f"Failed to send reply: {e}")
63
105
 
@@ -72,7 +114,7 @@ class Message:
72
114
  await msg.react("👍")
73
115
  ```
74
116
  """
75
- content = ReactionContent(event_id=self.id, emoji=emoji)
117
+ content = ReactionContent(event_id=self.event_id, emoji=emoji)
76
118
 
77
119
  try:
78
120
  await self.client.room_send(
@@ -95,7 +137,7 @@ class Message:
95
137
  await msg.edit("Hello world!")
96
138
  ```
97
139
  """
98
- content = EditContent(new_body, original_event_id=self.id)
140
+ content = EditContent(new_body, original_event_id=self.event_id)
99
141
 
100
142
  try:
101
143
  await self.client.room_send(
@@ -122,10 +164,7 @@ class Message:
122
164
  try:
123
165
  await self.client.room_redact(
124
166
  room_id=self.room.room_id,
125
- event_id=self.id,
167
+ event_id=self.event_id,
126
168
  )
127
169
  except Exception as e:
128
170
  raise MatrixError(f"Failed to delete message: {e}")
129
-
130
- def __repr__(self) -> str:
131
- return f"<Message id={self.id!r} body={self.body!r}>"
matrix/protocols.py CHANGED
@@ -6,4 +6,4 @@ from matrix.room import Room
6
6
  class BotLike(Protocol):
7
7
  prefix: str | None
8
8
 
9
- def get_room(self, room_id: str) -> Room: ...
9
+ def get_room(self, room_id: str) -> Room | None: ...
matrix/room.py CHANGED
@@ -1,6 +1,6 @@
1
1
  from typing import Any
2
2
 
3
- from nio import AsyncClient, MatrixRoom
3
+ from nio import AsyncClient, MatrixRoom, Event
4
4
 
5
5
  from matrix.errors import MatrixError
6
6
  from matrix.message import Message
@@ -25,6 +25,22 @@ class Room:
25
25
  self._matrix_room: MatrixRoom = matrix_room
26
26
  self._client: AsyncClient = client
27
27
 
28
+ def __getattr__(self, name: str) -> Any:
29
+ """
30
+ Fallback to MatrixRoom for attributes not explicitly defined.
31
+
32
+ This allows access to any MatrixRoom attribute not wrapped by this class.
33
+ See matrix-nio's MatrixRoom documentation for available attributes.
34
+
35
+ https://matrix-nio.readthedocs.io/en/latest/nio.html#nio.rooms.MatrixRoom
36
+ """
37
+ try:
38
+ return getattr(self._matrix_room, name)
39
+ except AttributeError:
40
+ raise AttributeError(
41
+ f"'{type(self).__name__}' object has no attribute '{name}'"
42
+ ) from None
43
+
28
44
  @property
29
45
  def matrix_room(self) -> MatrixRoom:
30
46
  """Access to underlying MatrixRoom object."""
@@ -65,22 +81,6 @@ class Room:
65
81
  """Whether the room is encrypted."""
66
82
  return self._matrix_room.encrypted # type: ignore[no-any-return]
67
83
 
68
- def __getattr__(self, name: str) -> Any:
69
- """
70
- Fallback to MatrixRoom for attributes not explicitly defined.
71
-
72
- This allows access to any MatrixRoom attribute not wrapped by this class.
73
- See matrix-nio's MatrixRoom documentation for available attributes.
74
-
75
- https://matrix-nio.readthedocs.io/en/latest/nio.html#nio.rooms.MatrixRoom
76
- """
77
- try:
78
- return getattr(self._matrix_room, name)
79
- except AttributeError:
80
- raise AttributeError(
81
- f"'{type(self).__name__}' object has no attribute '{name}'"
82
- ) from None
83
-
84
84
  async def send(
85
85
  self,
86
86
  content: str | None = None,
@@ -319,16 +319,50 @@ class Room:
319
319
  message_type="m.room.message",
320
320
  content=payload.build(),
321
321
  )
322
+ event = await self.fetch_event(resp.event_id)
322
323
 
323
324
  return Message(
324
325
  room=self,
325
- event_id=resp.event_id,
326
- body=getattr(payload, "body", None),
326
+ event=event,
327
327
  client=self.client,
328
328
  )
329
329
  except Exception as e:
330
330
  raise MatrixError(f"Failed to send message: {e}")
331
331
 
332
+ async def fetch_event(self, event_id: str) -> Event:
333
+ """Fetch a Matrix event by its ID.
334
+
335
+ ## Example
336
+ ```python
337
+ event = await room.fetch_event("$event_id:matrix.org")
338
+ print(event.sender)
339
+ ```
340
+ """
341
+ try:
342
+ response = await self.client.room_get_event(
343
+ room_id=self.room_id,
344
+ event_id=event_id,
345
+ )
346
+ return response.event
347
+ except Exception as e:
348
+ raise MatrixError(f"Failed to get event: {e}")
349
+
350
+ async def fetch_message(self, event_id: str) -> Message:
351
+ """Fetch a Message by its event ID.
352
+
353
+ ## Example
354
+ ```python
355
+ message = await room.fetch_message("$event_id:matrix.org")
356
+ message.reply("hello world")
357
+ ```
358
+ """
359
+ event = await self.fetch_event(event_id)
360
+ return Message(
361
+ room=self,
362
+ event=event,
363
+ client=self.client,
364
+ )
365
+
332
366
  async def invite_user(self, user_id: str) -> None:
333
367
  """Invite a user to the room.
334
368
 
matrix/types.py CHANGED
@@ -24,3 +24,9 @@ class Video(File):
24
24
  width: int = 0
25
25
  height: int = 0
26
26
  duration: int = 0
27
+
28
+
29
+ @dataclass
30
+ class Reaction:
31
+ key: str
32
+ senders: list[str]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: matrix-python
3
- Version: 1.4.1a0
3
+ Version: 1.4.4a0
4
4
  Summary: An easy-to-use Matrix bot framework designed for quick development and minimal setup
5
5
  Author: Simon Roy, Chris Dedman Rollet
6
6
  Maintainer-email: Code Society Lab <admin@codesociety.xyz>
@@ -718,6 +718,7 @@ decorator-based API similar to popular event-driven frameworks, allowing
718
718
  developers to focus on behavior rather than boilerplate.
719
719
 
720
720
  #### Key Features
721
+
721
722
  - Minimal setup, easy to extend
722
723
  - Event-driven API using async/await
723
724
  - Clean command registration
@@ -727,6 +728,7 @@ developers to focus on behavior rather than boilerplate.
727
728
  # Quickstart
728
729
 
729
730
  **Requirements**
731
+
730
732
  - Python 3.10+
731
733
 
732
734
  ```
@@ -734,38 +736,45 @@ pip install matrix-python
734
736
  ```
735
737
 
736
738
  If you plan on contributing to matrix.py, we recommend to install the development libraries:
739
+
737
740
  ```
738
741
  pip install -e .[dev]
739
742
  ```
740
743
 
741
- *Note*: It is recommended to use a [virtual environment](https://packaging.python.org/en/latest/guides/installing-using-pip-and-virtual-environments/) when installing python packages.
742
-
744
+ *Note*: It is recommended to use
745
+ a [virtual environment](https://packaging.python.org/en/latest/guides/installing-using-pip-and-virtual-environments/)
746
+ when installing python packages.
743
747
 
744
748
  ```python
745
749
  from matrix import Bot, Context
746
750
 
747
- bot = Bot(config="config.yml")
751
+ bot = Bot()
748
752
 
749
753
 
750
754
  @bot.command("ping")
751
755
  async def ping(ctx: Context):
752
- await ctx.send("Pong!")
756
+ await ctx.reply("Pong!")
753
757
 
754
758
 
755
- bot.start()
759
+ bot.start(config="config.yml")
756
760
  ```
757
761
 
758
762
  [Documentation](https://github.com/Code-Society-Lab/matrixpy/wiki) - [Examples](https://github.com/Code-Society-Lab/matrixpy/tree/main/examples)
759
763
 
760
764
  # Contributing
761
- We welcome everyone to contribute!
765
+
766
+ We welcome everyone to contribute!
762
767
 
763
768
  Whether it's fixing bugs, suggesting features, or improving the docs - every bit helps.
769
+
764
770
  - Submit an issue
765
771
  - Open a pull request
766
- - Or just hop into our [Matrix](https://matrix.to/#/%23codesociety:matrix.org) or [Discord](https://discord.gg/code-society-823178343943897088) server and say hi!
772
+ - Or just hop into our [Matrix](https://matrix.to/#/%23codesociety:matrix.org)
773
+ or [Discord](https://discord.gg/code-society-823178343943897088) server and say hi!
767
774
 
768
- If you intend to contribute, please read the [CONTRIBUTING.md](./CONTRIBUTING.md) first. Additionally, **every contributor** is expected to follow the [code of conduct](./CODE_OF_CONDUCT.md).
775
+ If you intend to contribute, please read the [CONTRIBUTING.md](./CONTRIBUTING.md) first. Additionally, **every
776
+ contributor** is expected to follow the [code of conduct](./CODE_OF_CONDUCT.md).
769
777
 
770
778
  # License
779
+
771
780
  matrix.py is released under [GPL-3.0](https://opensource.org/license/gpl-3-0)
@@ -0,0 +1,24 @@
1
+ matrix/__init__.py,sha256=g8yEFjELnnwlvOKns-Ug6LgOezkjAFZ-Opt7esbBHKg,728
2
+ matrix/_version.py,sha256=tcfrwnvkUDHHz8JoKK522ystGqqHOEnmR8F4E8SoWsI,528
3
+ matrix/bot.py,sha256=4gwL2vawLFEREwZD4cEydv6XSXm_SP6pztLD8uwB86M,11944
4
+ matrix/checks.py,sha256=F_7432_OcFO-im4fRAj62MUsyv1mXywT4OsGC_7xbBQ,486
5
+ matrix/command.py,sha256=GrP3WsT07sKehGX7PHfnT7gRX22d99877VPd0X2ViEw,10514
6
+ matrix/config.py,sha256=wPLfcHGpSapkBqbZIuI7zBdxh52OHTD8cQS0WqQkMeU,2388
7
+ matrix/content.py,sha256=z5_E2rTvHsODE52OiDkhDHNQAryx5NLhyHjBb65Xe-U,3853
8
+ matrix/context.py,sha256=-CbxY-LtK9-jgHERhvJH73B3SpO-Uk5ty0j1TMKfzuI,4032
9
+ matrix/errors.py,sha256=HKGb5NUeFuZvieXgpLlVSmUxK4jpA0ODuiPQqQlbQTE,1676
10
+ matrix/extension.py,sha256=RbCx58CdRXF8kGUgS-ec1aZdd-K5hQedhCCQ0-YR4Vg,2272
11
+ matrix/group.py,sha256=TRIX7PE3lcB2ZWu3xY2W2OAmE_a8-i2zHNBYnX5uj28,3691
12
+ matrix/message.py,sha256=w6pu86goylxdrX5fgXPUMB_tW0bOFIk6tKy6qkXTjl4,5136
13
+ matrix/protocols.py,sha256=nFb4tLanwtrKWoIhZ96xMwXPjD3RF5ITca_yXtakXC4,166
14
+ matrix/registry.py,sha256=jxXg_f_pVl6nuwLdVOIjWJ9Yl9hDJSLwoChnnr3ztNs,12753
15
+ matrix/room.py,sha256=PBuMWQo8mKy2d2XIeMbBlVBTnnqZjOPPGpKLp4K1AVM,14038
16
+ matrix/scheduler.py,sha256=EXsL9i8IDXhcpdW8lti0BR5XcIgkmud4iwOPaqcE9Gw,1727
17
+ matrix/types.py,sha256=UFjC7p8RAf7piEPvp2X3NuWdqBwkM9Yc3He7KWb9icc,384
18
+ matrix/help/__init__.py,sha256=1u7V7T_-VgYDeQCTXsc4y8Fo-8gJhOqYJq2U3cUjMWg,168
19
+ matrix/help/help_command.py,sha256=xCLmKklw74LEMjbUfgQR9eaPMFvi3sPtDw2n2pnAnVQ,12800
20
+ matrix/help/pagination.py,sha256=sJk0wC46sFHf7xl7WsGRAUc4FC7b9hPqmwQDmvcjwgM,2717
21
+ matrix_python-1.4.4a0.dist-info/METADATA,sha256=zswqUmzf_FyaRISg-p2Rqxqocwb9vwHT7Ldr51d4K5A,44541
22
+ matrix_python-1.4.4a0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
23
+ matrix_python-1.4.4a0.dist-info/top_level.txt,sha256=BvHVM9c7-5SLzg-1OCRpHKgqAubWhRN1e38e6coHs-g,7
24
+ matrix_python-1.4.4a0.dist-info/RECORD,,
@@ -1,24 +0,0 @@
1
- matrix/__init__.py,sha256=Wo5-bisd2CLwH5p48d2AwqaCeYtGi78GWeMkvJRuaTk,684
2
- matrix/_version.py,sha256=hLbk0OM_vBZ8bjp25JufFvnWCZ7E5n03qPCWDS3CuPc,528
3
- matrix/bot.py,sha256=FqM4uRGFk7lEgJXgmOFDUdmuEb-Oa8CYzJh1X7rjebk,10258
4
- matrix/checks.py,sha256=F_7432_OcFO-im4fRAj62MUsyv1mXywT4OsGC_7xbBQ,486
5
- matrix/command.py,sha256=GrP3WsT07sKehGX7PHfnT7gRX22d99877VPd0X2ViEw,10514
6
- matrix/config.py,sha256=wPLfcHGpSapkBqbZIuI7zBdxh52OHTD8cQS0WqQkMeU,2388
7
- matrix/content.py,sha256=z5_E2rTvHsODE52OiDkhDHNQAryx5NLhyHjBb65Xe-U,3853
8
- matrix/context.py,sha256=-CbxY-LtK9-jgHERhvJH73B3SpO-Uk5ty0j1TMKfzuI,4032
9
- matrix/errors.py,sha256=_9WtZ2D0RxYCQTwItImUEjfD1qjvkQWPn5ZG3VUsUn4,1627
10
- matrix/extension.py,sha256=7zBTlqVC-9F8RY60Loo65YgdVoJa5QDFeiz8nHjuebo,1883
11
- matrix/group.py,sha256=TRIX7PE3lcB2ZWu3xY2W2OAmE_a8-i2zHNBYnX5uj28,3691
12
- matrix/message.py,sha256=7L9M354VM0KWmzL0032-Nq_2wBrSvbqy7KixMXocP-Q,3752
13
- matrix/protocols.py,sha256=UC7F8T2pPffBMf_QiANXtga50rznSfUsJ7pxpKhQGPQ,159
14
- matrix/registry.py,sha256=jxXg_f_pVl6nuwLdVOIjWJ9Yl9hDJSLwoChnnr3ztNs,12753
15
- matrix/room.py,sha256=uNcUrqHhHK98fCxnVZUwLk1nR-4No0Wlx-RG-J9_lQA,13051
16
- matrix/scheduler.py,sha256=EXsL9i8IDXhcpdW8lti0BR5XcIgkmud4iwOPaqcE9Gw,1727
17
- matrix/types.py,sha256=FHnSYmf5yB99kR9ZCeXLAqNcbWkt0zG75s_TD2pIp2Q,319
18
- matrix/help/__init__.py,sha256=1u7V7T_-VgYDeQCTXsc4y8Fo-8gJhOqYJq2U3cUjMWg,168
19
- matrix/help/help_command.py,sha256=xCLmKklw74LEMjbUfgQR9eaPMFvi3sPtDw2n2pnAnVQ,12800
20
- matrix/help/pagination.py,sha256=sJk0wC46sFHf7xl7WsGRAUc4FC7b9hPqmwQDmvcjwgM,2717
21
- matrix_python-1.4.1a0.dist-info/METADATA,sha256=DOdiTiUth4zsbzKq_PtFR-L6CYFaCdtbkSq5VVED0Uw,44534
22
- matrix_python-1.4.1a0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
23
- matrix_python-1.4.1a0.dist-info/top_level.txt,sha256=BvHVM9c7-5SLzg-1OCRpHKgqAubWhRN1e38e6coHs-g,7
24
- matrix_python-1.4.1a0.dist-info/RECORD,,