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.
- pylolka-0.1.0/LICENSE +22 -0
- pylolka-0.1.0/MANIFEST.in +19 -0
- pylolka-0.1.0/PKG-INFO +223 -0
- pylolka-0.1.0/README.rst +176 -0
- pylolka-0.1.0/lolka/__init__.py +124 -0
- pylolka-0.1.0/lolka/__main__.py +380 -0
- pylolka-0.1.0/lolka/_version.py +105 -0
- pylolka-0.1.0/lolka/abc.py +2104 -0
- pylolka-0.1.0/lolka/activity.py +881 -0
- pylolka-0.1.0/lolka/appinfo.py +650 -0
- pylolka-0.1.0/lolka/application_role_connection.py +128 -0
- pylolka-0.1.0/lolka/asset.py +557 -0
- pylolka-0.1.0/lolka/audit_logs.py +719 -0
- pylolka-0.1.0/lolka/automod.py +560 -0
- pylolka-0.1.0/lolka/backoff.py +101 -0
- pylolka-0.1.0/lolka/bin/libopus-0.x64.dll +0 -0
- pylolka-0.1.0/lolka/bin/libopus-0.x86.dll +0 -0
- pylolka-0.1.0/lolka/bot.py +1686 -0
- pylolka-0.1.0/lolka/channel.py +3649 -0
- pylolka-0.1.0/lolka/client.py +2387 -0
- pylolka-0.1.0/lolka/cog.py +1168 -0
- pylolka-0.1.0/lolka/collectibles.py +136 -0
- pylolka-0.1.0/lolka/colour.py +411 -0
- pylolka-0.1.0/lolka/commands/__init__.py +29 -0
- pylolka-0.1.0/lolka/commands/context.py +476 -0
- pylolka-0.1.0/lolka/commands/core.py +2295 -0
- pylolka-0.1.0/lolka/commands/options.py +557 -0
- pylolka-0.1.0/lolka/commands/permissions.py +139 -0
- pylolka-0.1.0/lolka/components.py +1823 -0
- pylolka-0.1.0/lolka/context_managers.py +90 -0
- pylolka-0.1.0/lolka/embeds.py +1079 -0
- pylolka-0.1.0/lolka/emoji.py +435 -0
- pylolka-0.1.0/lolka/emojis.json +1 -0
- pylolka-0.1.0/lolka/enums.py +1233 -0
- pylolka-0.1.0/lolka/errors.py +434 -0
- pylolka-0.1.0/lolka/ext/bridge/__init__.py +28 -0
- pylolka-0.1.0/lolka/ext/bridge/bot.py +204 -0
- pylolka-0.1.0/lolka/ext/bridge/context.py +203 -0
- pylolka-0.1.0/lolka/ext/bridge/core.py +689 -0
- pylolka-0.1.0/lolka/ext/commands/__init__.py +19 -0
- pylolka-0.1.0/lolka/ext/commands/_types.py +49 -0
- pylolka-0.1.0/lolka/ext/commands/bot.py +457 -0
- pylolka-0.1.0/lolka/ext/commands/cog.py +85 -0
- pylolka-0.1.0/lolka/ext/commands/context.py +411 -0
- pylolka-0.1.0/lolka/ext/commands/converter.py +1269 -0
- pylolka-0.1.0/lolka/ext/commands/cooldowns.py +409 -0
- pylolka-0.1.0/lolka/ext/commands/core.py +2501 -0
- pylolka-0.1.0/lolka/ext/commands/errors.py +1022 -0
- pylolka-0.1.0/lolka/ext/commands/flags.py +700 -0
- pylolka-0.1.0/lolka/ext/commands/help.py +1412 -0
- pylolka-0.1.0/lolka/ext/commands/view.py +200 -0
- pylolka-0.1.0/lolka/ext/pages/__init__.py +10 -0
- pylolka-0.1.0/lolka/ext/pages/pagination.py +1340 -0
- pylolka-0.1.0/lolka/ext/tasks/__init__.py +858 -0
- pylolka-0.1.0/lolka/file.py +206 -0
- pylolka-0.1.0/lolka/flags.py +1840 -0
- pylolka-0.1.0/lolka/gateway.py +800 -0
- pylolka-0.1.0/lolka/guild.py +4723 -0
- pylolka-0.1.0/lolka/http.py +3396 -0
- pylolka-0.1.0/lolka/incidents.py +87 -0
- pylolka-0.1.0/lolka/integrations.py +374 -0
- pylolka-0.1.0/lolka/interactions.py +1944 -0
- pylolka-0.1.0/lolka/invite.py +818 -0
- pylolka-0.1.0/lolka/iterators.py +1303 -0
- pylolka-0.1.0/lolka/member.py +1312 -0
- pylolka-0.1.0/lolka/mentions.py +158 -0
- pylolka-0.1.0/lolka/message.py +2623 -0
- pylolka-0.1.0/lolka/mixins.py +48 -0
- pylolka-0.1.0/lolka/monetization.py +350 -0
- pylolka-0.1.0/lolka/object.py +117 -0
- pylolka-0.1.0/lolka/oggparse.py +122 -0
- pylolka-0.1.0/lolka/onboarding.py +483 -0
- pylolka-0.1.0/lolka/opus.py +733 -0
- pylolka-0.1.0/lolka/partial_emoji.py +265 -0
- pylolka-0.1.0/lolka/permissions.py +900 -0
- pylolka-0.1.0/lolka/player.py +944 -0
- pylolka-0.1.0/lolka/poll.py +529 -0
- pylolka-0.1.0/lolka/primary_guild.py +98 -0
- pylolka-0.1.0/lolka/py.typed +0 -0
- pylolka-0.1.0/lolka/raw_models.py +1032 -0
- pylolka-0.1.0/lolka/reaction.py +296 -0
- pylolka-0.1.0/lolka/role.py +935 -0
- pylolka-0.1.0/lolka/scheduled_events.py +578 -0
- pylolka-0.1.0/lolka/shard.py +586 -0
- pylolka-0.1.0/lolka/sinks/__init__.py +20 -0
- pylolka-0.1.0/lolka/sinks/core.py +250 -0
- pylolka-0.1.0/lolka/sinks/errors.py +89 -0
- pylolka-0.1.0/lolka/sinks/m4a.py +103 -0
- pylolka-0.1.0/lolka/sinks/mka.py +96 -0
- pylolka-0.1.0/lolka/sinks/mkv.py +95 -0
- pylolka-0.1.0/lolka/sinks/mp3.py +96 -0
- pylolka-0.1.0/lolka/sinks/mp4.py +103 -0
- pylolka-0.1.0/lolka/sinks/ogg.py +96 -0
- pylolka-0.1.0/lolka/sinks/pcm.py +45 -0
- pylolka-0.1.0/lolka/sinks/wave.py +74 -0
- pylolka-0.1.0/lolka/soundboard.py +269 -0
- pylolka-0.1.0/lolka/stage_instance.py +199 -0
- pylolka-0.1.0/lolka/state.py +2291 -0
- pylolka-0.1.0/lolka/sticker.py +554 -0
- pylolka-0.1.0/lolka/team.py +180 -0
- pylolka-0.1.0/lolka/template.py +280 -0
- pylolka-0.1.0/lolka/threads.py +939 -0
- pylolka-0.1.0/lolka/types/__init__.py +9 -0
- pylolka-0.1.0/lolka/types/activity.py +111 -0
- pylolka-0.1.0/lolka/types/appinfo.py +95 -0
- pylolka-0.1.0/lolka/types/application_role_connection.py +40 -0
- pylolka-0.1.0/lolka/types/audit_log.py +296 -0
- pylolka-0.1.0/lolka/types/automod.py +91 -0
- pylolka-0.1.0/lolka/types/channel.py +196 -0
- pylolka-0.1.0/lolka/types/collectibles.py +45 -0
- pylolka-0.1.0/lolka/types/components.py +256 -0
- pylolka-0.1.0/lolka/types/embed.py +103 -0
- pylolka-0.1.0/lolka/types/emoji.py +50 -0
- pylolka-0.1.0/lolka/types/gateway.py +42 -0
- pylolka-0.1.0/lolka/types/guild.py +212 -0
- pylolka-0.1.0/lolka/types/integration.py +83 -0
- pylolka-0.1.0/lolka/types/interactions.py +296 -0
- pylolka-0.1.0/lolka/types/invite.py +106 -0
- pylolka-0.1.0/lolka/types/member.py +92 -0
- pylolka-0.1.0/lolka/types/message.py +196 -0
- pylolka-0.1.0/lolka/types/monetization.py +78 -0
- pylolka-0.1.0/lolka/types/onboarding.py +65 -0
- pylolka-0.1.0/lolka/types/poll.py +64 -0
- pylolka-0.1.0/lolka/types/primary_guild.py +36 -0
- pylolka-0.1.0/lolka/types/raw_models.py +167 -0
- pylolka-0.1.0/lolka/types/role.py +62 -0
- pylolka-0.1.0/lolka/types/scheduled_events.py +65 -0
- pylolka-0.1.0/lolka/types/snowflake.py +29 -0
- pylolka-0.1.0/lolka/types/soundboard.py +42 -0
- pylolka-0.1.0/lolka/types/sticker.py +91 -0
- pylolka-0.1.0/lolka/types/team.py +46 -0
- pylolka-0.1.0/lolka/types/template.py +51 -0
- pylolka-0.1.0/lolka/types/threads.py +76 -0
- pylolka-0.1.0/lolka/types/user.py +57 -0
- pylolka-0.1.0/lolka/types/voice.py +89 -0
- pylolka-0.1.0/lolka/types/webhook.py +65 -0
- pylolka-0.1.0/lolka/types/welcome_screen.py +42 -0
- pylolka-0.1.0/lolka/types/widget.py +64 -0
- pylolka-0.1.0/lolka/ui/__init__.py +30 -0
- pylolka-0.1.0/lolka/ui/action_row.py +436 -0
- pylolka-0.1.0/lolka/ui/button.py +419 -0
- pylolka-0.1.0/lolka/ui/checkbox.py +137 -0
- pylolka-0.1.0/lolka/ui/checkbox_group.py +286 -0
- pylolka-0.1.0/lolka/ui/container.py +442 -0
- pylolka-0.1.0/lolka/ui/core.py +157 -0
- pylolka-0.1.0/lolka/ui/file.py +150 -0
- pylolka-0.1.0/lolka/ui/file_upload.py +199 -0
- pylolka-0.1.0/lolka/ui/input_text.py +299 -0
- pylolka-0.1.0/lolka/ui/item.py +269 -0
- pylolka-0.1.0/lolka/ui/label.py +566 -0
- pylolka-0.1.0/lolka/ui/media_gallery.py +179 -0
- pylolka-0.1.0/lolka/ui/modal.py +527 -0
- pylolka-0.1.0/lolka/ui/radio_group.py +236 -0
- pylolka-0.1.0/lolka/ui/section.py +358 -0
- pylolka-0.1.0/lolka/ui/select.py +1181 -0
- pylolka-0.1.0/lolka/ui/separator.py +122 -0
- pylolka-0.1.0/lolka/ui/text_display.py +110 -0
- pylolka-0.1.0/lolka/ui/thumbnail.py +153 -0
- pylolka-0.1.0/lolka/ui/view.py +1050 -0
- pylolka-0.1.0/lolka/user.py +747 -0
- pylolka-0.1.0/lolka/utils.py +1715 -0
- pylolka-0.1.0/lolka/voice/__init__.py +13 -0
- pylolka-0.1.0/lolka/voice/_types.py +166 -0
- pylolka-0.1.0/lolka/voice/_voice_impl.py +859 -0
- pylolka-0.1.0/lolka/voice/client.py +1034 -0
- pylolka-0.1.0/lolka/voice/enums.py +79 -0
- pylolka-0.1.0/lolka/voice/gateway.py +521 -0
- pylolka-0.1.0/lolka/voice/packets/__init__.py +63 -0
- pylolka-0.1.0/lolka/voice/packets/core.py +93 -0
- pylolka-0.1.0/lolka/voice/packets/rtp.py +320 -0
- pylolka-0.1.0/lolka/voice/receive/__init__.py +33 -0
- pylolka-0.1.0/lolka/voice/receive/reader.py +577 -0
- pylolka-0.1.0/lolka/voice/receive/router.py +231 -0
- pylolka-0.1.0/lolka/voice/state.py +983 -0
- pylolka-0.1.0/lolka/voice/utils/__init__.py +0 -0
- pylolka-0.1.0/lolka/voice/utils/buffer.py +215 -0
- pylolka-0.1.0/lolka/voice/utils/dependencies.py +40 -0
- pylolka-0.1.0/lolka/voice/utils/multidataevent.py +79 -0
- pylolka-0.1.0/lolka/voice/utils/wrapped.py +32 -0
- pylolka-0.1.0/lolka/webhook/__init__.py +12 -0
- pylolka-0.1.0/lolka/webhook/async_.py +2213 -0
- pylolka-0.1.0/lolka/webhook/sync.py +1320 -0
- pylolka-0.1.0/lolka/welcome_screen.py +234 -0
- pylolka-0.1.0/lolka/widget.py +348 -0
- pylolka-0.1.0/pylolka.egg-info/PKG-INFO +223 -0
- pylolka-0.1.0/pylolka.egg-info/SOURCES.txt +194 -0
- pylolka-0.1.0/pylolka.egg-info/dependency_links.txt +1 -0
- pylolka-0.1.0/pylolka.egg-info/requires.txt +25 -0
- pylolka-0.1.0/pylolka.egg-info/top_level.txt +1 -0
- pylolka-0.1.0/pyproject.toml +142 -0
- pylolka-0.1.0/requirements/_.txt +4 -0
- pylolka-0.1.0/requirements/docs.txt +11 -0
- pylolka-0.1.0/requirements/speed.txt +2 -0
- pylolka-0.1.0/requirements/voice.txt +2 -0
- pylolka-0.1.0/setup.cfg +4 -0
- 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.
|
pylolka-0.1.0/README.rst
ADDED
|
@@ -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())
|