Cleaned up some code and added some types
This commit is contained in:
parent
134398dcbd
commit
ec9e6929b4
|
|
@ -2,15 +2,14 @@ import asyncio
|
||||||
import json
|
import json
|
||||||
import re
|
import re
|
||||||
import socket
|
import socket
|
||||||
|
import aiohttp
|
||||||
import time
|
import time
|
||||||
from typing import Optional, Type
|
from typing import Optional, Type
|
||||||
from urllib.parse import quote
|
from urllib.parse import quote
|
||||||
|
|
||||||
import aiohttp
|
|
||||||
import discord
|
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
|
|
||||||
from . import __version__, objects, spotify
|
|
||||||
|
from . import __version__, objects, spotify, NodePool
|
||||||
from .exceptions import (
|
from .exceptions import (
|
||||||
InvalidSpotifyClientAuthorization,
|
InvalidSpotifyClientAuthorization,
|
||||||
NodeConnectionFailure,
|
NodeConnectionFailure,
|
||||||
|
|
@ -37,7 +36,7 @@ class Node:
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
pool,
|
pool,
|
||||||
bot: Type[discord.Client],
|
bot: Type[commands.Bot],
|
||||||
host: str,
|
host: str,
|
||||||
port: int,
|
port: int,
|
||||||
password: str,
|
password: str,
|
||||||
|
|
@ -96,7 +95,7 @@ class Node:
|
||||||
return self._websocket is not None and not self._websocket.closed
|
return self._websocket is not None and not self._websocket.closed
|
||||||
|
|
||||||
@property
|
@property
|
||||||
async def latency(self):
|
async def latency(self) -> int:
|
||||||
"""Property which returns the latency of the node in milliseconds"""
|
"""Property which returns the latency of the node in milliseconds"""
|
||||||
start_time = time.time()
|
start_time = time.time()
|
||||||
await self.send(op="ping")
|
await self.send(op="ping")
|
||||||
|
|
@ -104,28 +103,28 @@ class Node:
|
||||||
return (end_time - start_time) * 1000
|
return (end_time - start_time) * 1000
|
||||||
|
|
||||||
@property
|
@property
|
||||||
async def stats(self):
|
async def stats(self) -> NodeStats:
|
||||||
"""Property which returns the node stats."""
|
"""Property which returns the node stats."""
|
||||||
await self.send(op="get-stats")
|
await self.send(op="get-stats")
|
||||||
node_stats = await self._bot.wait_for("node_stats")
|
node_stats = await self._bot.wait_for("node_stats")
|
||||||
return node_stats
|
return node_stats
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def players(self):
|
def players(self) -> dict:
|
||||||
"""Property which returns a dict containing the guild ID and the player object."""
|
"""Property which returns a dict containing the guild ID and the player object."""
|
||||||
return self._players
|
return self._players
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def bot(self):
|
def bot(self) -> commands.Bot:
|
||||||
"""Property which returns the discord.py client linked to this node"""
|
"""Property which returns the discord.py client linked to this node"""
|
||||||
return self._bot
|
return self._bot
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def player_count(self):
|
def player_count(self) -> int:
|
||||||
return len(self.players)
|
return len(self.players)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def pool(self):
|
def pool(self) -> NodePool:
|
||||||
"""Property which returns the node pool this node is a part of."""
|
"""Property which returns the node pool this node is a part of."""
|
||||||
return self._pool
|
return self._pool
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import discord
|
||||||
from discord import VoiceChannel, VoiceProtocol
|
from discord import VoiceChannel, VoiceProtocol
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
|
|
||||||
|
|
||||||
from . import events, filters, objects
|
from . import events, filters, objects
|
||||||
from .exceptions import TrackInvalidPosition
|
from .exceptions import TrackInvalidPosition
|
||||||
from .pool import NodePool
|
from .pool import NodePool
|
||||||
|
|
@ -18,21 +19,21 @@ class Player(VoiceProtocol):
|
||||||
```
|
```
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, client: Type[discord.Client], channel: VoiceChannel):
|
def __init__(self, client: Type[commands.Bot], channel: VoiceChannel):
|
||||||
super().__init__(client=client, channel=channel)
|
super().__init__(client=client, channel=channel)
|
||||||
|
|
||||||
self.client = client
|
self.client = client
|
||||||
self.bot = client
|
self.bot = client
|
||||||
self.channel = channel
|
self.channel = channel
|
||||||
self.guild: discord.Guild = self.channel.guild
|
self._guild: discord.Guild = self.channel.guild
|
||||||
self.dj: discord.Member = None
|
self._dj: discord.Member = None
|
||||||
|
|
||||||
self.node = NodePool.get_node()
|
self._node = NodePool.get_node()
|
||||||
self.current: objects.Track = None
|
self._current: objects.Track = None
|
||||||
self.filter: filters.Filter = None
|
self._filter: filters.Filter = None
|
||||||
self.volume = 100
|
self._volume = 100
|
||||||
self.paused = False
|
self._paused = False
|
||||||
self.is_connected = False
|
self._is_connected = False
|
||||||
|
|
||||||
self._position = 0
|
self._position = 0
|
||||||
self._last_position = 0
|
self._last_position = 0
|
||||||
|
|
@ -47,10 +48,10 @@ class Player(VoiceProtocol):
|
||||||
)
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def position(self):
|
def position(self) -> float:
|
||||||
"""Property which returns the player's position in a track in milliseconds"""
|
"""Property which returns the player's position in a track in milliseconds"""
|
||||||
|
|
||||||
if not self.is_playing or not self.current:
|
if not self.is_playing or not self._current:
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
if self.is_paused:
|
if self.is_paused:
|
||||||
|
|
@ -59,25 +60,25 @@ class Player(VoiceProtocol):
|
||||||
difference = (time.time() * 1000) - self._last_update
|
difference = (time.time() * 1000) - self._last_update
|
||||||
position = self._last_position + difference
|
position = self._last_position + difference
|
||||||
|
|
||||||
if position > self.current.length:
|
if position > self._current.length:
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
return min(position, self.current.length)
|
return min(position, self._current.length)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_playing(self):
|
def is_playing(self) -> bool:
|
||||||
"""Property which returns whether or not the player is actively playing a track."""
|
"""Property which returns whether or not the player is actively playing a track."""
|
||||||
return self.is_connected and self.current is not None
|
return self._is_connected and self._current is not None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_paused(self):
|
def is_paused(self) -> bool:
|
||||||
"""Property which returns whether or not the player has a track which is paused or not."""
|
"""Property which returns whether or not the player has a track which is paused or not."""
|
||||||
return self.is_connected and self.paused
|
return self._is_connected and self._paused
|
||||||
|
|
||||||
async def _update_state(self, data: dict):
|
async def _update_state(self, data: dict):
|
||||||
state: dict = data.get("state")
|
state: dict = data.get("state")
|
||||||
self._last_update = time.time() * 1000
|
self._last_update = time.time() * 1000
|
||||||
self.is_connected = state.get("connected")
|
self._is_connected = state.get("connected")
|
||||||
self._last_position = state.get("position")
|
self._last_position = state.get("position")
|
||||||
|
|
||||||
async def _dispatch_voice_update(self, voice_data: Dict[str, Any]):
|
async def _dispatch_voice_update(self, voice_data: Dict[str, Any]):
|
||||||
|
|
@ -122,8 +123,8 @@ class Player(VoiceProtocol):
|
||||||
return await self.node.get_tracks(query, ctx)
|
return await self.node.get_tracks(query, ctx)
|
||||||
|
|
||||||
async def connect(self, *, timeout: float, reconnect: bool):
|
async def connect(self, *, timeout: float, reconnect: bool):
|
||||||
await self.guild.change_voice_state(channel=self.channel)
|
await self._guild.change_voice_state(channel=self.channel)
|
||||||
self.node._players[self.guild.id] = self
|
self._node._players[self.guild.id] = self
|
||||||
self.is_connected = True
|
self.is_connected = True
|
||||||
|
|
||||||
async def stop(self):
|
async def stop(self):
|
||||||
|
|
@ -133,24 +134,24 @@ class Player(VoiceProtocol):
|
||||||
|
|
||||||
async def disconnect(self, *, force: bool = False):
|
async def disconnect(self, *, force: bool = False):
|
||||||
await self.stop()
|
await self.stop()
|
||||||
await self.guild.change_voice_state(channel=None)
|
await self._guild.change_voice_state(channel=None)
|
||||||
self.cleanup()
|
self.cleanup()
|
||||||
self.channel = None
|
self.channel = None
|
||||||
self.is_connected = False
|
self._is_connected = False
|
||||||
del self.node._players[self.guild.id]
|
del self._node._players[self.guild.id]
|
||||||
|
|
||||||
async def destroy(self):
|
async def destroy(self):
|
||||||
"""Disconnects a player and destroys the player instance."""
|
"""Disconnects a player and destroys the player instance."""
|
||||||
await self.disconnect()
|
await self.disconnect()
|
||||||
await self.node.send(op="destroy", guildId=str(self.guild.id))
|
await self._node.send(op="destroy", guildId=str(self.guild.id))
|
||||||
|
|
||||||
async def play(self, track: objects.Track, start_position: int = 0):
|
async def play(self, track: objects.Track, start_position: int = 0) -> objects.Track:
|
||||||
"""Plays a track. If a Spotify track is passed in, it will be handled accordingly."""
|
"""Plays a track. If a Spotify track is passed in, it will be handled accordingly."""
|
||||||
if track.spotify:
|
if track.spotify:
|
||||||
spotify_track: objects.Track = (await self.node.get_tracks(
|
spotify_track: objects.Track = (await self.node.get_tracks(
|
||||||
f"ytmsearch:{track.title} {track.author}"
|
f"ytmsearch:{track.title} {track.author}"
|
||||||
))[0]
|
))[0]
|
||||||
await self.node.send(
|
await self._node.send(
|
||||||
op="play",
|
op="play",
|
||||||
guildId=str(self.guild.id),
|
guildId=str(self.guild.id),
|
||||||
track=spotify_track.track_id,
|
track=spotify_track.track_id,
|
||||||
|
|
@ -159,7 +160,7 @@ class Player(VoiceProtocol):
|
||||||
noReplace=False
|
noReplace=False
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
await self.node.send(
|
await self._node.send(
|
||||||
op="play",
|
op="play",
|
||||||
guildId=str(self.guild.id),
|
guildId=str(self.guild.id),
|
||||||
track=track.track_id,
|
track=track.track_id,
|
||||||
|
|
@ -167,10 +168,10 @@ class Player(VoiceProtocol):
|
||||||
endTime=track.length,
|
endTime=track.length,
|
||||||
noReplace=False
|
noReplace=False
|
||||||
)
|
)
|
||||||
self.current = track
|
self._current = track
|
||||||
return self.current
|
return self._current
|
||||||
|
|
||||||
async def seek(self, position: float):
|
async def seek(self, position: float) -> float:
|
||||||
"""Seeks to a position in the currently playing track milliseconds"""
|
"""Seeks to a position in the currently playing track milliseconds"""
|
||||||
|
|
||||||
if position < 0 or position > self.current.length:
|
if position < 0 or position > self.current.length:
|
||||||
|
|
@ -178,26 +179,26 @@ class Player(VoiceProtocol):
|
||||||
f"Seek position must be between 0 and the track length"
|
f"Seek position must be between 0 and the track length"
|
||||||
)
|
)
|
||||||
|
|
||||||
await self.node.send(op="seek", guildId=str(self.guild.id), position=position)
|
await self._node.send(op="seek", guildId=str(self.guild.id), position=position)
|
||||||
return self.position
|
return self._position
|
||||||
|
|
||||||
async def set_pause(self, pause: bool):
|
async def set_pause(self, pause: bool) -> bool:
|
||||||
"""Sets the pause state of the currently playing track."""
|
"""Sets the pause state of the currently playing track."""
|
||||||
await self.node.send(op="pause", guildId=str(self.guild.id), pause=pause)
|
await self._node.send(op="pause", guildId=str(self.guild.id), pause=pause)
|
||||||
self.paused = pause
|
self._paused = pause
|
||||||
return self.paused
|
return self._paused
|
||||||
|
|
||||||
async def set_volume(self, volume: int):
|
async def set_volume(self, volume: int) -> int:
|
||||||
"""Sets the volume of the player as an integer. Lavalink accepts an amount from 0 to 500."""
|
"""Sets the volume of the player as an integer. Lavalink accepts an amount from 0 to 500."""
|
||||||
await self.node.send(op="volume", guildId=str(self.guild.id), volume=volume)
|
await self._node.send(op="volume", guildId=str(self.guild.id), volume=volume)
|
||||||
self.volume = volume
|
self._volume = volume
|
||||||
return self.volume
|
return self._volume
|
||||||
|
|
||||||
async def set_filter(self, filter: filters.Filter):
|
async def set_filter(self, filter: filters.Filter) -> filters.Filter:
|
||||||
"""Sets a filter of the player. Takes a pomice.Filter object.
|
"""Sets a filter of the player. Takes a pomice.Filter object.
|
||||||
This will only work if you are using the development version of Lavalink.
|
This will only work if you are using the development version of Lavalink.
|
||||||
"""
|
"""
|
||||||
await self.node.send(op="filters", guildId=str(self.guild.id), **filter.payload)
|
await self._node.send(op="filters", guildId=str(self.guild.id), **filter.payload)
|
||||||
await self.seek(self.position)
|
await self.seek(self.position)
|
||||||
self.filter = filter
|
self._filter = filter
|
||||||
return filter
|
return filter
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue