pylolka 0.1.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.
Files changed (196) hide show
  1. pylolka-0.1.0/LICENSE +22 -0
  2. pylolka-0.1.0/MANIFEST.in +19 -0
  3. pylolka-0.1.0/PKG-INFO +223 -0
  4. pylolka-0.1.0/README.rst +176 -0
  5. pylolka-0.1.0/lolka/__init__.py +124 -0
  6. pylolka-0.1.0/lolka/__main__.py +380 -0
  7. pylolka-0.1.0/lolka/_version.py +105 -0
  8. pylolka-0.1.0/lolka/abc.py +2104 -0
  9. pylolka-0.1.0/lolka/activity.py +881 -0
  10. pylolka-0.1.0/lolka/appinfo.py +650 -0
  11. pylolka-0.1.0/lolka/application_role_connection.py +128 -0
  12. pylolka-0.1.0/lolka/asset.py +557 -0
  13. pylolka-0.1.0/lolka/audit_logs.py +719 -0
  14. pylolka-0.1.0/lolka/automod.py +560 -0
  15. pylolka-0.1.0/lolka/backoff.py +101 -0
  16. pylolka-0.1.0/lolka/bin/libopus-0.x64.dll +0 -0
  17. pylolka-0.1.0/lolka/bin/libopus-0.x86.dll +0 -0
  18. pylolka-0.1.0/lolka/bot.py +1686 -0
  19. pylolka-0.1.0/lolka/channel.py +3649 -0
  20. pylolka-0.1.0/lolka/client.py +2387 -0
  21. pylolka-0.1.0/lolka/cog.py +1168 -0
  22. pylolka-0.1.0/lolka/collectibles.py +136 -0
  23. pylolka-0.1.0/lolka/colour.py +411 -0
  24. pylolka-0.1.0/lolka/commands/__init__.py +29 -0
  25. pylolka-0.1.0/lolka/commands/context.py +476 -0
  26. pylolka-0.1.0/lolka/commands/core.py +2295 -0
  27. pylolka-0.1.0/lolka/commands/options.py +557 -0
  28. pylolka-0.1.0/lolka/commands/permissions.py +139 -0
  29. pylolka-0.1.0/lolka/components.py +1823 -0
  30. pylolka-0.1.0/lolka/context_managers.py +90 -0
  31. pylolka-0.1.0/lolka/embeds.py +1079 -0
  32. pylolka-0.1.0/lolka/emoji.py +435 -0
  33. pylolka-0.1.0/lolka/emojis.json +1 -0
  34. pylolka-0.1.0/lolka/enums.py +1233 -0
  35. pylolka-0.1.0/lolka/errors.py +434 -0
  36. pylolka-0.1.0/lolka/ext/bridge/__init__.py +28 -0
  37. pylolka-0.1.0/lolka/ext/bridge/bot.py +204 -0
  38. pylolka-0.1.0/lolka/ext/bridge/context.py +203 -0
  39. pylolka-0.1.0/lolka/ext/bridge/core.py +689 -0
  40. pylolka-0.1.0/lolka/ext/commands/__init__.py +19 -0
  41. pylolka-0.1.0/lolka/ext/commands/_types.py +49 -0
  42. pylolka-0.1.0/lolka/ext/commands/bot.py +457 -0
  43. pylolka-0.1.0/lolka/ext/commands/cog.py +85 -0
  44. pylolka-0.1.0/lolka/ext/commands/context.py +411 -0
  45. pylolka-0.1.0/lolka/ext/commands/converter.py +1269 -0
  46. pylolka-0.1.0/lolka/ext/commands/cooldowns.py +409 -0
  47. pylolka-0.1.0/lolka/ext/commands/core.py +2501 -0
  48. pylolka-0.1.0/lolka/ext/commands/errors.py +1022 -0
  49. pylolka-0.1.0/lolka/ext/commands/flags.py +700 -0
  50. pylolka-0.1.0/lolka/ext/commands/help.py +1412 -0
  51. pylolka-0.1.0/lolka/ext/commands/view.py +200 -0
  52. pylolka-0.1.0/lolka/ext/pages/__init__.py +10 -0
  53. pylolka-0.1.0/lolka/ext/pages/pagination.py +1340 -0
  54. pylolka-0.1.0/lolka/ext/tasks/__init__.py +858 -0
  55. pylolka-0.1.0/lolka/file.py +206 -0
  56. pylolka-0.1.0/lolka/flags.py +1840 -0
  57. pylolka-0.1.0/lolka/gateway.py +800 -0
  58. pylolka-0.1.0/lolka/guild.py +4723 -0
  59. pylolka-0.1.0/lolka/http.py +3396 -0
  60. pylolka-0.1.0/lolka/incidents.py +87 -0
  61. pylolka-0.1.0/lolka/integrations.py +374 -0
  62. pylolka-0.1.0/lolka/interactions.py +1944 -0
  63. pylolka-0.1.0/lolka/invite.py +818 -0
  64. pylolka-0.1.0/lolka/iterators.py +1303 -0
  65. pylolka-0.1.0/lolka/member.py +1312 -0
  66. pylolka-0.1.0/lolka/mentions.py +158 -0
  67. pylolka-0.1.0/lolka/message.py +2623 -0
  68. pylolka-0.1.0/lolka/mixins.py +48 -0
  69. pylolka-0.1.0/lolka/monetization.py +350 -0
  70. pylolka-0.1.0/lolka/object.py +117 -0
  71. pylolka-0.1.0/lolka/oggparse.py +122 -0
  72. pylolka-0.1.0/lolka/onboarding.py +483 -0
  73. pylolka-0.1.0/lolka/opus.py +733 -0
  74. pylolka-0.1.0/lolka/partial_emoji.py +265 -0
  75. pylolka-0.1.0/lolka/permissions.py +900 -0
  76. pylolka-0.1.0/lolka/player.py +944 -0
  77. pylolka-0.1.0/lolka/poll.py +529 -0
  78. pylolka-0.1.0/lolka/primary_guild.py +98 -0
  79. pylolka-0.1.0/lolka/py.typed +0 -0
  80. pylolka-0.1.0/lolka/raw_models.py +1032 -0
  81. pylolka-0.1.0/lolka/reaction.py +296 -0
  82. pylolka-0.1.0/lolka/role.py +935 -0
  83. pylolka-0.1.0/lolka/scheduled_events.py +578 -0
  84. pylolka-0.1.0/lolka/shard.py +586 -0
  85. pylolka-0.1.0/lolka/sinks/__init__.py +20 -0
  86. pylolka-0.1.0/lolka/sinks/core.py +250 -0
  87. pylolka-0.1.0/lolka/sinks/errors.py +89 -0
  88. pylolka-0.1.0/lolka/sinks/m4a.py +103 -0
  89. pylolka-0.1.0/lolka/sinks/mka.py +96 -0
  90. pylolka-0.1.0/lolka/sinks/mkv.py +95 -0
  91. pylolka-0.1.0/lolka/sinks/mp3.py +96 -0
  92. pylolka-0.1.0/lolka/sinks/mp4.py +103 -0
  93. pylolka-0.1.0/lolka/sinks/ogg.py +96 -0
  94. pylolka-0.1.0/lolka/sinks/pcm.py +45 -0
  95. pylolka-0.1.0/lolka/sinks/wave.py +74 -0
  96. pylolka-0.1.0/lolka/soundboard.py +269 -0
  97. pylolka-0.1.0/lolka/stage_instance.py +199 -0
  98. pylolka-0.1.0/lolka/state.py +2291 -0
  99. pylolka-0.1.0/lolka/sticker.py +554 -0
  100. pylolka-0.1.0/lolka/team.py +180 -0
  101. pylolka-0.1.0/lolka/template.py +280 -0
  102. pylolka-0.1.0/lolka/threads.py +939 -0
  103. pylolka-0.1.0/lolka/types/__init__.py +9 -0
  104. pylolka-0.1.0/lolka/types/activity.py +111 -0
  105. pylolka-0.1.0/lolka/types/appinfo.py +95 -0
  106. pylolka-0.1.0/lolka/types/application_role_connection.py +40 -0
  107. pylolka-0.1.0/lolka/types/audit_log.py +296 -0
  108. pylolka-0.1.0/lolka/types/automod.py +91 -0
  109. pylolka-0.1.0/lolka/types/channel.py +196 -0
  110. pylolka-0.1.0/lolka/types/collectibles.py +45 -0
  111. pylolka-0.1.0/lolka/types/components.py +256 -0
  112. pylolka-0.1.0/lolka/types/embed.py +103 -0
  113. pylolka-0.1.0/lolka/types/emoji.py +50 -0
  114. pylolka-0.1.0/lolka/types/gateway.py +42 -0
  115. pylolka-0.1.0/lolka/types/guild.py +212 -0
  116. pylolka-0.1.0/lolka/types/integration.py +83 -0
  117. pylolka-0.1.0/lolka/types/interactions.py +296 -0
  118. pylolka-0.1.0/lolka/types/invite.py +106 -0
  119. pylolka-0.1.0/lolka/types/member.py +92 -0
  120. pylolka-0.1.0/lolka/types/message.py +196 -0
  121. pylolka-0.1.0/lolka/types/monetization.py +78 -0
  122. pylolka-0.1.0/lolka/types/onboarding.py +65 -0
  123. pylolka-0.1.0/lolka/types/poll.py +64 -0
  124. pylolka-0.1.0/lolka/types/primary_guild.py +36 -0
  125. pylolka-0.1.0/lolka/types/raw_models.py +167 -0
  126. pylolka-0.1.0/lolka/types/role.py +62 -0
  127. pylolka-0.1.0/lolka/types/scheduled_events.py +65 -0
  128. pylolka-0.1.0/lolka/types/snowflake.py +29 -0
  129. pylolka-0.1.0/lolka/types/soundboard.py +42 -0
  130. pylolka-0.1.0/lolka/types/sticker.py +91 -0
  131. pylolka-0.1.0/lolka/types/team.py +46 -0
  132. pylolka-0.1.0/lolka/types/template.py +51 -0
  133. pylolka-0.1.0/lolka/types/threads.py +76 -0
  134. pylolka-0.1.0/lolka/types/user.py +57 -0
  135. pylolka-0.1.0/lolka/types/voice.py +89 -0
  136. pylolka-0.1.0/lolka/types/webhook.py +65 -0
  137. pylolka-0.1.0/lolka/types/welcome_screen.py +42 -0
  138. pylolka-0.1.0/lolka/types/widget.py +64 -0
  139. pylolka-0.1.0/lolka/ui/__init__.py +30 -0
  140. pylolka-0.1.0/lolka/ui/action_row.py +436 -0
  141. pylolka-0.1.0/lolka/ui/button.py +419 -0
  142. pylolka-0.1.0/lolka/ui/checkbox.py +137 -0
  143. pylolka-0.1.0/lolka/ui/checkbox_group.py +286 -0
  144. pylolka-0.1.0/lolka/ui/container.py +442 -0
  145. pylolka-0.1.0/lolka/ui/core.py +157 -0
  146. pylolka-0.1.0/lolka/ui/file.py +150 -0
  147. pylolka-0.1.0/lolka/ui/file_upload.py +199 -0
  148. pylolka-0.1.0/lolka/ui/input_text.py +299 -0
  149. pylolka-0.1.0/lolka/ui/item.py +269 -0
  150. pylolka-0.1.0/lolka/ui/label.py +566 -0
  151. pylolka-0.1.0/lolka/ui/media_gallery.py +179 -0
  152. pylolka-0.1.0/lolka/ui/modal.py +527 -0
  153. pylolka-0.1.0/lolka/ui/radio_group.py +236 -0
  154. pylolka-0.1.0/lolka/ui/section.py +358 -0
  155. pylolka-0.1.0/lolka/ui/select.py +1181 -0
  156. pylolka-0.1.0/lolka/ui/separator.py +122 -0
  157. pylolka-0.1.0/lolka/ui/text_display.py +110 -0
  158. pylolka-0.1.0/lolka/ui/thumbnail.py +153 -0
  159. pylolka-0.1.0/lolka/ui/view.py +1050 -0
  160. pylolka-0.1.0/lolka/user.py +747 -0
  161. pylolka-0.1.0/lolka/utils.py +1715 -0
  162. pylolka-0.1.0/lolka/voice/__init__.py +13 -0
  163. pylolka-0.1.0/lolka/voice/_types.py +166 -0
  164. pylolka-0.1.0/lolka/voice/_voice_impl.py +859 -0
  165. pylolka-0.1.0/lolka/voice/client.py +1034 -0
  166. pylolka-0.1.0/lolka/voice/enums.py +79 -0
  167. pylolka-0.1.0/lolka/voice/gateway.py +521 -0
  168. pylolka-0.1.0/lolka/voice/packets/__init__.py +63 -0
  169. pylolka-0.1.0/lolka/voice/packets/core.py +93 -0
  170. pylolka-0.1.0/lolka/voice/packets/rtp.py +320 -0
  171. pylolka-0.1.0/lolka/voice/receive/__init__.py +33 -0
  172. pylolka-0.1.0/lolka/voice/receive/reader.py +577 -0
  173. pylolka-0.1.0/lolka/voice/receive/router.py +231 -0
  174. pylolka-0.1.0/lolka/voice/state.py +983 -0
  175. pylolka-0.1.0/lolka/voice/utils/__init__.py +0 -0
  176. pylolka-0.1.0/lolka/voice/utils/buffer.py +215 -0
  177. pylolka-0.1.0/lolka/voice/utils/dependencies.py +40 -0
  178. pylolka-0.1.0/lolka/voice/utils/multidataevent.py +79 -0
  179. pylolka-0.1.0/lolka/voice/utils/wrapped.py +32 -0
  180. pylolka-0.1.0/lolka/webhook/__init__.py +12 -0
  181. pylolka-0.1.0/lolka/webhook/async_.py +2213 -0
  182. pylolka-0.1.0/lolka/webhook/sync.py +1320 -0
  183. pylolka-0.1.0/lolka/welcome_screen.py +234 -0
  184. pylolka-0.1.0/lolka/widget.py +348 -0
  185. pylolka-0.1.0/pylolka.egg-info/PKG-INFO +223 -0
  186. pylolka-0.1.0/pylolka.egg-info/SOURCES.txt +194 -0
  187. pylolka-0.1.0/pylolka.egg-info/dependency_links.txt +1 -0
  188. pylolka-0.1.0/pylolka.egg-info/requires.txt +25 -0
  189. pylolka-0.1.0/pylolka.egg-info/top_level.txt +1 -0
  190. pylolka-0.1.0/pyproject.toml +142 -0
  191. pylolka-0.1.0/requirements/_.txt +4 -0
  192. pylolka-0.1.0/requirements/docs.txt +11 -0
  193. pylolka-0.1.0/requirements/speed.txt +2 -0
  194. pylolka-0.1.0/requirements/voice.txt +2 -0
  195. pylolka-0.1.0/setup.cfg +4 -0
  196. pylolka-0.1.0/setup.py +4 -0
pylolka-0.1.0/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015-2021 Rapptz
4
+ Copyright (c) 2021-present Pycord Development
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a
7
+ copy of this software and associated documentation files (the "Software"),
8
+ to deal in the Software without restriction, including without limitation
9
+ the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
+ and/or sell copies of the Software, and to permit persons to whom the
11
+ Software is furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in
14
+ all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22
+ DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,19 @@
1
+ include README.rst
2
+ include LICENSE
3
+ include requirements.txt
4
+ include lolka/bin/*.dll
5
+ include lolka/py.typed
6
+ include lolka/emojis.json
7
+
8
+ prune .github
9
+ prune docs
10
+ prune examples
11
+ prune tests
12
+ exclude lolka/bin/COPYING
13
+ exclude .flake8
14
+ exclude .gitignore
15
+ exclude .pre-commit-config.yaml
16
+ exclude .prettierrc
17
+ exclude .readthedocs.yml
18
+ exclude CHANGELOG.md
19
+ exclude FUNDING.yml
pylolka-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,223 @@
1
+ Metadata-Version: 2.4
2
+ Name: pylolka
3
+ Version: 0.1.0
4
+ Summary: A Python wrapper for the lolka bot API (pycord-compatible fork)
5
+ Author: lolka
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/Lolka-App/pylolka
8
+ Project-URL: Issue tracker, https://github.com/Lolka-App/pylolka/issues
9
+ Classifier: Development Status :: 5 - Production/Stable
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: Natural Language :: English
12
+ Classifier: Operating System :: OS Independent
13
+ Classifier: Programming Language :: Python :: 3.10
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.13
17
+ Classifier: Programming Language :: Python :: 3.14
18
+ Classifier: Topic :: Internet
19
+ Classifier: Topic :: Software Development :: Libraries
20
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
21
+ Classifier: Topic :: Utilities
22
+ Classifier: Typing :: Typed
23
+ Requires-Python: <3.15,>=3.10
24
+ Description-Content-Type: text/x-rst
25
+ License-File: LICENSE
26
+ Requires-Dist: aiohttp<4.0,>=3.13.2
27
+ Requires-Dist: typing_extensions<5,>=4.12.0
28
+ Requires-Dist: aiortc>=1.9.0
29
+ Requires-Dist: pymediasoup>=1.5.0
30
+ Provides-Extra: docs
31
+ Requires-Dist: sphinx==9.1.0; python_version >= "3.13" and extra == "docs"
32
+ Requires-Dist: sphinxcontrib_trio==1.2.0; python_version >= "3.13" and extra == "docs"
33
+ Requires-Dist: sphinxcontrib-websupport==2.0.0; python_version >= "3.13" and extra == "docs"
34
+ Requires-Dist: myst-parser[linkify]==5.1.0; python_version >= "3.13" and extra == "docs"
35
+ Requires-Dist: sphinxext-opengraph==0.13.0; python_version >= "3.13" and extra == "docs"
36
+ Requires-Dist: sphinx-copybutton==0.5.2; python_version >= "3.13" and extra == "docs"
37
+ Requires-Dist: furo==2025.12.19; python_version >= "3.13" and extra == "docs"
38
+ Requires-Dist: sphinx-autodoc-typehints==3.12.1; python_version >= "3.13" and extra == "docs"
39
+ Requires-Dist: sphinx-intl==2.3.2; python_version >= "3.13" and extra == "docs"
40
+ Requires-Dist: typing_extensions==4.16.0; python_version >= "3.13" and extra == "docs"
41
+ Requires-Dist: levenshtein==0.27.3; python_version >= "3.13" and extra == "docs"
42
+ Provides-Extra: speed
43
+ Requires-Dist: msgspec~=0.21.0; extra == "speed"
44
+ Requires-Dist: aiohttp[speedups]; extra == "speed"
45
+ Provides-Extra: voice
46
+ Dynamic: license-file
47
+
48
+ pylolka
49
+ =======
50
+
51
+ **Fork of** `pycord <https://github.com/Pycord-Development/pycord>`_ **(MIT License, © 2015-2021 Rapptz, © 2021-present Pycord Development).**
52
+
53
+ ``pylolka`` (imported as ``import lolka``) is a Python wrapper for the **lolka** bot API, built on
54
+ py-cord 2.8.1. It targets lolka by default — no manual REST/Gateway overrides needed — decodes lolka
55
+ snowflakes, and resolves lolka CDN asset URLs. Slash commands, cogs, UI components, ``lolka.ext.commands``,
56
+ ``lolka.ext.bridge``, ``lolka.ext.pages`` and ``lolka.ext.tasks`` keep the py-cord API. See ``LICENSE`` for
57
+ licensing (the original MIT copyrights are retained).
58
+
59
+ Installing
60
+ ----------
61
+
62
+ **Python 3.10 or higher is required**
63
+
64
+ .. code:: sh
65
+
66
+ # Linux/macOS
67
+ python3 -m pip install -U pylolka
68
+
69
+ # Windows
70
+ py -3 -m pip install -U pylolka
71
+
72
+ Quick Example
73
+ -------------
74
+
75
+ .. code:: py
76
+
77
+ import lolka
78
+
79
+ bot = lolka.Bot()
80
+
81
+ @bot.slash_command()
82
+ async def ping(ctx):
83
+ await ctx.respond("pong")
84
+
85
+ bot.run("token")
86
+
87
+ Bot Example
88
+ ~~~~~~~~~~~
89
+
90
+ .. code:: py
91
+
92
+ import lolka
93
+ from lolka.ext import commands
94
+
95
+ intents = lolka.Intents.default()
96
+ intents.message_content = True
97
+ bot = commands.Bot(command_prefix=">", intents=intents)
98
+
99
+ @bot.command()
100
+ async def ping(ctx):
101
+ await ctx.send("pong")
102
+
103
+ bot.run("token")
104
+
105
+ Configuration
106
+ -------------
107
+
108
+ The defaults point to lolka. They are read from the environment when ``lolka`` is imported,
109
+ so set them before ``import lolka``:
110
+
111
+ - ``LOLKA_API_BASE`` — REST API base URL (default ``https://lolka.app/api/bot``)
112
+ - ``LOLKA_GATEWAY`` — Gateway URL (default ``wss://lolka.app/ws/bot``)
113
+ - ``LOLKA_CDN`` — CDN base URL for asset links (default ``https://cdn.lolka.app``)
114
+
115
+ Voice
116
+ -----
117
+
118
+ Voice works over WebRTC (lolka's voice stack), not Discord's UDP/PyNaCl/DAVE transport.
119
+ The required dependencies (``aiortc``, ``pymediasoup``) ship with the base install — nothing extra to add.
120
+
121
+ The API stays py-cord-compatible — ``await channel.connect()`` returns a ``VoiceClient`` that speaks
122
+ lolka's WebRTC voice under the hood:
123
+
124
+ .. code:: py
125
+
126
+ vc = await channel.connect()
127
+ vc.play(lolka.FFmpegPCMAudio("song.mp3"))
128
+
129
+ # receive other participants' audio (optional):
130
+ async def on_track(track, user_id, producer_id):
131
+ ... # track is an aiortc MediaStreamTrack
132
+ vc.on_receive_track = on_track
133
+
134
+ ...
135
+ await vc.disconnect()
136
+
137
+ The track passed to ``on_receive_track`` only delivers frames from the moment it was handed over and
138
+ keeps just the latest one, so read it (``await track.recv()`` in a loop until ``MediaStreamError``)
139
+ or call ``track.stop()`` if you do not need it. Only audio producers are consumed (video is ignored).
140
+
141
+ ``after`` callbacks of ``vc.play()`` run in a helper thread, like in pycord, so they may block or call
142
+ ``vc.play()`` again; use ``asyncio.run_coroutine_threadsafe(coro, vc.loop)`` to run a coroutine from them.
143
+ Unlike in pycord, ``after`` is called after ``source.cleanup()`` (not before); if the source's ``read()``
144
+ hangs, ``after`` is called after 2 seconds, before ``cleanup()``, which runs once ``read()`` returns.
145
+ ``vc.stop_recording()`` finalizes the sink asynchronously: the recording callback arrives after the call
146
+ returns. A new ``start_recording`` right after ``stop_recording()`` works when called from the event loop;
147
+ from another thread the finalization is scheduled through the loop, and until it runs ``start_recording``
148
+ raises ``ClientException``.
149
+
150
+ If the voice connection is lost (the voice server restarted, the network dropped), the client disconnects
151
+ and leaves the channel; ``reconnect=True`` is accepted for compatibility but reconnecting is up to the bot.
152
+
153
+ Recording works through the usual sinks. Every participant's incoming audio is written to the sink as
154
+ 48 kHz 16-bit stereo PCM under the participant's user ID. Only audio received after
155
+ ``start_recording()`` is written, and no silence is inserted between talking: the tracks of different
156
+ users are not time-aligned. Both pycord callback contracts are supported. With extra arguments (or an
157
+ ``async def`` callback) it is the pycord 2.0 - 2.6 style, ``callback(sink, *args)``:
158
+
159
+ .. code:: py
160
+
161
+ async def finished(sink, channel):
162
+ files = [lolka.File(audio.file, f"{user_id}.wav") for user_id, audio in sink.audio_data.items()]
163
+ await channel.send("Done recording!", files=files)
164
+
165
+ vc = await channel.connect()
166
+ vc.start_recording(lolka.sinks.WaveSink(), finished, text_channel)
167
+ ...
168
+ vc.stop_recording()
169
+
170
+ Without extra arguments and with a regular function it is the pycord 2.7+ style, ``callback(error)``,
171
+ where ``error`` is the first exception raised while recording or finishing the sink (or ``None``);
172
+ keep a reference to the sink yourself:
173
+
174
+ .. code:: py
175
+
176
+ sink = lolka.sinks.WaveSink()
177
+
178
+ def finished(error):
179
+ if error is None:
180
+ print(len(sink.audio_data), "users recorded")
181
+
182
+ vc.start_recording(sink, finished)
183
+ ...
184
+ vc.stop_recording()
185
+
186
+ The sink is finalized (e.g. mp3/ogg conversion through ffmpeg) in a worker thread, so the bot stays responsive.
187
+
188
+ Recording and ``on_receive_track`` can be used together. Raw UDP helpers (``send_audio_packet``) are not
189
+ available over WebRTC — use ``vc.play()`` with an audio source.
190
+
191
+ Migrating from pycord
192
+ ---------------------
193
+
194
+ Already have a pycord bot? You don't have to rewrite it — just alias the import:
195
+
196
+ .. code:: py
197
+
198
+ import lolka as discord
199
+ from lolka.ext import commands
200
+
201
+ # everything below is unmodified pycord bot code
202
+ bot = commands.Bot(command_prefix=">", intents=discord.Intents.default())
203
+
204
+ @bot.slash_command()
205
+ async def ping(ctx):
206
+ await ctx.respond("pong")
207
+
208
+ bot.run("token")
209
+
210
+ ``import lolka as discord`` covers every ``discord.Whatever`` attribute access in your existing code
211
+ (``discord.Bot``, ``discord.Intents``, ``discord.Embed``, ``discord.option``, ``discord.sinks``,
212
+ ``discord.ui`` and so on). The only lines that actually need editing are explicit submodule imports,
213
+ since Python resolves those by real module path rather than by the alias:
214
+
215
+ - ``import discord`` → ``import lolka as discord``
216
+ - ``from discord import X`` → ``from lolka import X``
217
+ - ``from discord import option`` → ``from lolka import option``
218
+ - ``from discord.ext import commands`` → ``from lolka.ext import commands`` (same for ``bridge``, ``pages``, ``tasks``)
219
+ - ``from discord.commands import ...`` → ``from lolka.commands import ...``
220
+ - ``from discord.ui import ...`` → ``from lolka.ui import ...``
221
+ - in general, ``from discord.<sub> import …`` → ``from lolka.<sub> import …`` for any submodule (``sinks``, ``voice``, ``commands``, ``ext.*``, ``ui``, …)
222
+
223
+ That's it — the rest of your bot's code stays exactly as it is.
@@ -0,0 +1,176 @@
1
+ pylolka
2
+ =======
3
+
4
+ **Fork of** `pycord <https://github.com/Pycord-Development/pycord>`_ **(MIT License, © 2015-2021 Rapptz, © 2021-present Pycord Development).**
5
+
6
+ ``pylolka`` (imported as ``import lolka``) is a Python wrapper for the **lolka** bot API, built on
7
+ py-cord 2.8.1. It targets lolka by default — no manual REST/Gateway overrides needed — decodes lolka
8
+ snowflakes, and resolves lolka CDN asset URLs. Slash commands, cogs, UI components, ``lolka.ext.commands``,
9
+ ``lolka.ext.bridge``, ``lolka.ext.pages`` and ``lolka.ext.tasks`` keep the py-cord API. See ``LICENSE`` for
10
+ licensing (the original MIT copyrights are retained).
11
+
12
+ Installing
13
+ ----------
14
+
15
+ **Python 3.10 or higher is required**
16
+
17
+ .. code:: sh
18
+
19
+ # Linux/macOS
20
+ python3 -m pip install -U pylolka
21
+
22
+ # Windows
23
+ py -3 -m pip install -U pylolka
24
+
25
+ Quick Example
26
+ -------------
27
+
28
+ .. code:: py
29
+
30
+ import lolka
31
+
32
+ bot = lolka.Bot()
33
+
34
+ @bot.slash_command()
35
+ async def ping(ctx):
36
+ await ctx.respond("pong")
37
+
38
+ bot.run("token")
39
+
40
+ Bot Example
41
+ ~~~~~~~~~~~
42
+
43
+ .. code:: py
44
+
45
+ import lolka
46
+ from lolka.ext import commands
47
+
48
+ intents = lolka.Intents.default()
49
+ intents.message_content = True
50
+ bot = commands.Bot(command_prefix=">", intents=intents)
51
+
52
+ @bot.command()
53
+ async def ping(ctx):
54
+ await ctx.send("pong")
55
+
56
+ bot.run("token")
57
+
58
+ Configuration
59
+ -------------
60
+
61
+ The defaults point to lolka. They are read from the environment when ``lolka`` is imported,
62
+ so set them before ``import lolka``:
63
+
64
+ - ``LOLKA_API_BASE`` — REST API base URL (default ``https://lolka.app/api/bot``)
65
+ - ``LOLKA_GATEWAY`` — Gateway URL (default ``wss://lolka.app/ws/bot``)
66
+ - ``LOLKA_CDN`` — CDN base URL for asset links (default ``https://cdn.lolka.app``)
67
+
68
+ Voice
69
+ -----
70
+
71
+ Voice works over WebRTC (lolka's voice stack), not Discord's UDP/PyNaCl/DAVE transport.
72
+ The required dependencies (``aiortc``, ``pymediasoup``) ship with the base install — nothing extra to add.
73
+
74
+ The API stays py-cord-compatible — ``await channel.connect()`` returns a ``VoiceClient`` that speaks
75
+ lolka's WebRTC voice under the hood:
76
+
77
+ .. code:: py
78
+
79
+ vc = await channel.connect()
80
+ vc.play(lolka.FFmpegPCMAudio("song.mp3"))
81
+
82
+ # receive other participants' audio (optional):
83
+ async def on_track(track, user_id, producer_id):
84
+ ... # track is an aiortc MediaStreamTrack
85
+ vc.on_receive_track = on_track
86
+
87
+ ...
88
+ await vc.disconnect()
89
+
90
+ The track passed to ``on_receive_track`` only delivers frames from the moment it was handed over and
91
+ keeps just the latest one, so read it (``await track.recv()`` in a loop until ``MediaStreamError``)
92
+ or call ``track.stop()`` if you do not need it. Only audio producers are consumed (video is ignored).
93
+
94
+ ``after`` callbacks of ``vc.play()`` run in a helper thread, like in pycord, so they may block or call
95
+ ``vc.play()`` again; use ``asyncio.run_coroutine_threadsafe(coro, vc.loop)`` to run a coroutine from them.
96
+ Unlike in pycord, ``after`` is called after ``source.cleanup()`` (not before); if the source's ``read()``
97
+ hangs, ``after`` is called after 2 seconds, before ``cleanup()``, which runs once ``read()`` returns.
98
+ ``vc.stop_recording()`` finalizes the sink asynchronously: the recording callback arrives after the call
99
+ returns. A new ``start_recording`` right after ``stop_recording()`` works when called from the event loop;
100
+ from another thread the finalization is scheduled through the loop, and until it runs ``start_recording``
101
+ raises ``ClientException``.
102
+
103
+ If the voice connection is lost (the voice server restarted, the network dropped), the client disconnects
104
+ and leaves the channel; ``reconnect=True`` is accepted for compatibility but reconnecting is up to the bot.
105
+
106
+ Recording works through the usual sinks. Every participant's incoming audio is written to the sink as
107
+ 48 kHz 16-bit stereo PCM under the participant's user ID. Only audio received after
108
+ ``start_recording()`` is written, and no silence is inserted between talking: the tracks of different
109
+ users are not time-aligned. Both pycord callback contracts are supported. With extra arguments (or an
110
+ ``async def`` callback) it is the pycord 2.0 - 2.6 style, ``callback(sink, *args)``:
111
+
112
+ .. code:: py
113
+
114
+ async def finished(sink, channel):
115
+ files = [lolka.File(audio.file, f"{user_id}.wav") for user_id, audio in sink.audio_data.items()]
116
+ await channel.send("Done recording!", files=files)
117
+
118
+ vc = await channel.connect()
119
+ vc.start_recording(lolka.sinks.WaveSink(), finished, text_channel)
120
+ ...
121
+ vc.stop_recording()
122
+
123
+ Without extra arguments and with a regular function it is the pycord 2.7+ style, ``callback(error)``,
124
+ where ``error`` is the first exception raised while recording or finishing the sink (or ``None``);
125
+ keep a reference to the sink yourself:
126
+
127
+ .. code:: py
128
+
129
+ sink = lolka.sinks.WaveSink()
130
+
131
+ def finished(error):
132
+ if error is None:
133
+ print(len(sink.audio_data), "users recorded")
134
+
135
+ vc.start_recording(sink, finished)
136
+ ...
137
+ vc.stop_recording()
138
+
139
+ The sink is finalized (e.g. mp3/ogg conversion through ffmpeg) in a worker thread, so the bot stays responsive.
140
+
141
+ Recording and ``on_receive_track`` can be used together. Raw UDP helpers (``send_audio_packet``) are not
142
+ available over WebRTC — use ``vc.play()`` with an audio source.
143
+
144
+ Migrating from pycord
145
+ ---------------------
146
+
147
+ Already have a pycord bot? You don't have to rewrite it — just alias the import:
148
+
149
+ .. code:: py
150
+
151
+ import lolka as discord
152
+ from lolka.ext import commands
153
+
154
+ # everything below is unmodified pycord bot code
155
+ bot = commands.Bot(command_prefix=">", intents=discord.Intents.default())
156
+
157
+ @bot.slash_command()
158
+ async def ping(ctx):
159
+ await ctx.respond("pong")
160
+
161
+ bot.run("token")
162
+
163
+ ``import lolka as discord`` covers every ``discord.Whatever`` attribute access in your existing code
164
+ (``discord.Bot``, ``discord.Intents``, ``discord.Embed``, ``discord.option``, ``discord.sinks``,
165
+ ``discord.ui`` and so on). The only lines that actually need editing are explicit submodule imports,
166
+ since Python resolves those by real module path rather than by the alias:
167
+
168
+ - ``import discord`` → ``import lolka as discord``
169
+ - ``from discord import X`` → ``from lolka import X``
170
+ - ``from discord import option`` → ``from lolka import option``
171
+ - ``from discord.ext import commands`` → ``from lolka.ext import commands`` (same for ``bridge``, ``pages``, ``tasks``)
172
+ - ``from discord.commands import ...`` → ``from lolka.commands import ...``
173
+ - ``from discord.ui import ...`` → ``from lolka.ui import ...``
174
+ - in general, ``from discord.<sub> import …`` → ``from lolka.<sub> import …`` for any submodule (``sinks``, ``voice``, ``commands``, ``ext.*``, ``ui``, …)
175
+
176
+ That's it — the rest of your bot's code stays exactly as it is.
@@ -0,0 +1,124 @@
1
+ """
2
+ lolka API Wrapper
3
+ ~~~~~~~~~~~~~~~~~
4
+
5
+ A wrapper for the lolka bot API — a fork of py-cord that talks to lolka by
6
+ default (REST/Gateway) and keeps the py-cord public API.
7
+
8
+ :copyright: (c) 2015-2021 Rapptz & (c) 2021-present Pycord Development; lolka fork
9
+ :license: MIT, see LICENSE for more details.
10
+ """
11
+
12
+ __title__ = "lolka"
13
+ __author__ = "lolka"
14
+ __license__ = "MIT"
15
+ __copyright__ = "Copyright 2015-2021 Rapptz, 2021-present Pycord Development; lolka fork"
16
+
17
+ __path__ = __import__("pkgutil").extend_path(__path__, __name__)
18
+
19
+ import logging
20
+ from typing import TYPE_CHECKING
21
+
22
+ # We need __version__ to be imported first
23
+ # isort: off
24
+ from ._version import *
25
+
26
+ # isort: on
27
+
28
+
29
+ from . import abc, opus, sinks, ui, utils
30
+ from .activity import *
31
+ from .appinfo import *
32
+ from .application_role_connection import *
33
+ from .asset import *
34
+ from .audit_logs import *
35
+ from .automod import *
36
+ from .bot import *
37
+ from .channel import *
38
+ from .client import *
39
+ from .cog import *
40
+ from .collectibles import *
41
+ from .colour import *
42
+ from .commands import *
43
+ from .components import *
44
+ from .embeds import *
45
+ from .emoji import *
46
+ from .enums import *
47
+ from .errors import *
48
+ from .file import *
49
+ from .flags import *
50
+ from .guild import *
51
+ from .http import *
52
+ from .incidents import *
53
+ from .integrations import *
54
+ from .interactions import *
55
+ from .invite import *
56
+ from .member import *
57
+ from .mentions import *
58
+ from .message import *
59
+ from .monetization import *
60
+ from .object import *
61
+ from .onboarding import *
62
+ from .partial_emoji import *
63
+ from .permissions import *
64
+ from .player import *
65
+ from .poll import *
66
+ from .primary_guild import *
67
+ from .raw_models import *
68
+ from .reaction import *
69
+ from .role import *
70
+ from .scheduled_events import *
71
+ from .shard import *
72
+ from .soundboard import *
73
+ from .stage_instance import *
74
+ from .sticker import *
75
+ from .team import *
76
+ from .template import *
77
+ from .threads import *
78
+ from .user import *
79
+ from .webhook import *
80
+ from .welcome_screen import *
81
+ from .widget import *
82
+
83
+ if TYPE_CHECKING:
84
+ from typing import Generic, TypeVar
85
+
86
+ from typing_extensions import deprecated
87
+
88
+ from lolka.voice import VoiceClient as VoiceClientC
89
+ from lolka.voice import VoiceProtocol as VoiceProtocolC
90
+
91
+ C = TypeVar("C", bound=Client)
92
+
93
+ @deprecated(
94
+ "lolka.VoiceClient is deprecated in favour of lolka.voice.VoiceClient since 2.7 and will be removed in 3.0",
95
+ )
96
+ class VoiceClient(VoiceClientC): ...
97
+
98
+ @deprecated(
99
+ "lolka.VoiceProtocol is deprecated in favour of lolka.voice.VoiceProtocol since 2.7 and will be removed in 3.0",
100
+ )
101
+ class VoiceProtocol(VoiceProtocolC[C], Generic[C]): ...
102
+
103
+ else:
104
+ from .utils import warn_deprecated
105
+
106
+ def __getattr__(name: str) -> object:
107
+ if name == "VoiceClient":
108
+ warn_deprecated(
109
+ "lolka.VoiceClient", "lolka.voice.VoiceClient", "2.7", "3.0"
110
+ )
111
+ from .voice import VoiceClient
112
+
113
+ return VoiceClient
114
+ if name == "VoiceProtocol":
115
+ warn_deprecated(
116
+ "lolka.VoiceProtocol", "lolka.voice.VoiceProtocol", "2.7", "3.0"
117
+ )
118
+ from .voice import VoiceProtocol
119
+
120
+ return VoiceProtocol
121
+ raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
122
+
123
+
124
+ logging.getLogger(__name__).addHandler(logging.NullHandler())