Merge branch 'main' into spotify
This commit is contained in:
commit
825db56fc5
|
|
@ -18,7 +18,7 @@ if not discord.__version__.startswith("2.0"):
|
||||||
"Uninstall your current version and install discord.py 2.0 or a compatible fork."
|
"Uninstall your current version and install discord.py 2.0 or a compatible fork."
|
||||||
)
|
)
|
||||||
|
|
||||||
__version__ = "1.1.6"
|
__version__ = "1.1.7"
|
||||||
__title__ = "pomice"
|
__title__ = "pomice"
|
||||||
__author__ = "cloudwithax"
|
__author__ = "cloudwithax"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -37,11 +37,6 @@ class Equalizer(Filter):
|
||||||
|
|
||||||
return _dict
|
return _dict
|
||||||
|
|
||||||
def _reset(self):
|
|
||||||
self.raw = [(0, .0), (1, .0), (2, .0), (3, .0), (4, .0),
|
|
||||||
(5, .0), (6, .0), (7, .0), (8, .0), (9, .0),
|
|
||||||
(10, .0), (11, .0), (12, .0), (13, .0), (14, .0)]
|
|
||||||
|
|
||||||
self.eq = self._factory(levels=self.raw)
|
self.eq = self._factory(levels=self.raw)
|
||||||
self.payload = {"equalizer": self.eq}
|
self.payload = {"equalizer": self.eq}
|
||||||
|
|
||||||
|
|
@ -82,18 +77,6 @@ class Timescale(Filter):
|
||||||
"pitch": self.pitch,
|
"pitch": self.pitch,
|
||||||
"rate": self.rate}}
|
"rate": self.rate}}
|
||||||
|
|
||||||
def _reset(self):
|
|
||||||
self.speed = 1.0
|
|
||||||
self.pitch = 1.0
|
|
||||||
self.rate = 1.0
|
|
||||||
|
|
||||||
self.payload = {"timescale": {"speed": self.speed,
|
|
||||||
"pitch": self.pitch,
|
|
||||||
"rate": self.rate}}
|
|
||||||
|
|
||||||
return self.payload
|
|
||||||
|
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f"<Pomice.TimescaleFilter speed={self.speed} pitch={self.pitch} rate={self.rate}>"
|
return f"<Pomice.TimescaleFilter speed={self.speed} pitch={self.pitch} rate={self.rate}>"
|
||||||
|
|
||||||
|
|
@ -123,20 +106,6 @@ class Karaoke(Filter):
|
||||||
"filterBand": self.filter_band,
|
"filterBand": self.filter_band,
|
||||||
"filterWidth": self.filter_width}}
|
"filterWidth": self.filter_width}}
|
||||||
|
|
||||||
def _reset(self):
|
|
||||||
self.level: float = 1.0
|
|
||||||
self.mono_level: float = 1.0
|
|
||||||
self.filter_band: float = 220.0
|
|
||||||
self.filter_width: float = 100.0
|
|
||||||
|
|
||||||
self.payload = {"karaoke": {"level": self.level,
|
|
||||||
"monoLevel": self.mono_level,
|
|
||||||
"filterBand": self.filter_band,
|
|
||||||
"filterWidth": self.filter_width}}
|
|
||||||
|
|
||||||
|
|
||||||
return self.payload
|
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return (
|
return (
|
||||||
f"<Pomice.KaraokeFilter level={self.level} mono_level={self.mono_level} "
|
f"<Pomice.KaraokeFilter level={self.level} mono_level={self.mono_level} "
|
||||||
|
|
@ -170,16 +139,6 @@ class Tremolo(Filter):
|
||||||
self.payload = {"tremolo": {"frequency": self.frequency,
|
self.payload = {"tremolo": {"frequency": self.frequency,
|
||||||
"depth": self.depth}}
|
"depth": self.depth}}
|
||||||
|
|
||||||
def _reset(self):
|
|
||||||
self.frequency: float = 2.0
|
|
||||||
self.depth: float = 0.5
|
|
||||||
|
|
||||||
self.payload = {"tremolo": {"frequency": self.frequency,
|
|
||||||
"depth": self.depth}}
|
|
||||||
|
|
||||||
|
|
||||||
return self.payload
|
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f"<Pomice.TremoloFilter frequency={self.frequency} depth={self.depth}>"
|
return f"<Pomice.TremoloFilter frequency={self.frequency} depth={self.depth}>"
|
||||||
|
|
||||||
|
|
@ -210,15 +169,6 @@ class Vibrato(Filter):
|
||||||
self.payload = {"vibrato": {"frequency": self.frequency,
|
self.payload = {"vibrato": {"frequency": self.frequency,
|
||||||
"depth": self.depth}}
|
"depth": self.depth}}
|
||||||
|
|
||||||
def _reset(self):
|
|
||||||
self.frequency: float = 2.0
|
|
||||||
self.depth: float = 0.5
|
|
||||||
|
|
||||||
self.payload = {"vibrato": {"frequency": self.frequency,
|
|
||||||
"depth": self.depth}}
|
|
||||||
|
|
||||||
return self.payload
|
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f"<Pomice.VibratoFilter frequency={self.frequency} depth={self.depth}>"
|
return f"<Pomice.VibratoFilter frequency={self.frequency} depth={self.depth}>"
|
||||||
|
|
||||||
|
|
@ -234,12 +184,6 @@ class Rotation(Filter):
|
||||||
self.rotation_hertz = rotation_hertz
|
self.rotation_hertz = rotation_hertz
|
||||||
self.payload = {"rotation": {"rotationHz": self.rotation_hertz}}
|
self.payload = {"rotation": {"rotationHz": self.rotation_hertz}}
|
||||||
|
|
||||||
def _reset(self):
|
|
||||||
self.rotation_hertz = 5
|
|
||||||
self.payload = {"rotation": {"rotationHz": self.rotation_hertz}}
|
|
||||||
|
|
||||||
return self.payload
|
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
return f"<Pomice.RotationFilter rotation_hertz={self.rotation_hertz}>"
|
return f"<Pomice.RotationFilter rotation_hertz={self.rotation_hertz}>"
|
||||||
|
|
||||||
|
|
@ -283,19 +227,6 @@ class ChannelMix(Filter):
|
||||||
"rightToRight": self.right_to_right}
|
"rightToRight": self.right_to_right}
|
||||||
}
|
}
|
||||||
|
|
||||||
def _reset(self):
|
|
||||||
self.left_to_left: float = 1
|
|
||||||
self.right_to_right: float = 1
|
|
||||||
self.left_to_right: float = 0
|
|
||||||
self.right_to_left: float = 0
|
|
||||||
|
|
||||||
self.payload = {"channelMix": {"leftToLeft": self.left_to_left,
|
|
||||||
"leftToRight": self.left_to_right,
|
|
||||||
"rightToLeft": self.right_to_left,
|
|
||||||
"rightToRight": self.right_to_right}
|
|
||||||
}
|
|
||||||
|
|
||||||
return self.payload
|
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
return (
|
return (
|
||||||
|
|
@ -342,30 +273,6 @@ class Distortion(Filter):
|
||||||
"scale": self.scale
|
"scale": self.scale
|
||||||
}}
|
}}
|
||||||
|
|
||||||
def _reset(self):
|
|
||||||
self.sin_offset: float = 0
|
|
||||||
self.sin_scale: float = 1
|
|
||||||
self.cos_offset: float = 0
|
|
||||||
self.cos_scale: float = 1
|
|
||||||
self.tan_offset: float = 0
|
|
||||||
self.tan_scale: float = 1
|
|
||||||
self.offset: float = 0
|
|
||||||
self.scale: float = 1
|
|
||||||
|
|
||||||
self.payload = {"distortion": {
|
|
||||||
"sinOffset": self.sin_offset,
|
|
||||||
"sinScale": self.sin_scale,
|
|
||||||
"cosOffset": self.cos_offset,
|
|
||||||
"cosScale": self.cos_scale,
|
|
||||||
"tanOffset": self.tan_offset,
|
|
||||||
"tanScale": self.tan_scale,
|
|
||||||
"offset": self.offset,
|
|
||||||
"scale": self.scale
|
|
||||||
}}
|
|
||||||
|
|
||||||
return self.payload
|
|
||||||
|
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
return (
|
return (
|
||||||
f"<Pomice.Distortion sin_offset={self.sin_offset} sin_scale={self.sin_scale}> "
|
f"<Pomice.Distortion sin_offset={self.sin_offset} sin_scale={self.sin_scale}> "
|
||||||
|
|
@ -385,12 +292,6 @@ class LowPass(Filter):
|
||||||
self.smoothing = smoothing
|
self.smoothing = smoothing
|
||||||
self.payload = {"lowPass": {"smoothing": self.smoothing}}
|
self.payload = {"lowPass": {"smoothing": self.smoothing}}
|
||||||
|
|
||||||
def _reset(self):
|
|
||||||
self.smoothing = 20
|
|
||||||
self.payload = {"lowPass": {"smoothing": self.smoothing}}
|
|
||||||
|
|
||||||
return self.payload
|
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
return f"<Pomice.LowPass smoothing={self.smoothing}>"
|
return f"<Pomice.LowPass smoothing={self.smoothing}>"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@ class Track:
|
||||||
self.author = info.get("author")
|
self.author = info.get("author")
|
||||||
self.uri = info.get("uri")
|
self.uri = info.get("uri")
|
||||||
self.identifier = info.get("identifier")
|
self.identifier = info.get("identifier")
|
||||||
|
self.isrc = info.get("isrc")
|
||||||
|
|
||||||
if info.get("thumbnail"):
|
if info.get("thumbnail"):
|
||||||
self.thumbnail = info.get("thumbnail")
|
self.thumbnail = info.get("thumbnail")
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ from discord.ext import commands
|
||||||
from . import events
|
from . import events
|
||||||
from .enums import SearchType
|
from .enums import SearchType
|
||||||
from .events import PomiceEvent, TrackEndEvent, TrackStartEvent
|
from .events import PomiceEvent, TrackEndEvent, TrackStartEvent
|
||||||
from .exceptions import FilterInvalidArgument, TrackInvalidPosition
|
from .exceptions import FilterInvalidArgument, TrackInvalidPosition, TrackLoadError
|
||||||
from .filters import Filter
|
from .filters import Filter
|
||||||
from .objects import Track
|
from .objects import Track
|
||||||
from .pool import Node, NodePool
|
from .pool import Node, NodePool
|
||||||
|
|
@ -247,9 +247,11 @@ class Player(VoiceProtocol):
|
||||||
"""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:
|
||||||
search: Track = (await self._node.get_tracks(
|
search: Track = (await self._node.get_tracks(
|
||||||
f"{track._search_type}:{track.author} - {track.title}",
|
f"{track._search_type}:{track.title} - {track.author}", ctx=track.ctx))[0]
|
||||||
ctx=track.ctx
|
if not search:
|
||||||
))[0]
|
raise TrackLoadError (
|
||||||
|
"No equivalent track was able to be found."
|
||||||
|
)
|
||||||
track.original = search
|
track.original = search
|
||||||
|
|
||||||
data = {
|
data = {
|
||||||
|
|
@ -298,16 +300,18 @@ class Player(VoiceProtocol):
|
||||||
self._volume = volume
|
self._volume = volume
|
||||||
return self._volume
|
return self._volume
|
||||||
|
|
||||||
async def set_filter(self, filter: Filter) -> Filter:
|
async def set_filter(self, filter: Filter, fast_apply=False) -> 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 a version of Lavalink that supports filters.
|
This will only work if you are using a version of Lavalink that supports filters.
|
||||||
|
If you would like for the filter to apply instantly, set the `fast_apply` arg to `True`.
|
||||||
"""
|
"""
|
||||||
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)
|
||||||
|
if fast_apply:
|
||||||
await self.seek(self.position)
|
await self.seek(self.position)
|
||||||
self._filter = filter
|
self._filter = filter
|
||||||
return filter
|
return filter
|
||||||
|
|
||||||
async def reset_filter(self):
|
async def reset_filter(self, fast_apply=False):
|
||||||
"""Resets a currently applied filter to its default parameters.
|
"""Resets a currently applied filter to its default parameters.
|
||||||
You must have a filter applied in order for this to work
|
You must have a filter applied in order for this to work
|
||||||
"""
|
"""
|
||||||
|
|
@ -317,8 +321,8 @@ class Player(VoiceProtocol):
|
||||||
"You must have a filter applied first in order to use this method."
|
"You must have a filter applied first in order to use this method."
|
||||||
)
|
)
|
||||||
|
|
||||||
_payload: dict = self._filter._reset()
|
await self._node.send(op="filters", guildId=str(self.guild.id))
|
||||||
await self._node.send(op="filters", guildId=str(self.guild.id), **_payload)
|
if fast_apply:
|
||||||
await self.seek(self.position)
|
await self.seek(self.position)
|
||||||
self._filter = None
|
self._filter = None
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,6 @@ class Node:
|
||||||
identifier: str,
|
identifier: str,
|
||||||
secure: bool = False,
|
secure: bool = False,
|
||||||
heartbeat: int = 30,
|
heartbeat: int = 30,
|
||||||
region: Optional[str] = None,
|
|
||||||
session: Optional[aiohttp.ClientSession] = None,
|
session: Optional[aiohttp.ClientSession] = None,
|
||||||
spotify_client_id: Optional[str] = None,
|
spotify_client_id: Optional[str] = None,
|
||||||
spotify_client_secret: Optional[str] = None,
|
spotify_client_secret: Optional[str] = None,
|
||||||
|
|
@ -79,7 +78,6 @@ class Node:
|
||||||
self._identifier = identifier
|
self._identifier = identifier
|
||||||
self._heartbeat = heartbeat
|
self._heartbeat = heartbeat
|
||||||
self._secure = secure
|
self._secure = secure
|
||||||
self._region: Optional[str] = region
|
|
||||||
|
|
||||||
|
|
||||||
self._websocket_uri = f"{'wss' if self._secure else 'ws'}://{self._host}:{self._port}"
|
self._websocket_uri = f"{'wss' if self._secure else 'ws'}://{self._host}:{self._port}"
|
||||||
|
|
@ -133,11 +131,6 @@ class Node:
|
||||||
"""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
|
|
||||||
def region(self) -> Optional[str]:
|
|
||||||
"""Property which returns the VoiceRegion of the node, if one is set"""
|
|
||||||
return self._region
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def bot(self) -> Client:
|
def bot(self) -> Client:
|
||||||
"""Property which returns the discord.py client linked to this node"""
|
"""Property which returns the discord.py client linked to this node"""
|
||||||
|
|
@ -336,7 +329,8 @@ class Node:
|
||||||
"isStream": False,
|
"isStream": False,
|
||||||
"isSeekable": True,
|
"isSeekable": True,
|
||||||
"position": 0,
|
"position": 0,
|
||||||
"thumbnail": spotify_results.image
|
"thumbnail": spotify_results.image,
|
||||||
|
"isrc": spotify_results.isrc
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
@ -357,7 +351,8 @@ class Node:
|
||||||
"isStream": False,
|
"isStream": False,
|
||||||
"isSeekable": True,
|
"isSeekable": True,
|
||||||
"position": 0,
|
"position": 0,
|
||||||
"thumbnail": track.image
|
"thumbnail": track.image,
|
||||||
|
"isrc": track.isrc
|
||||||
}
|
}
|
||||||
) for track in spotify_results.tracks
|
) for track in spotify_results.tracks
|
||||||
]
|
]
|
||||||
|
|
@ -455,7 +450,7 @@ class NodePool:
|
||||||
return len(self._nodes.values())
|
return len(self._nodes.values())
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_best_node(cls, *, algorithm: NodeAlgorithm, voice_region: str = None) -> Node:
|
def get_best_node(cls, *, algorithm: NodeAlgorithm) -> Node:
|
||||||
"""Fetches the best node based on an NodeAlgorithm.
|
"""Fetches the best node based on an NodeAlgorithm.
|
||||||
This option is preferred if you want to choose the best node
|
This option is preferred if you want to choose the best node
|
||||||
from a multi-node setup using either the node's latency
|
from a multi-node setup using either the node's latency
|
||||||
|
|
@ -485,18 +480,6 @@ class NodePool:
|
||||||
tested_nodes = {node: len(node.players.keys()) for node in available_nodes}
|
tested_nodes = {node: len(node.players.keys()) for node in available_nodes}
|
||||||
return min(tested_nodes, key=tested_nodes.get)
|
return min(tested_nodes, key=tested_nodes.get)
|
||||||
|
|
||||||
else:
|
|
||||||
if voice_region == None:
|
|
||||||
raise NodeException("You must specify a VoiceRegion in order to use this functionality.")
|
|
||||||
|
|
||||||
nodes = [node for node in available_nodes if node._region == voice_region]
|
|
||||||
if not nodes:
|
|
||||||
raise NoNodesAvailable(
|
|
||||||
f"No nodes for region {voice_region} exist in this pool."
|
|
||||||
)
|
|
||||||
|
|
||||||
return nodes[0]
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_node(cls, *, identifier: str = None) -> Node:
|
def get_node(cls, *, identifier: str = None) -> Node:
|
||||||
"""Fetches a node from the node pool using it's identifier.
|
"""Fetches a node from the node pool using it's identifier.
|
||||||
|
|
@ -526,7 +509,6 @@ class NodePool:
|
||||||
identifier: str,
|
identifier: str,
|
||||||
secure: bool = False,
|
secure: bool = False,
|
||||||
heartbeat: int = 30,
|
heartbeat: int = 30,
|
||||||
region: Optional[str] = None,
|
|
||||||
spotify_client_id: Optional[str] = None,
|
spotify_client_id: Optional[str] = None,
|
||||||
spotify_client_secret: Optional[str] = None,
|
spotify_client_secret: Optional[str] = None,
|
||||||
session: Optional[aiohttp.ClientSession] = None,
|
session: Optional[aiohttp.ClientSession] = None,
|
||||||
|
|
@ -541,7 +523,7 @@ class NodePool:
|
||||||
node = Node(
|
node = Node(
|
||||||
pool=cls, bot=bot, host=host, port=port, password=password,
|
pool=cls, bot=bot, host=host, port=port, password=password,
|
||||||
identifier=identifier, secure=secure, heartbeat=heartbeat,
|
identifier=identifier, secure=secure, heartbeat=heartbeat,
|
||||||
region=region, spotify_client_id=spotify_client_id,
|
spotify_client_id=spotify_client_id,
|
||||||
session=session, spotify_client_secret=spotify_client_secret
|
session=session, spotify_client_secret=spotify_client_secret
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ class Track:
|
||||||
self.artists = ", ".join(artist["name"] for artist in data["artists"])
|
self.artists = ", ".join(artist["name"] for artist in data["artists"])
|
||||||
self.length = data["duration_ms"]
|
self.length = data["duration_ms"]
|
||||||
self.id = data["id"]
|
self.id = data["id"]
|
||||||
|
self.isrc = data["external_ids"]["isrc"]
|
||||||
|
|
||||||
if data.get("album") and data["album"].get("images"):
|
if data.get("album") and data["album"].get("images"):
|
||||||
self.image = data["album"]["images"][0]["url"]
|
self.image = data["album"]["images"][0]["url"]
|
||||||
|
|
@ -20,5 +21,5 @@ class Track:
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
return (
|
return (
|
||||||
f"<Pomice.spotify.Track name={self.name} artists={self.artists} "
|
f"<Pomice.spotify.Track name={self.name} artists={self.artists} "
|
||||||
f"length={self.length} id={self.id}>"
|
f"length={self.length} id={self.id} isrc={self.isrc}>"
|
||||||
)
|
)
|
||||||
|
|
|
||||||
2
setup.py
2
setup.py
|
|
@ -6,7 +6,7 @@ with open("README.md") as f:
|
||||||
setuptools.setup(
|
setuptools.setup(
|
||||||
name="pomice",
|
name="pomice",
|
||||||
author="cloudwithax",
|
author="cloudwithax",
|
||||||
version="1.1.6.1",
|
version="1.1.7",
|
||||||
url="https://github.com/cloudwithax/pomice",
|
url="https://github.com/cloudwithax/pomice",
|
||||||
packages=setuptools.find_packages(),
|
packages=setuptools.find_packages(),
|
||||||
license="GPL",
|
license="GPL",
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue