sonolink 0.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- sonolink-0.0.0/LICENSE +21 -0
- sonolink-0.0.0/PKG-INFO +107 -0
- sonolink-0.0.0/README.md +69 -0
- sonolink-0.0.0/pyproject.toml +87 -0
- sonolink-0.0.0/setup.cfg +4 -0
- sonolink-0.0.0/sonolink/__init__.py +50 -0
- sonolink-0.0.0/sonolink/_registry.py +36 -0
- sonolink-0.0.0/sonolink/_version.py +48 -0
- sonolink-0.0.0/sonolink/errors.py +31 -0
- sonolink-0.0.0/sonolink/gateway/__init__.py +38 -0
- sonolink-0.0.0/sonolink/gateway/cache.py +120 -0
- sonolink-0.0.0/sonolink/gateway/client/__init__.py +411 -0
- sonolink-0.0.0/sonolink/gateway/client/_base.py +23 -0
- sonolink-0.0.0/sonolink/gateway/client/_factory.py +48 -0
- sonolink-0.0.0/sonolink/gateway/client/adapters/__init__.py +11 -0
- sonolink-0.0.0/sonolink/gateway/client/adapters/_disnake.py +55 -0
- sonolink-0.0.0/sonolink/gateway/client/adapters/_dpy.py +55 -0
- sonolink-0.0.0/sonolink/gateway/client/adapters/_pycord.py +55 -0
- sonolink-0.0.0/sonolink/gateway/enums.py +150 -0
- sonolink-0.0.0/sonolink/gateway/errors.py +72 -0
- sonolink-0.0.0/sonolink/gateway/event_models.py +234 -0
- sonolink-0.0.0/sonolink/gateway/node.py +790 -0
- sonolink-0.0.0/sonolink/gateway/player/__init__.py +191 -0
- sonolink-0.0.0/sonolink/gateway/player/_base.py +746 -0
- sonolink-0.0.0/sonolink/gateway/player/_factory.py +130 -0
- sonolink-0.0.0/sonolink/gateway/player/adapters/__init__.py +11 -0
- sonolink-0.0.0/sonolink/gateway/player/adapters/_disnake.py +228 -0
- sonolink-0.0.0/sonolink/gateway/player/adapters/_dpy.py +227 -0
- sonolink-0.0.0/sonolink/gateway/player/adapters/_pycord.py +207 -0
- sonolink-0.0.0/sonolink/gateway/player/handlers/__init__.py +16 -0
- sonolink-0.0.0/sonolink/gateway/player/handlers/_autoplay.py +127 -0
- sonolink-0.0.0/sonolink/gateway/player/handlers/_base.py +44 -0
- sonolink-0.0.0/sonolink/gateway/player/handlers/_events.py +231 -0
- sonolink-0.0.0/sonolink/gateway/player/handlers/_incativity.py +121 -0
- sonolink-0.0.0/sonolink/gateway/player/handlers/_lifecycle.py +170 -0
- sonolink-0.0.0/sonolink/gateway/player/handlers/_playback.py +224 -0
- sonolink-0.0.0/sonolink/gateway/queue/__init__.py +17 -0
- sonolink-0.0.0/sonolink/gateway/queue/base.py +240 -0
- sonolink-0.0.0/sonolink/gateway/queue/history.py +61 -0
- sonolink-0.0.0/sonolink/gateway/queue/queue.py +461 -0
- sonolink-0.0.0/sonolink/gateway/schemas/__init__.py +12 -0
- sonolink-0.0.0/sonolink/gateway/schemas/events.py +86 -0
- sonolink-0.0.0/sonolink/gateway/schemas/receive.py +149 -0
- sonolink-0.0.0/sonolink/models/__init__.py +17 -0
- sonolink-0.0.0/sonolink/models/base.py +207 -0
- sonolink-0.0.0/sonolink/models/filters.py +800 -0
- sonolink-0.0.0/sonolink/models/info.py +180 -0
- sonolink-0.0.0/sonolink/models/player_info.py +119 -0
- sonolink-0.0.0/sonolink/models/playlist.py +117 -0
- sonolink-0.0.0/sonolink/models/responses.py +110 -0
- sonolink-0.0.0/sonolink/models/settings.py +165 -0
- sonolink-0.0.0/sonolink/models/track.py +218 -0
- sonolink-0.0.0/sonolink/network/__init__.py +93 -0
- sonolink-0.0.0/sonolink/network/_aiohttp.py +140 -0
- sonolink-0.0.0/sonolink/network/_curl_cffi.py +157 -0
- sonolink-0.0.0/sonolink/network/base.py +107 -0
- sonolink-0.0.0/sonolink/network/errors.py +65 -0
- sonolink-0.0.0/sonolink/network/message.py +67 -0
- sonolink-0.0.0/sonolink/rest/__init__.py +22 -0
- sonolink-0.0.0/sonolink/rest/enums.py +115 -0
- sonolink-0.0.0/sonolink/rest/errors.py +104 -0
- sonolink-0.0.0/sonolink/rest/http/__init__.py +118 -0
- sonolink-0.0.0/sonolink/rest/http/base.py +17 -0
- sonolink-0.0.0/sonolink/rest/http/info.py +31 -0
- sonolink-0.0.0/sonolink/rest/http/planner.py +40 -0
- sonolink-0.0.0/sonolink/rest/http/player.py +52 -0
- sonolink-0.0.0/sonolink/rest/http/session.py +26 -0
- sonolink-0.0.0/sonolink/rest/http/track.py +38 -0
- sonolink-0.0.0/sonolink/rest/schemas/__init__.py +64 -0
- sonolink-0.0.0/sonolink/rest/schemas/filters.py +279 -0
- sonolink-0.0.0/sonolink/rest/schemas/info.py +210 -0
- sonolink-0.0.0/sonolink/rest/schemas/planner.py +138 -0
- sonolink-0.0.0/sonolink/rest/schemas/player.py +166 -0
- sonolink-0.0.0/sonolink/rest/schemas/playlist.py +43 -0
- sonolink-0.0.0/sonolink/rest/schemas/session.py +51 -0
- sonolink-0.0.0/sonolink/rest/schemas/track.py +130 -0
- sonolink-0.0.0/sonolink/utils/__init__.py +12 -0
- sonolink-0.0.0/sonolink/utils/properties.py +99 -0
- sonolink-0.0.0/sonolink/utils/snowflake.py +16 -0
- sonolink-0.0.0/sonolink.egg-info/PKG-INFO +107 -0
- sonolink-0.0.0/sonolink.egg-info/SOURCES.txt +82 -0
- sonolink-0.0.0/sonolink.egg-info/dependency_links.txt +1 -0
- sonolink-0.0.0/sonolink.egg-info/requires.txt +13 -0
- sonolink-0.0.0/sonolink.egg-info/top_level.txt +1 -0
sonolink-0.0.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026-present SonoLink Development Team.
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
sonolink-0.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: sonolink
|
|
3
|
+
Version: 0.0.0
|
|
4
|
+
Summary: A high-performance Lavalink v4 wrapper for Python, inspired by WaveLink.
|
|
5
|
+
Author: vmphase, Soheab, DA-344 (aka Developer Anonymous)
|
|
6
|
+
Maintainer: vmphase, DA-344 (aka Developer Anonymous), Soheab
|
|
7
|
+
License: MIT
|
|
8
|
+
Project-URL: Repository, https://github.com/sonolink/sonolink
|
|
9
|
+
Keywords: lavalink,wavelink,fork,sonolink,discord.py,discord,music,audio,bot,library,python,asyncio,pycord,py-cord,disnake
|
|
10
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
11
|
+
Classifier: Framework :: AsyncIO
|
|
12
|
+
Classifier: Natural Language :: English
|
|
13
|
+
Classifier: Operating System :: OS Independent
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
17
|
+
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
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.12
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
License-File: LICENSE
|
|
26
|
+
Requires-Dist: aiohttp<4,>=3.11.0
|
|
27
|
+
Requires-Dist: msgspec<1,>=0.20.0
|
|
28
|
+
Requires-Dist: typing_extensions>=4.0.0
|
|
29
|
+
Requires-Dist: packaging<27.0,>=26.0
|
|
30
|
+
Provides-Extra: speed
|
|
31
|
+
Requires-Dist: curl-cffi<1,>=0.14.0; extra == "speed"
|
|
32
|
+
Provides-Extra: docs
|
|
33
|
+
Requires-Dist: sphinx>=9.1.0; extra == "docs"
|
|
34
|
+
Requires-Dist: furo; extra == "docs"
|
|
35
|
+
Requires-Dist: sphinx-copybutton; extra == "docs"
|
|
36
|
+
Requires-Dist: sphinx-autobuild>=2024.10.3; extra == "docs"
|
|
37
|
+
Dynamic: license-file
|
|
38
|
+
|
|
39
|
+
<div align="center">
|
|
40
|
+
|
|
41
|
+

|
|
42
|
+
|
|
43
|
+
**SonoLink** is a high-performance Lavalink v4 wrapper for Python, inspired by [WaveLink](https://github.com/PythonistaGuild/Wavelink).
|
|
44
|
+
|
|
45
|
+
[Documentation](https://sonolink.readthedocs.io/en/latest) · [Discord](https://discord.gg/tPHVWBPedt) · [Migration from WaveLink](https://sonolink.readthedocs.io/en/latest/guides/migrating-from-wavelink.html)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
[](https://pypi.org/project/sonolink)
|
|
50
|
+
[](https://www.python.org)
|
|
51
|
+
[](LICENSE)
|
|
52
|
+
[](https://lavalink.dev)
|
|
53
|
+
[](https://discord.gg/tPHVWBPedt)
|
|
54
|
+
|
|
55
|
+
</div>
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## Features
|
|
60
|
+
|
|
61
|
+
- Full Lavalink v4+ REST API support
|
|
62
|
+
- Built on [msgspec](https://github.com/jcrist/msgspec) for rapid serialization and strict type validation
|
|
63
|
+
- Optional [curl_cffi](https://github.com/lexiforest/curl_cffi) for faster networking
|
|
64
|
+
- Drop-in familiarity for Wavelink users — [migration guide included](https://sonolink.readthedocs.io/en/latest/guides/migrating-from-wavelink.html)
|
|
65
|
+
- Async-first and [Basedpyright](https://docs.basedpyright.com/latest/) strict-compliant
|
|
66
|
+
- Built-in support for [discord.py](https://github.com/Rapptz/discord.py), [pycord](https://github.com/Pycord-Development/pycord), and [disnake](https://github.com/DisnakeDev/disnake)
|
|
67
|
+
|
|
68
|
+
## Installation
|
|
69
|
+
|
|
70
|
+
> [!NOTE]
|
|
71
|
+
> A [virtual environment](https://docs.python.org/3/library/venv.html) is recommended, especially on Linux where the system Python may restrict package installations.
|
|
72
|
+
>
|
|
73
|
+
### Requirements:
|
|
74
|
+
- Python 3.12 or higher
|
|
75
|
+
- A running Lavalink 4.x server ([guide on setup](https://sonolink.readthedocs.io/en/latest/guides/lavalink-setup.html))
|
|
76
|
+
- Any of the supported libraries:
|
|
77
|
+
- [discord.py](https://pypi.org/project/discord.py)[voice] 2.7+
|
|
78
|
+
- [py-cord](https://pypi.org/project/py-cord)[voice] 2.8+
|
|
79
|
+
- [disnake](https://pypi.org/project/disnake)[voice] 2.12+
|
|
80
|
+
|
|
81
|
+
To install the stable version from PyPI:
|
|
82
|
+
```sh
|
|
83
|
+
# Linux/macOS
|
|
84
|
+
python3 -m pip install -U sonolink
|
|
85
|
+
|
|
86
|
+
# Windows
|
|
87
|
+
py -3 -m pip install -U sonolink
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
To install with optional speed improvements:
|
|
91
|
+
```sh
|
|
92
|
+
# Linux/macOS
|
|
93
|
+
python3 -m pip install -U "sonolink[speed]"
|
|
94
|
+
|
|
95
|
+
# Windows
|
|
96
|
+
py -3 -m pip install -U "sonolink[speed]"
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
<br>
|
|
100
|
+
|
|
101
|
+
<p align="center">
|
|
102
|
+
<img src="https://raw.githubusercontent.com/catppuccin/catppuccin/main/assets/footers/gray0_ctp_on_line.svg?sanitize=true" />
|
|
103
|
+
</p>
|
|
104
|
+
|
|
105
|
+
<p align="center">
|
|
106
|
+
<i><code>© 2026 <a href="https://github.com/sonolink">SonoLink Development Team</a></code></i>
|
|
107
|
+
</p>
|
sonolink-0.0.0/README.md
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+
|
|
5
|
+
**SonoLink** is a high-performance Lavalink v4 wrapper for Python, inspired by [WaveLink](https://github.com/PythonistaGuild/Wavelink).
|
|
6
|
+
|
|
7
|
+
[Documentation](https://sonolink.readthedocs.io/en/latest) · [Discord](https://discord.gg/tPHVWBPedt) · [Migration from WaveLink](https://sonolink.readthedocs.io/en/latest/guides/migrating-from-wavelink.html)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
[](https://pypi.org/project/sonolink)
|
|
12
|
+
[](https://www.python.org)
|
|
13
|
+
[](LICENSE)
|
|
14
|
+
[](https://lavalink.dev)
|
|
15
|
+
[](https://discord.gg/tPHVWBPedt)
|
|
16
|
+
|
|
17
|
+
</div>
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Features
|
|
22
|
+
|
|
23
|
+
- Full Lavalink v4+ REST API support
|
|
24
|
+
- Built on [msgspec](https://github.com/jcrist/msgspec) for rapid serialization and strict type validation
|
|
25
|
+
- Optional [curl_cffi](https://github.com/lexiforest/curl_cffi) for faster networking
|
|
26
|
+
- Drop-in familiarity for Wavelink users — [migration guide included](https://sonolink.readthedocs.io/en/latest/guides/migrating-from-wavelink.html)
|
|
27
|
+
- Async-first and [Basedpyright](https://docs.basedpyright.com/latest/) strict-compliant
|
|
28
|
+
- Built-in support for [discord.py](https://github.com/Rapptz/discord.py), [pycord](https://github.com/Pycord-Development/pycord), and [disnake](https://github.com/DisnakeDev/disnake)
|
|
29
|
+
|
|
30
|
+
## Installation
|
|
31
|
+
|
|
32
|
+
> [!NOTE]
|
|
33
|
+
> A [virtual environment](https://docs.python.org/3/library/venv.html) is recommended, especially on Linux where the system Python may restrict package installations.
|
|
34
|
+
>
|
|
35
|
+
### Requirements:
|
|
36
|
+
- Python 3.12 or higher
|
|
37
|
+
- A running Lavalink 4.x server ([guide on setup](https://sonolink.readthedocs.io/en/latest/guides/lavalink-setup.html))
|
|
38
|
+
- Any of the supported libraries:
|
|
39
|
+
- [discord.py](https://pypi.org/project/discord.py)[voice] 2.7+
|
|
40
|
+
- [py-cord](https://pypi.org/project/py-cord)[voice] 2.8+
|
|
41
|
+
- [disnake](https://pypi.org/project/disnake)[voice] 2.12+
|
|
42
|
+
|
|
43
|
+
To install the stable version from PyPI:
|
|
44
|
+
```sh
|
|
45
|
+
# Linux/macOS
|
|
46
|
+
python3 -m pip install -U sonolink
|
|
47
|
+
|
|
48
|
+
# Windows
|
|
49
|
+
py -3 -m pip install -U sonolink
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
To install with optional speed improvements:
|
|
53
|
+
```sh
|
|
54
|
+
# Linux/macOS
|
|
55
|
+
python3 -m pip install -U "sonolink[speed]"
|
|
56
|
+
|
|
57
|
+
# Windows
|
|
58
|
+
py -3 -m pip install -U "sonolink[speed]"
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
<br>
|
|
62
|
+
|
|
63
|
+
<p align="center">
|
|
64
|
+
<img src="https://raw.githubusercontent.com/catppuccin/catppuccin/main/assets/footers/gray0_ctp_on_line.svg?sanitize=true" />
|
|
65
|
+
</p>
|
|
66
|
+
|
|
67
|
+
<p align="center">
|
|
68
|
+
<i><code>© 2026 <a href="https://github.com/sonolink">SonoLink Development Team</a></code></i>
|
|
69
|
+
</p>
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=77.0.3"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
dynamic = ["version"]
|
|
7
|
+
name = "sonolink"
|
|
8
|
+
dependencies = [
|
|
9
|
+
"aiohttp>=3.11.0,<4",
|
|
10
|
+
"msgspec>=0.20.0,<1",
|
|
11
|
+
"typing_extensions>=4.0.0",
|
|
12
|
+
"packaging>=26.0,<27.0",
|
|
13
|
+
]
|
|
14
|
+
requires-python = ">=3.12"
|
|
15
|
+
authors = [
|
|
16
|
+
{ name = "vmphase" },
|
|
17
|
+
{ name = "Soheab" },
|
|
18
|
+
{ name = "DA-344 (aka Developer Anonymous)" },
|
|
19
|
+
]
|
|
20
|
+
maintainers = [
|
|
21
|
+
{ name = "vmphase" },
|
|
22
|
+
{ name = "DA-344 (aka Developer Anonymous)" },
|
|
23
|
+
{ name = "Soheab" },
|
|
24
|
+
]
|
|
25
|
+
description = "A high-performance Lavalink v4 wrapper for Python, inspired by WaveLink."
|
|
26
|
+
readme = "README.md"
|
|
27
|
+
license = { text = "MIT" }
|
|
28
|
+
keywords = [
|
|
29
|
+
"lavalink",
|
|
30
|
+
"wavelink",
|
|
31
|
+
"fork",
|
|
32
|
+
"sonolink",
|
|
33
|
+
"discord.py",
|
|
34
|
+
"discord",
|
|
35
|
+
"music",
|
|
36
|
+
"audio",
|
|
37
|
+
"bot",
|
|
38
|
+
"library",
|
|
39
|
+
"python",
|
|
40
|
+
"asyncio",
|
|
41
|
+
"pycord",
|
|
42
|
+
"py-cord",
|
|
43
|
+
"disnake",
|
|
44
|
+
]
|
|
45
|
+
classifiers = [
|
|
46
|
+
"Development Status :: 5 - Production/Stable",
|
|
47
|
+
"Framework :: AsyncIO",
|
|
48
|
+
"Natural Language :: English",
|
|
49
|
+
"Operating System :: OS Independent",
|
|
50
|
+
"Programming Language :: Python :: 3.12",
|
|
51
|
+
"Programming Language :: Python :: 3.13",
|
|
52
|
+
"Programming Language :: Python :: 3.14",
|
|
53
|
+
"Programming Language :: Python :: Implementation :: CPython",
|
|
54
|
+
"Topic :: Internet",
|
|
55
|
+
"Topic :: Software Development :: Libraries",
|
|
56
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
57
|
+
"Topic :: Utilities",
|
|
58
|
+
"Typing :: Typed",
|
|
59
|
+
]
|
|
60
|
+
|
|
61
|
+
[project.optional-dependencies]
|
|
62
|
+
speed = ["curl-cffi>=0.14.0,<1"]
|
|
63
|
+
docs = [
|
|
64
|
+
"sphinx>=9.1.0",
|
|
65
|
+
"furo",
|
|
66
|
+
"sphinx-copybutton",
|
|
67
|
+
"sphinx-autobuild>=2024.10.3",
|
|
68
|
+
]
|
|
69
|
+
|
|
70
|
+
[project.urls]
|
|
71
|
+
Repository = "https://github.com/sonolink/sonolink"
|
|
72
|
+
|
|
73
|
+
[tool.basedpyright]
|
|
74
|
+
pythonVersion = "3.12"
|
|
75
|
+
typeCheckingMode = "strict"
|
|
76
|
+
reportPrivateUsage = false
|
|
77
|
+
reportUnnecessaryComparison = false
|
|
78
|
+
exclude = ["docs/"]
|
|
79
|
+
|
|
80
|
+
[tool.ruff]
|
|
81
|
+
exclude = ["docs/"]
|
|
82
|
+
|
|
83
|
+
[tool.ruff.lint]
|
|
84
|
+
ignore = ["F405", "F403"]
|
|
85
|
+
|
|
86
|
+
[tool.setuptools.dynamic]
|
|
87
|
+
version = { attr = "sonolink._version.__version__" }
|
sonolink-0.0.0/setup.cfg
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"""
|
|
2
|
+
sonolink
|
|
3
|
+
~~~~~~
|
|
4
|
+
|
|
5
|
+
A high-performance Lavalink v4 wrapper for Python, inspired by WaveLink.
|
|
6
|
+
|
|
7
|
+
:copyright: (c) 2026-present SonoLink Development Team
|
|
8
|
+
:license: MIT
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from . import gateway, models, rest, utils
|
|
12
|
+
from ._version import __version__, version_info
|
|
13
|
+
from .gateway import *
|
|
14
|
+
from .rest import *
|
|
15
|
+
from .utils import *
|
|
16
|
+
|
|
17
|
+
__all__ = (
|
|
18
|
+
"__version__",
|
|
19
|
+
"version_info",
|
|
20
|
+
"Client",
|
|
21
|
+
"Node",
|
|
22
|
+
"Player",
|
|
23
|
+
"gateway",
|
|
24
|
+
"models",
|
|
25
|
+
"rest",
|
|
26
|
+
"utils",
|
|
27
|
+
"PlayerConnectionState",
|
|
28
|
+
"NodeStatus",
|
|
29
|
+
"TrackEndReason",
|
|
30
|
+
"TrackExceptionSeverity",
|
|
31
|
+
"QueueMode",
|
|
32
|
+
"AutoPlayMode",
|
|
33
|
+
"InactivityMode",
|
|
34
|
+
"SearchProvider",
|
|
35
|
+
"NodeError",
|
|
36
|
+
"InvalidNodePassword",
|
|
37
|
+
"NodeURINotFound",
|
|
38
|
+
"QueueEmpty",
|
|
39
|
+
"HistoryEmpty",
|
|
40
|
+
"Queue",
|
|
41
|
+
"History",
|
|
42
|
+
"ExceptionSeverity",
|
|
43
|
+
"TrackLoadResult",
|
|
44
|
+
"TrackSourceType",
|
|
45
|
+
"RoutePlannerType",
|
|
46
|
+
"IPBlockType",
|
|
47
|
+
"ErrorResponseType",
|
|
48
|
+
"HTTPException",
|
|
49
|
+
"cached_property",
|
|
50
|
+
)
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"""
|
|
2
|
+
MIT License
|
|
3
|
+
|
|
4
|
+
Copyright (c) 2026-present SonoLink Development Team.
|
|
5
|
+
|
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
8
|
+
in the Software without restriction, including without limitation the rights
|
|
9
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
10
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
11
|
+
furnished to do so, subject to the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be included in all
|
|
14
|
+
copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
+
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 FROM,
|
|
21
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
|
+
SOFTWARE.
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
from __future__ import annotations
|
|
26
|
+
|
|
27
|
+
from typing import TYPE_CHECKING, Any
|
|
28
|
+
from weakref import WeakKeyDictionary
|
|
29
|
+
|
|
30
|
+
if TYPE_CHECKING:
|
|
31
|
+
from .gateway.client import Client
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
__all__ = ("clients",)
|
|
35
|
+
|
|
36
|
+
clients: WeakKeyDictionary[Any, Client[Any]] = WeakKeyDictionary()
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"""
|
|
2
|
+
MIT License
|
|
3
|
+
|
|
4
|
+
Copyright (c) 2026-present SonoLink Development Team.
|
|
5
|
+
|
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
8
|
+
in the Software without restriction, including without limitation the rights
|
|
9
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
10
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
11
|
+
furnished to do so, subject to the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be included in all
|
|
14
|
+
copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
+
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 FROM,
|
|
21
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
|
+
SOFTWARE.
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
from __future__ import annotations
|
|
26
|
+
from typing import Literal, NamedTuple
|
|
27
|
+
|
|
28
|
+
__all__ = ("version_info", "__version__")
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class VersionInfo(NamedTuple):
|
|
32
|
+
major: int
|
|
33
|
+
minor: int
|
|
34
|
+
patch: int
|
|
35
|
+
release_level: Literal["alpha", "beta", "candidate", "final"]
|
|
36
|
+
|
|
37
|
+
def __str__(self) -> str:
|
|
38
|
+
return self.as_str()
|
|
39
|
+
|
|
40
|
+
def as_str(self) -> str:
|
|
41
|
+
base = f"{self.major}.{self.minor}.{self.patch}"
|
|
42
|
+
suffixes = {"alpha": "a0", "beta": "b0", "candidate": "rc0"}
|
|
43
|
+
suffix = suffixes.get(self.release_level, "")
|
|
44
|
+
return base + suffix
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
version_info = VersionInfo(major=0, minor=0, patch=0, release_level="final")
|
|
48
|
+
__version__ = version_info.as_str()
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"""
|
|
2
|
+
MIT License
|
|
3
|
+
|
|
4
|
+
Copyright (c) 2026-present SonoLink Development Team.
|
|
5
|
+
|
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
8
|
+
in the Software without restriction, including without limitation the rights
|
|
9
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
10
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
11
|
+
furnished to do so, subject to the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be included in all
|
|
14
|
+
copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
+
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 FROM,
|
|
21
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
|
+
SOFTWARE.
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
from __future__ import annotations
|
|
26
|
+
|
|
27
|
+
__all__ = ("SonoLinkException",)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class SonoLinkException(Exception):
|
|
31
|
+
"""Base exception class for all errors on this library."""
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"""
|
|
2
|
+
sonolink.gateway
|
|
3
|
+
~~~~~~~~~~~~~~
|
|
4
|
+
|
|
5
|
+
Module that handles gateway-related objects.
|
|
6
|
+
|
|
7
|
+
:copyright: (c) 2026-present SonoLink Development Team
|
|
8
|
+
:license: MIT
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from .client import *
|
|
12
|
+
from .enums import *
|
|
13
|
+
from .errors import *
|
|
14
|
+
from .event_models import *
|
|
15
|
+
from .node import *
|
|
16
|
+
from .player import *
|
|
17
|
+
from .queue import *
|
|
18
|
+
|
|
19
|
+
__all__ = (
|
|
20
|
+
"AutoPlayMode",
|
|
21
|
+
"Client",
|
|
22
|
+
"History",
|
|
23
|
+
"HistoryEmpty",
|
|
24
|
+
"InactivityMode",
|
|
25
|
+
"InvalidNodePassword",
|
|
26
|
+
"Node",
|
|
27
|
+
"NodeError",
|
|
28
|
+
"NodeStatus",
|
|
29
|
+
"NodeURINotFound",
|
|
30
|
+
"Player",
|
|
31
|
+
"PlayerConnectionState",
|
|
32
|
+
"Queue",
|
|
33
|
+
"QueueEmpty",
|
|
34
|
+
"QueueMode",
|
|
35
|
+
"SearchProvider",
|
|
36
|
+
"TrackEndReason",
|
|
37
|
+
"TrackExceptionSeverity",
|
|
38
|
+
)
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
"""
|
|
2
|
+
MIT License
|
|
3
|
+
|
|
4
|
+
Copyright (c) 2026-present SonoLink Development Team.
|
|
5
|
+
|
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
8
|
+
in the Software without restriction, including without limitation the rights
|
|
9
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
10
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
11
|
+
furnished to do so, subject to the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be included in all
|
|
14
|
+
copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
+
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 FROM,
|
|
21
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
|
+
SOFTWARE.
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
from __future__ import annotations
|
|
26
|
+
|
|
27
|
+
import collections
|
|
28
|
+
from typing import Any, Final
|
|
29
|
+
|
|
30
|
+
import msgspec
|
|
31
|
+
|
|
32
|
+
from sonolink.models.settings import CacheSettings
|
|
33
|
+
|
|
34
|
+
UNSET: Final = msgspec.UNSET
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class CacheNode[K, V]:
|
|
38
|
+
__slots__ = ("key", "value", "freq", "prev", "next")
|
|
39
|
+
|
|
40
|
+
def __init__(self, key: K, value: V, freq: int = 1) -> None:
|
|
41
|
+
self.key: K = key
|
|
42
|
+
self.value: V = value
|
|
43
|
+
self.freq: int = freq
|
|
44
|
+
|
|
45
|
+
self.prev: CacheNode[K, V] = self
|
|
46
|
+
self.next: CacheNode[K, V] = self
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class LFUCache[K, V]:
|
|
50
|
+
"""
|
|
51
|
+
LFU cache utilizing Circular Doubly Linked Lists.
|
|
52
|
+
"""
|
|
53
|
+
|
|
54
|
+
__slots__ = ("_settings", "_cache", "_freq_map", "_min_freq")
|
|
55
|
+
|
|
56
|
+
def __init__(self, settings: CacheSettings | None = None) -> None:
|
|
57
|
+
self._settings = settings or CacheSettings.default()
|
|
58
|
+
|
|
59
|
+
self._cache: dict[K, CacheNode[K, V]] = {}
|
|
60
|
+
self._freq_map: dict[int, CacheNode[Any, Any]] = collections.defaultdict(
|
|
61
|
+
lambda: CacheNode(None, None, 0)
|
|
62
|
+
)
|
|
63
|
+
self._min_freq: int = 0
|
|
64
|
+
|
|
65
|
+
def __repr__(self) -> str:
|
|
66
|
+
return f"<LFUCache entries={len(self._cache)} max_items={self._settings.max_items}>"
|
|
67
|
+
|
|
68
|
+
def __len__(self) -> int:
|
|
69
|
+
return len(self._cache)
|
|
70
|
+
|
|
71
|
+
def _unlink(self, node: CacheNode[K, V]) -> None:
|
|
72
|
+
"""Remove a node from its current circular list."""
|
|
73
|
+
node.prev.next = node.next
|
|
74
|
+
node.next.prev = node.prev
|
|
75
|
+
|
|
76
|
+
def _link(self, sentinel: CacheNode[Any, Any], node: CacheNode[K, V]) -> None:
|
|
77
|
+
"""Add a node to the end of a circular list (just before the sentinel)."""
|
|
78
|
+
node.next = sentinel
|
|
79
|
+
node.prev = sentinel.prev
|
|
80
|
+
sentinel.prev.next = node
|
|
81
|
+
sentinel.prev = node
|
|
82
|
+
|
|
83
|
+
def get(self, key: K, default: Any = UNSET) -> V | Any:
|
|
84
|
+
if not self._settings.enabled or (node := self._cache.get(key)) is None:
|
|
85
|
+
return default
|
|
86
|
+
|
|
87
|
+
self._unlink(node)
|
|
88
|
+
|
|
89
|
+
# If the min_freq list is empty (sentinel points to itself)
|
|
90
|
+
if (
|
|
91
|
+
node.freq == self._min_freq
|
|
92
|
+
and self._freq_map[node.freq].next is self._freq_map[node.freq]
|
|
93
|
+
):
|
|
94
|
+
self._min_freq += 1
|
|
95
|
+
|
|
96
|
+
node.freq += 1
|
|
97
|
+
self._link(self._freq_map[node.freq], node)
|
|
98
|
+
return node.value
|
|
99
|
+
|
|
100
|
+
def put(self, key: K, value: V) -> None:
|
|
101
|
+
if not self._settings.enabled or self._settings.max_items <= 0:
|
|
102
|
+
return
|
|
103
|
+
|
|
104
|
+
if key in self._cache:
|
|
105
|
+
node = self._cache[key]
|
|
106
|
+
node.value = value
|
|
107
|
+
self.get(key)
|
|
108
|
+
return
|
|
109
|
+
|
|
110
|
+
if len(self._cache) >= self._settings.max_items:
|
|
111
|
+
# Evict the oldest node from the lowest freq. list
|
|
112
|
+
sentinel = self._freq_map[self._min_freq]
|
|
113
|
+
evicted = sentinel.next
|
|
114
|
+
self._unlink(evicted)
|
|
115
|
+
del self._cache[evicted.key]
|
|
116
|
+
|
|
117
|
+
new_node = CacheNode(key, value)
|
|
118
|
+
self._cache[key] = new_node
|
|
119
|
+
self._link(self._freq_map[1], new_node)
|
|
120
|
+
self._min_freq = 1
|