start typehinting and correcting the library
This commit is contained in:
parent
31d4e1aca2
commit
c9a331b278
|
|
@ -5,3 +5,5 @@ dist/
|
||||||
pomice.egg-info/
|
pomice.egg-info/
|
||||||
docs/_build/
|
docs/_build/
|
||||||
build/
|
build/
|
||||||
|
.gitpod.yml
|
||||||
|
.python-verson
|
||||||
|
|
|
||||||
10
.gitpod.yml
10
.gitpod.yml
|
|
@ -1,10 +0,0 @@
|
||||||
# This configuration file was automatically generated by Gitpod.
|
|
||||||
# Please adjust to your needs (see https://www.gitpod.io/docs/introduction/learn-gitpod/gitpod-yaml)
|
|
||||||
# and commit this file to your remote git repository to share the goodness with others.
|
|
||||||
|
|
||||||
# Learn more from ready-to-use templates: https://www.gitpod.io/docs/introduction/getting-started/quickstart
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- init: pip install .
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
3.10.9
|
||||||
44
docs/conf.py
44
docs/conf.py
|
|
@ -1,15 +1,3 @@
|
||||||
# Configuration file for the Sphinx documentation builder.
|
|
||||||
#
|
|
||||||
# This file only contains a selection of the most common options. For a full
|
|
||||||
# list see the documentation:
|
|
||||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html
|
|
||||||
|
|
||||||
# -- Path setup --------------------------------------------------------------
|
|
||||||
|
|
||||||
# If extensions (or modules to document with autodoc) are in another directory,
|
|
||||||
# add these directories to sys.path here. If the directory is relative to the
|
|
||||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
|
||||||
#
|
|
||||||
import importlib
|
import importlib
|
||||||
import inspect
|
import inspect
|
||||||
import os
|
import os
|
||||||
|
|
@ -20,21 +8,14 @@ sys.path.insert(0, os.path.abspath('..'))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# -- Project information -----------------------------------------------------
|
|
||||||
|
|
||||||
project = 'Pomice'
|
project = 'Pomice'
|
||||||
copyright = '2023, cloudwithax'
|
copyright = '2023, cloudwithax'
|
||||||
author = 'cloudwithax'
|
author = 'cloudwithax'
|
||||||
|
|
||||||
# The full version, including alpha/beta/rc tags
|
release = '2.2'
|
||||||
release = '2.1.1'
|
|
||||||
|
|
||||||
|
|
||||||
# -- General configuration ---------------------------------------------------
|
|
||||||
|
|
||||||
# Add any Sphinx extension module names here, as strings. They can be
|
|
||||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
|
||||||
# ones.
|
|
||||||
extensions = [
|
extensions = [
|
||||||
'sphinx.ext.autodoc',
|
'sphinx.ext.autodoc',
|
||||||
'sphinx.ext.autosummary',
|
'sphinx.ext.autosummary',
|
||||||
|
|
@ -60,25 +41,23 @@ myst_enable_extensions = [
|
||||||
myst_heading_anchors = 3
|
myst_heading_anchors = 3
|
||||||
|
|
||||||
|
|
||||||
# Add any paths that contain templates here, relative to this directory.
|
|
||||||
templates_path = ['_templates']
|
templates_path = ['_templates']
|
||||||
|
|
||||||
# List of patterns, relative to source directory, that match files and
|
|
||||||
# directories to ignore when looking for source files.
|
|
||||||
# This pattern also affects html_static_path and html_extra_path.
|
|
||||||
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
|
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
|
||||||
|
|
||||||
|
# We need to include this because discord.py has special tags
|
||||||
|
# they inlcude within their docstrings that dont parse
|
||||||
|
# right within our docs
|
||||||
|
|
||||||
# -- Options for HTML output -------------------------------------------------
|
rst_prolog = """
|
||||||
|
.. |coro| replace:: This function is a |coroutine_link|_.
|
||||||
|
.. |maybecoro| replace:: This function *could be a* |coroutine_link|_.
|
||||||
|
.. |coroutine_link| replace:: *coroutine*
|
||||||
|
.. _coroutine_link: https://docs.python.org/3/library/asyncio-task.html#coroutine
|
||||||
|
"""
|
||||||
|
|
||||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
|
||||||
# a list of builtin themes.
|
|
||||||
#
|
|
||||||
html_theme = 'furo'
|
html_theme = 'furo'
|
||||||
|
|
||||||
# Add any paths that contain custom static files (such as style sheets) here,
|
|
||||||
# relative to this directory. They are copied after the builtin static files,
|
|
||||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
|
||||||
html_static_path = ['_static']
|
html_static_path = ['_static']
|
||||||
|
|
||||||
html_title = "Pomice"
|
html_title = "Pomice"
|
||||||
|
|
@ -103,6 +82,9 @@ html_theme_options: Dict[str, Any] = {
|
||||||
"source_directory": "docs/",
|
"source_directory": "docs/",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Grab lines from source files and embed into the docs
|
||||||
|
# so theres a point of reference
|
||||||
|
|
||||||
def linkcode_resolve(domain, info):
|
def linkcode_resolve(domain, info):
|
||||||
if domain != 'py':
|
if domain != 'py':
|
||||||
return None
|
return None
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,12 @@ import re
|
||||||
|
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
|
|
||||||
|
__all__ = (
|
||||||
|
'SearchType',
|
||||||
|
'TrackType',
|
||||||
|
'PlaylistType'
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class SearchType(Enum):
|
class SearchType(Enum):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ from discord import Client
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
|
|
||||||
from .pool import NodePool
|
from .pool import NodePool
|
||||||
|
from .objects import Track
|
||||||
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING, Union
|
from typing import TYPE_CHECKING, Union
|
||||||
|
|
@ -34,8 +35,8 @@ class TrackStartEvent(PomiceEvent):
|
||||||
name = "track_start"
|
name = "track_start"
|
||||||
|
|
||||||
def __init__(self, data: dict, player: Player):
|
def __init__(self, data: dict, player: Player):
|
||||||
self.player = player
|
self.player: Player = player
|
||||||
self.track = self.player._current
|
self.track: Track = self.player._current
|
||||||
|
|
||||||
# on_pomice_track_start(player, track)
|
# on_pomice_track_start(player, track)
|
||||||
self.handler_args = self.player, self.track
|
self.handler_args = self.player, self.track
|
||||||
|
|
@ -51,8 +52,8 @@ class TrackEndEvent(PomiceEvent):
|
||||||
name = "track_end"
|
name = "track_end"
|
||||||
|
|
||||||
def __init__(self, data: dict, player: Player):
|
def __init__(self, data: dict, player: Player):
|
||||||
self.player = player
|
self.player: Player = player
|
||||||
self.track = self.player._ending_track
|
self.track: Track = self.player._ending_track
|
||||||
self.reason: str = data["reason"]
|
self.reason: str = data["reason"]
|
||||||
|
|
||||||
# on_pomice_track_end(player, track, reason)
|
# on_pomice_track_end(player, track, reason)
|
||||||
|
|
@ -73,8 +74,8 @@ class TrackStuckEvent(PomiceEvent):
|
||||||
name = "track_stuck"
|
name = "track_stuck"
|
||||||
|
|
||||||
def __init__(self, data: dict, player: Player):
|
def __init__(self, data: dict, player: Player):
|
||||||
self.player = player
|
self.player: Player = player
|
||||||
self.track = self.player._ending_track
|
self.track: Track = self.player._ending_track
|
||||||
self.threshold: float = data["thresholdMs"]
|
self.threshold: float = data["thresholdMs"]
|
||||||
|
|
||||||
# on_pomice_track_stuck(player, track, threshold)
|
# on_pomice_track_stuck(player, track, threshold)
|
||||||
|
|
@ -92,8 +93,8 @@ class TrackExceptionEvent(PomiceEvent):
|
||||||
name = "track_exception"
|
name = "track_exception"
|
||||||
|
|
||||||
def __init__(self, data: dict, player: Player):
|
def __init__(self, data: dict, player: Player):
|
||||||
self.player = player
|
self.player: Player = player
|
||||||
self.track = self.player._ending_track
|
self.track: Track = self.player._ending_track
|
||||||
if data.get('error'):
|
if data.get('error'):
|
||||||
# User is running Lavalink <= 3.3
|
# User is running Lavalink <= 3.3
|
||||||
self.exception: str = data["error"]
|
self.exception: str = data["error"]
|
||||||
|
|
@ -110,7 +111,7 @@ class TrackExceptionEvent(PomiceEvent):
|
||||||
|
|
||||||
class WebSocketClosedPayload:
|
class WebSocketClosedPayload:
|
||||||
def __init__(self, data: dict):
|
def __init__(self, data: dict):
|
||||||
self.guild = NodePool.get_node().bot.get_guild(int(data["guildId"]))
|
self.guild: Guild = NodePool.get_node().bot.get_guild(int(data["guildId"]))
|
||||||
self.code: int = data["code"]
|
self.code: int = data["code"]
|
||||||
self.reason: str = data["code"]
|
self.reason: str = data["code"]
|
||||||
self.by_remote: bool = data["byRemote"]
|
self.by_remote: bool = data["byRemote"]
|
||||||
|
|
@ -127,7 +128,7 @@ class WebSocketClosedEvent(PomiceEvent):
|
||||||
name = "websocket_closed"
|
name = "websocket_closed"
|
||||||
|
|
||||||
def __init__(self, data: dict, _):
|
def __init__(self, data: dict, _):
|
||||||
self.payload = WebSocketClosedPayload(data)
|
self.payload: WebSocketClosedPayload = WebSocketClosedPayload(data)
|
||||||
|
|
||||||
# on_pomice_websocket_closed(payload)
|
# on_pomice_websocket_closed(payload)
|
||||||
self.handler_args = self.payload,
|
self.handler_args = self.payload,
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ class Filter:
|
||||||
This is necessary for the removal of filters.
|
This is necessary for the removal of filters.
|
||||||
"""
|
"""
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.payload = None
|
self.payload: dict = None
|
||||||
self.tag: str = None
|
self.tag: str = None
|
||||||
self.preload: bool = False
|
self.preload: bool = False
|
||||||
|
|
||||||
|
|
@ -132,12 +132,12 @@ class Timescale(Filter):
|
||||||
if rate < 0:
|
if rate < 0:
|
||||||
raise FilterInvalidArgument("Timescale rate must be more than 0.")
|
raise FilterInvalidArgument("Timescale rate must be more than 0.")
|
||||||
|
|
||||||
self.speed = speed
|
self.speed: float = speed
|
||||||
self.pitch = pitch
|
self.pitch: float = pitch
|
||||||
self.rate = rate
|
self.rate: float = rate
|
||||||
self.tag = tag
|
self.tag: str = tag
|
||||||
|
|
||||||
self.payload = {"timescale": {"speed": self.speed,
|
self.payload: dict = {"timescale": {"speed": self.speed,
|
||||||
"pitch": self.pitch,
|
"pitch": self.pitch,
|
||||||
"rate": self.rate}}
|
"rate": self.rate}}
|
||||||
|
|
||||||
|
|
@ -181,13 +181,13 @@ class Karaoke(Filter):
|
||||||
):
|
):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
self.level = level
|
self.level: float = level
|
||||||
self.mono_level = mono_level
|
self.mono_level: float = mono_level
|
||||||
self.filter_band = filter_band
|
self.filter_band: float = filter_band
|
||||||
self.filter_width = filter_width
|
self.filter_width: float = filter_width
|
||||||
self.tag = tag
|
self.tag: str = tag
|
||||||
|
|
||||||
self.payload = {"karaoke": {"level": self.level,
|
self.payload: dict = {"karaoke": {"level": self.level,
|
||||||
"monoLevel": self.mono_level,
|
"monoLevel": self.mono_level,
|
||||||
"filterBand": self.filter_band,
|
"filterBand": self.filter_band,
|
||||||
"filterWidth": self.filter_width}}
|
"filterWidth": self.filter_width}}
|
||||||
|
|
@ -220,11 +220,11 @@ class Tremolo(Filter):
|
||||||
raise FilterInvalidArgument(
|
raise FilterInvalidArgument(
|
||||||
"Tremolo depth must be between 0 and 1.")
|
"Tremolo depth must be between 0 and 1.")
|
||||||
|
|
||||||
self.frequency = frequency
|
self.frequency: float = frequency
|
||||||
self.depth = depth
|
self.depth: float = depth
|
||||||
self.tag = tag
|
self.tag: str = tag
|
||||||
|
|
||||||
self.payload = {"tremolo": {"frequency": self.frequency,
|
self.payload: dict = {"tremolo": {"frequency": self.frequency,
|
||||||
"depth": self.depth}}
|
"depth": self.depth}}
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
|
|
@ -252,11 +252,11 @@ class Vibrato(Filter):
|
||||||
raise FilterInvalidArgument(
|
raise FilterInvalidArgument(
|
||||||
"Vibrato depth must be between 0 and 1.")
|
"Vibrato depth must be between 0 and 1.")
|
||||||
|
|
||||||
self.frequency = frequency
|
self.frequency: float = frequency
|
||||||
self.depth = depth
|
self.depth: float = depth
|
||||||
self.tag = tag
|
self.tag: str = tag
|
||||||
|
|
||||||
self.payload = {"vibrato": {"frequency": self.frequency,
|
self.payload: dict = {"vibrato": {"frequency": self.frequency,
|
||||||
"depth": self.depth}}
|
"depth": self.depth}}
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
|
|
@ -271,9 +271,9 @@ class Rotation(Filter):
|
||||||
def __init__(self, *, tag: str, rotation_hertz: float = 5):
|
def __init__(self, *, tag: str, rotation_hertz: float = 5):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
self.rotation_hertz = rotation_hertz
|
self.rotation_hertz: float = rotation_hertz
|
||||||
self.tag = tag
|
self.tag: str = tag
|
||||||
self.payload = {"rotation": {"rotationHz": self.rotation_hertz}}
|
self.payload: dict = {"rotation": {"rotationHz": self.rotation_hertz}}
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
return f"<Pomice.RotationFilter tag={self.tag} rotation_hertz={self.rotation_hertz}>"
|
return f"<Pomice.RotationFilter tag={self.tag} rotation_hertz={self.rotation_hertz}>"
|
||||||
|
|
@ -308,13 +308,13 @@ class ChannelMix(Filter):
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
"'right_to_left' value must be more than or equal to 0 or less than or equal to 1.")
|
"'right_to_left' value must be more than or equal to 0 or less than or equal to 1.")
|
||||||
|
|
||||||
self.left_to_left = left_to_left
|
self.left_to_left: float = left_to_left
|
||||||
self.left_to_right = left_to_right
|
self.left_to_right: float = left_to_right
|
||||||
self.right_to_left = right_to_left
|
self.right_to_left: float = right_to_left
|
||||||
self.right_to_right = right_to_right
|
self.right_to_right: float = right_to_right
|
||||||
self.tag = tag
|
self.tag: str = tag
|
||||||
|
|
||||||
self.payload = {"channelMix": {"leftToLeft": self.left_to_left,
|
self.payload: dict = {"channelMix": {"leftToLeft": self.left_to_left,
|
||||||
"leftToRight": self.left_to_right,
|
"leftToRight": self.left_to_right,
|
||||||
"rightToLeft": self.right_to_left,
|
"rightToLeft": self.right_to_left,
|
||||||
"rightToRight": self.right_to_right}
|
"rightToRight": self.right_to_right}
|
||||||
|
|
@ -347,17 +347,17 @@ class Distortion(Filter):
|
||||||
):
|
):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
self.sin_offset = sin_offset
|
self.sin_offset: float = sin_offset
|
||||||
self.sin_scale = sin_scale
|
self.sin_scale: float = sin_scale
|
||||||
self.cos_offset = cos_offset
|
self.cos_offset: float = cos_offset
|
||||||
self.cos_scale = cos_scale
|
self.cos_scale: float = cos_scale
|
||||||
self.tan_offset = tan_offset
|
self.tan_offset: float = tan_offset
|
||||||
self.tan_scale = tan_scale
|
self.tan_scale: float = tan_scale
|
||||||
self.offset = offset
|
self.offset: float = offset
|
||||||
self.scale = scale
|
self.scale: float = scale
|
||||||
self.tag = tag
|
self.tag: str = tag
|
||||||
|
|
||||||
self.payload = {"distortion": {
|
self.payload: dict = {"distortion": {
|
||||||
"sinOffset": self.sin_offset,
|
"sinOffset": self.sin_offset,
|
||||||
"sinScale": self.sin_scale,
|
"sinScale": self.sin_scale,
|
||||||
"cosOffset": self.cos_offset,
|
"cosOffset": self.cos_offset,
|
||||||
|
|
@ -383,9 +383,9 @@ class LowPass(Filter):
|
||||||
def __init__(self, *, tag: str, smoothing: float = 20):
|
def __init__(self, *, tag: str, smoothing: float = 20):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
self.smoothing = smoothing
|
self.smoothing: float = smoothing
|
||||||
self.tag = tag
|
self.tag: str = tag
|
||||||
self.payload = {"lowPass": {"smoothing": self.smoothing}}
|
self.payload: dict = {"lowPass": {"smoothing": self.smoothing}}
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
return f"<Pomice.LowPass tag={self.tag} smoothing={self.smoothing}>"
|
return f"<Pomice.LowPass tag={self.tag} smoothing={self.smoothing}>"
|
||||||
|
|
|
||||||
|
|
@ -26,8 +26,8 @@ class Track:
|
||||||
timestamp: Optional[float] = None,
|
timestamp: Optional[float] = None,
|
||||||
requester: Optional[Union[Member, User]] = None,
|
requester: Optional[Union[Member, User]] = None,
|
||||||
):
|
):
|
||||||
self.track_id = track_id
|
self.track_id: str = track_id
|
||||||
self.info = info
|
self.info: dict = info
|
||||||
self.track_type: TrackType = track_type
|
self.track_type: TrackType = track_type
|
||||||
self.filters: Optional[List[Filter]] = filters
|
self.filters: Optional[List[Filter]] = filters
|
||||||
self.timestamp: Optional[float] = timestamp
|
self.timestamp: Optional[float] = timestamp
|
||||||
|
|
@ -36,35 +36,35 @@ class Track:
|
||||||
self.original: Optional[Track] = None
|
self.original: Optional[Track] = None
|
||||||
else:
|
else:
|
||||||
self.original = self
|
self.original = self
|
||||||
self._search_type = search_type
|
self._search_type: SearchType = search_type
|
||||||
|
|
||||||
self.playlist: Playlist = None
|
self.playlist: Playlist = None
|
||||||
|
|
||||||
self.title = info.get("title")
|
self.title: str = info.get("title")
|
||||||
self.author = info.get("author")
|
self.author: str = info.get("author")
|
||||||
self.uri = info.get("uri")
|
self.uri: str = info.get("uri")
|
||||||
self.identifier = info.get("identifier")
|
self.identifier: str = info.get("identifier")
|
||||||
self.isrc = info.get("isrc")
|
self.isrc: str = info.get("isrc")
|
||||||
|
|
||||||
if self.uri:
|
if self.uri:
|
||||||
if info.get("thumbnail"):
|
if info.get("thumbnail"):
|
||||||
self.thumbnail = info.get("thumbnail")
|
self.thumbnail: str = info.get("thumbnail")
|
||||||
elif self.track_type == TrackType.SOUNDCLOUD:
|
elif self.track_type == TrackType.SOUNDCLOUD:
|
||||||
# ok so theres no feasible way of getting a Soundcloud image URL
|
# ok so theres no feasible way of getting a Soundcloud image URL
|
||||||
# so we're just gonna leave it blank for brevity
|
# so we're just gonna leave it blank for brevity
|
||||||
self.thumbnail = None
|
self.thumbnail = None
|
||||||
else:
|
else:
|
||||||
self.thumbnail = f"https://img.youtube.com/vi/{self.identifier}/mqdefault.jpg"
|
self.thumbnail: str = f"https://img.youtube.com/vi/{self.identifier}/mqdefault.jpg"
|
||||||
|
|
||||||
self.length = info.get("length")
|
self.length: int = info.get("length")
|
||||||
self.ctx = ctx
|
self.ctx: commands.Context = ctx
|
||||||
if requester:
|
if requester:
|
||||||
self.requester = requester
|
self.requester: Optional[Union[Member, User]] = requester
|
||||||
else:
|
else:
|
||||||
self.requester = self.ctx.author if ctx else None
|
self.requester: Optional[Union[Member, User]] = self.ctx.author if ctx else None
|
||||||
self.is_stream = info.get("isStream")
|
self.is_stream: bool = info.get("isStream")
|
||||||
self.is_seekable = info.get("isSeekable")
|
self.is_seekable: bool = info.get("isSeekable")
|
||||||
self.position = info.get("position")
|
self.position: int = info.get("position")
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
if not isinstance(other, Track):
|
if not isinstance(other, Track):
|
||||||
|
|
@ -97,13 +97,13 @@ class Playlist:
|
||||||
thumbnail: Optional[str] = None,
|
thumbnail: Optional[str] = None,
|
||||||
uri: Optional[str] = None
|
uri: Optional[str] = None
|
||||||
):
|
):
|
||||||
self.playlist_info = playlist_info
|
self.playlist_info: dict = playlist_info
|
||||||
self.tracks: List[Track] = tracks
|
self.tracks: List[Track] = tracks
|
||||||
self.name = playlist_info.get("name")
|
self.name: str = playlist_info.get("name")
|
||||||
self.playlist_type = playlist_type
|
self.playlist_type: PlaylistType = playlist_type
|
||||||
|
|
||||||
self._thumbnail = thumbnail
|
self._thumbnail: str = thumbnail
|
||||||
self._uri = uri
|
self._uri: str = uri
|
||||||
|
|
||||||
for track in self.tracks:
|
for track in self.tracks:
|
||||||
track.playlist = self
|
track.playlist = self
|
||||||
|
|
@ -111,9 +111,9 @@ class Playlist:
|
||||||
if (index := playlist_info.get("selectedTrack")) == -1:
|
if (index := playlist_info.get("selectedTrack")) == -1:
|
||||||
self.selected_track = None
|
self.selected_track = None
|
||||||
else:
|
else:
|
||||||
self.selected_track = self.tracks[index]
|
self.selected_track: Track = self.tracks[index]
|
||||||
|
|
||||||
self.track_count = len(self.tracks)
|
self.track_count: int = len(self.tracks)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,8 @@ from .pool import Node, NodePool
|
||||||
|
|
||||||
class Filters:
|
class Filters:
|
||||||
"""Helper class for filters"""
|
"""Helper class for filters"""
|
||||||
|
__slots__ = ('_filters')
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self._filters: List[Filter] = []
|
self._filters: List[Filter] = []
|
||||||
|
|
||||||
|
|
@ -97,6 +99,24 @@ class Player(VoiceProtocol):
|
||||||
```
|
```
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
__slots__ = (
|
||||||
|
'client',
|
||||||
|
'_bot',
|
||||||
|
'channel',
|
||||||
|
'_guild',
|
||||||
|
'_node',
|
||||||
|
'_current',
|
||||||
|
'_filters',
|
||||||
|
'_volume',
|
||||||
|
'_paused',
|
||||||
|
'_is_connected',
|
||||||
|
'_position',
|
||||||
|
'_last_position',
|
||||||
|
'_last_update',
|
||||||
|
'_ending_track',
|
||||||
|
'_player_endpoint_uri'
|
||||||
|
)
|
||||||
|
|
||||||
def __call__(self, client: Client, channel: VoiceChannel):
|
def __call__(self, client: Client, channel: VoiceChannel):
|
||||||
self.client: Client = client
|
self.client: Client = client
|
||||||
self.channel: VoiceChannel = channel
|
self.channel: VoiceChannel = channel
|
||||||
|
|
@ -117,7 +137,7 @@ class Player(VoiceProtocol):
|
||||||
self._guild: Guild = channel.guild if channel else None
|
self._guild: Guild = channel.guild if channel else None
|
||||||
|
|
||||||
self._node: Node = node if node else NodePool.get_node()
|
self._node: Node = node if node else NodePool.get_node()
|
||||||
self._current: Track = None
|
self._current: Optional[Track] = None
|
||||||
self._filters: Filters = Filters()
|
self._filters: Filters = Filters()
|
||||||
self._volume: int = 100
|
self._volume: int = 100
|
||||||
self._paused: bool = False
|
self._paused: bool = False
|
||||||
|
|
@ -130,9 +150,9 @@ class Player(VoiceProtocol):
|
||||||
|
|
||||||
self._voice_state: dict = {}
|
self._voice_state: dict = {}
|
||||||
|
|
||||||
self._player_endpoint_uri = f'sessions/{self._node._session_id}/players'
|
self._player_endpoint_uri: str = f'sessions/{self._node._session_id}/players'
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self) -> str:
|
||||||
return (
|
return (
|
||||||
f"<Pomice.player bot={self.bot} guildId={self.guild.id} "
|
f"<Pomice.player bot={self.bot} guildId={self.guild.id} "
|
||||||
f"is_connected={self.is_connected} is_playing={self.is_playing}>"
|
f"is_connected={self.is_connected} is_playing={self.is_playing}>"
|
||||||
|
|
|
||||||
|
|
@ -65,27 +65,26 @@ class Node:
|
||||||
fallback: bool = False
|
fallback: bool = False
|
||||||
|
|
||||||
):
|
):
|
||||||
self._bot = bot
|
self._bot: Union[Client, commands.Bot] = bot
|
||||||
self._host = host
|
self._host: str = host
|
||||||
self._port = port
|
self._port: int = port
|
||||||
self._pool = pool
|
self._pool: NodePool = pool
|
||||||
self._password = password
|
self._password: str = password
|
||||||
self._identifier = identifier
|
self._identifier: str = identifier
|
||||||
self._heartbeat = heartbeat
|
self._heartbeat: int = heartbeat
|
||||||
self._secure = secure
|
self._secure: bool = secure
|
||||||
self.fallback = fallback
|
self.fallback: bool = fallback
|
||||||
|
|
||||||
|
|
||||||
self._websocket_uri = f"{'wss' if self._secure else 'ws'}://{self._host}:{self._port}/v3/websocket"
|
self._websocket_uri: str = f"{'wss' if self._secure else 'ws'}://{self._host}:{self._port}/v3/websocket"
|
||||||
self._rest_uri = f"{'https' if self._secure else 'http'}://{self._host}:{self._port}"
|
self._rest_uri: str = f"{'https' if self._secure else 'http'}://{self._host}:{self._port}"
|
||||||
|
|
||||||
self._session = session or aiohttp.ClientSession()
|
self._session: ClientSession = session or aiohttp.ClientSession()
|
||||||
self._websocket: aiohttp.ClientWebSocketResponse = None
|
self._websocket: aiohttp.ClientWebSocketResponse = None
|
||||||
self._task: asyncio.Task = None
|
self._task: asyncio.Task = None
|
||||||
|
|
||||||
self._session_id: str = None
|
self._session_id: str = None
|
||||||
self._metadata = None
|
self._available: bool = False
|
||||||
self._available = None
|
|
||||||
self._version: str = None
|
self._version: str = None
|
||||||
self._route_planner = RoutePlanner(self)
|
self._route_planner = RoutePlanner(self)
|
||||||
|
|
||||||
|
|
@ -97,13 +96,13 @@ class Node:
|
||||||
|
|
||||||
self._players: Dict[int, Player] = {}
|
self._players: Dict[int, Player] = {}
|
||||||
|
|
||||||
self._spotify_client_id = spotify_client_id
|
self._spotify_client_id: str = spotify_client_id
|
||||||
self._spotify_client_secret = spotify_client_secret
|
self._spotify_client_secret: str = spotify_client_secret
|
||||||
|
|
||||||
self._apple_music_client = None
|
self._apple_music_client: Optional[applemusic.Client] = None
|
||||||
|
|
||||||
if self._spotify_client_id and self._spotify_client_secret:
|
if self._spotify_client_id and self._spotify_client_secret:
|
||||||
self._spotify_client = spotify.Client(
|
self._spotify_client: spotify.Client = spotify.Client(
|
||||||
self, self._spotify_client_id, self._spotify_client_secret
|
self, self._spotify_client_id, self._spotify_client_secret
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -175,13 +175,12 @@ class Queue(Iterable[Track]):
|
||||||
return len(self._queue)
|
return len(self._queue)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def get_queue(self) -> List:
|
def get_queue(self) -> List:
|
||||||
"""Returns the queue as a List"""
|
"""Returns the queue as a List"""
|
||||||
return self._queue
|
return self._queue
|
||||||
|
|
||||||
|
|
||||||
def get(self):
|
def get(self) -> Track:
|
||||||
"""Return next immediately available item in queue if any.
|
"""Return next immediately available item in queue if any.
|
||||||
Raises QueueEmpty if no items in queue.
|
Raises QueueEmpty if no items in queue.
|
||||||
"""
|
"""
|
||||||
|
|
@ -297,7 +296,7 @@ class Queue(Iterable[Track]):
|
||||||
"""Remove all items from the queue."""
|
"""Remove all items from the queue."""
|
||||||
self._queue.clear()
|
self._queue.clear()
|
||||||
|
|
||||||
def set_loop_mode(self, mode: LoopMode):
|
def set_loop_mode(self, mode: LoopMode) -> None:
|
||||||
"""
|
"""
|
||||||
Sets the loop mode of the queue.
|
Sets the loop mode of the queue.
|
||||||
Takes the LoopMode enum as an argument.
|
Takes the LoopMode enum as an argument.
|
||||||
|
|
@ -313,7 +312,7 @@ class Queue(Iterable[Track]):
|
||||||
self._current_item = self._queue[index]
|
self._current_item = self._queue[index]
|
||||||
|
|
||||||
|
|
||||||
def disable_loop(self):
|
def disable_loop(self) -> None:
|
||||||
"""
|
"""
|
||||||
Disables loop mode if set.
|
Disables loop mode if set.
|
||||||
Raises QueueException if loop mode is already None.
|
Raises QueueException if loop mode is already None.
|
||||||
|
|
@ -328,17 +327,17 @@ class Queue(Iterable[Track]):
|
||||||
self._loop_mode = None
|
self._loop_mode = None
|
||||||
|
|
||||||
|
|
||||||
def shuffle(self):
|
def shuffle(self) -> None:
|
||||||
"""Shuffles the queue."""
|
"""Shuffles the queue."""
|
||||||
return random.shuffle(self._queue)
|
return random.shuffle(self._queue)
|
||||||
|
|
||||||
def clear_track_filters(self):
|
def clear_track_filters(self) -> None:
|
||||||
"""Clears all filters applied to tracks"""
|
"""Clears all filters applied to tracks"""
|
||||||
for track in self._queue:
|
for track in self._queue:
|
||||||
track.filters = None
|
track.filters = None
|
||||||
|
|
||||||
def jump(self, item: Track):
|
def jump(self, item: Track) -> None:
|
||||||
"""Returns a new queue with the specified track at the beginning."""
|
"""Mutates the queue so that all tracks before the specified track are removed."""
|
||||||
index = self.find_position(item)
|
index = self.find_position(item)
|
||||||
new_queue = self._queue[index:self.size]
|
new_queue = self._queue[index:self.size]
|
||||||
self._queue = new_queue
|
self._queue = new_queue
|
||||||
|
|
@ -4,6 +4,7 @@ if TYPE_CHECKING:
|
||||||
from .pool import Node
|
from .pool import Node
|
||||||
|
|
||||||
from .utils import RouteStats
|
from .utils import RouteStats
|
||||||
|
from aiohttp import ClientSession
|
||||||
|
|
||||||
class RoutePlanner:
|
class RoutePlanner:
|
||||||
"""
|
"""
|
||||||
|
|
@ -12,15 +13,14 @@ class RoutePlanner:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, node: Node) -> None:
|
def __init__(self, node: Node) -> None:
|
||||||
self.node = node
|
self.node: Node = node
|
||||||
self.session = node._session
|
self.session: ClientSession = node._session
|
||||||
|
|
||||||
async def get_status(self):
|
async def get_status(self) -> RouteStats:
|
||||||
"""Gets the status of the route planner API."""
|
"""Gets the status of the route planner API."""
|
||||||
data: dict = await self.node.send(method="GET", path="routeplanner/status")
|
data: dict = await self.node.send(method="GET", path="routeplanner/status")
|
||||||
return RouteStats(data)
|
return RouteStats(data)
|
||||||
|
|
||||||
|
|
||||||
async def free_address(self, ip: str):
|
async def free_address(self, ip: str):
|
||||||
"""Frees an address using the route planner API"""
|
"""Frees an address using the route planner API"""
|
||||||
await self.node.send(method="POST", path="routeplanner/free/address", data={"address": ip})
|
await self.node.send(method="POST", path="routeplanner/free/address", data={"address": ip})
|
||||||
|
|
|
||||||
1
setup.py
1
setup.py
|
|
@ -41,6 +41,7 @@ setuptools.setup(
|
||||||
description="The modern Lavalink wrapper designed for Discord.py",
|
description="The modern Lavalink wrapper designed for Discord.py",
|
||||||
long_description=readme,
|
long_description=readme,
|
||||||
long_description_content_type="text/markdown",
|
long_description_content_type="text/markdown",
|
||||||
|
package_data={"pomice": ["py.typed"]},
|
||||||
include_package_data=True,
|
include_package_data=True,
|
||||||
install_requires=requirements,
|
install_requires=requirements,
|
||||||
extra_require=None,
|
extra_require=None,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue