Added new reset_filter() helper function, fixed bug with Spotify tracks not retaining thumbnails and some other QoL features
This commit is contained in:
parent
fcbca4e8e1
commit
d1d2463680
|
|
@ -11,7 +11,7 @@ if discord.__version__ != "2.0.0a":
|
|||
"using 'pip install git+https://github.com/Rapptz/discord.py@master'"
|
||||
)
|
||||
|
||||
__version__ = "1.1.5.1"
|
||||
__version__ = "1.1.6"
|
||||
__title__ = "pomice"
|
||||
__author__ = "cloudwithax"
|
||||
|
||||
|
|
|
|||
|
|
@ -37,6 +37,16 @@ class Equalizer(Filter):
|
|||
|
||||
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.payload = {"equalizer": self.eq}
|
||||
|
||||
return self.payload
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"<Pomice.EqualizerFilter eq={self.eq} raw={self.raw}>"
|
||||
|
||||
|
|
@ -72,6 +82,18 @@ class Timescale(Filter):
|
|||
"pitch": self.pitch,
|
||||
"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):
|
||||
return f"<Pomice.TimescaleFilter speed={self.speed} pitch={self.pitch} rate={self.rate}>"
|
||||
|
||||
|
|
@ -101,6 +123,20 @@ class Karaoke(Filter):
|
|||
"filterBand": self.filter_band,
|
||||
"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):
|
||||
return (
|
||||
f"<Pomice.KaraokeFilter level={self.level} mono_level={self.mono_level} "
|
||||
|
|
@ -134,6 +170,16 @@ class Tremolo(Filter):
|
|||
self.payload = {"tremolo": {"frequency": self.frequency,
|
||||
"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):
|
||||
return f"<Pomice.TremoloFilter frequency={self.frequency} depth={self.depth}>"
|
||||
|
||||
|
|
@ -164,6 +210,15 @@ class Vibrato(Filter):
|
|||
self.payload = {"vibrato": {"frequency": self.frequency,
|
||||
"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):
|
||||
return f"<Pomice.VibratoFilter frequency={self.frequency} depth={self.depth}>"
|
||||
|
||||
|
|
@ -179,6 +234,12 @@ class Rotation(Filter):
|
|||
self.rotation_hertz = 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:
|
||||
return f"<Pomice.RotationFilter rotation_hertz={self.rotation_hertz}>"
|
||||
|
||||
|
|
@ -222,6 +283,20 @@ class ChannelMix(Filter):
|
|||
"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:
|
||||
return (
|
||||
f"<Pomice.ChannelMix left_to_left={self.left_to_left} left_to_right={self.left_to_right} "
|
||||
|
|
@ -267,6 +342,30 @@ class Distortion(Filter):
|
|||
"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:
|
||||
return (
|
||||
f"<Pomice.Distortion sin_offset={self.sin_offset} sin_scale={self.sin_scale}> "
|
||||
|
|
@ -286,6 +385,12 @@ class LowPass(Filter):
|
|||
self.smoothing = 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:
|
||||
return f"<Pomice.LowPass smoothing={self.smoothing}>"
|
||||
|
||||
|
|
|
|||
|
|
@ -37,15 +37,16 @@ class Track:
|
|||
self.author = info.get("author")
|
||||
self.uri = info.get("uri")
|
||||
self.identifier = info.get("identifier")
|
||||
|
||||
if info.get("thumbnail"):
|
||||
self.thumbnail = info.get("thumbnail")
|
||||
else:
|
||||
if SOUNDCLOUD_URL_REGEX.match(self.uri):
|
||||
elif SOUNDCLOUD_URL_REGEX.match(self.uri):
|
||||
# ok so theres no feasible way of getting a Soundcloud image URL
|
||||
# so we're just gonna leave it blank for brevity
|
||||
self.thumbnail = None
|
||||
else:
|
||||
self.thumbnail = f"https://img.youtube.com/vi/{self.identifier}/mqdefault.jpg"
|
||||
|
||||
self.length = info.get("length")
|
||||
self.ctx = ctx
|
||||
self.requester = self.ctx.author if ctx else None
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ from discord.ext import commands
|
|||
from . import events
|
||||
from .enums import SearchType
|
||||
from .events import PomiceEvent, TrackEndEvent, TrackStartEvent
|
||||
from .exceptions import TrackInvalidPosition
|
||||
from .exceptions import FilterInvalidArgument, TrackInvalidPosition
|
||||
from .filters import Filter
|
||||
from .objects import Track
|
||||
from .pool import Node, NodePool
|
||||
|
|
@ -279,7 +279,7 @@ class Player(VoiceProtocol):
|
|||
"""Seeks to a position in the currently playing track milliseconds"""
|
||||
if position < 0 or position > self._current.original.length:
|
||||
raise TrackInvalidPosition(
|
||||
f"Seek position must be between 0 and the track length"
|
||||
"Seek position must be between 0 and the track length"
|
||||
)
|
||||
|
||||
await self._node.send(op="seek", guildId=str(self.guild.id), position=position)
|
||||
|
|
@ -299,9 +299,29 @@ class Player(VoiceProtocol):
|
|||
|
||||
async def set_filter(self, filter: Filter) -> Filter:
|
||||
"""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 a version of Lavalink that supports filters.
|
||||
"""
|
||||
await self._node.send(op="filters", guildId=str(self.guild.id), **filter.payload)
|
||||
await self.seek(self.position)
|
||||
self._filter = filter
|
||||
return filter
|
||||
|
||||
async def reset_filter(self):
|
||||
"""Resets a currently applied filter to its default parameters.
|
||||
You must have a filter applied in order for this to work
|
||||
"""
|
||||
|
||||
if not self._filter:
|
||||
raise FilterInvalidArgument(
|
||||
"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), **_payload)
|
||||
await self.seek(self.position)
|
||||
self._filter = None
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ import json
|
|||
import random
|
||||
import re
|
||||
import time
|
||||
import socket
|
||||
from typing import Dict, Optional, TYPE_CHECKING
|
||||
from urllib.parse import quote
|
||||
from enum import Enum
|
||||
|
|
@ -194,7 +193,6 @@ class Node:
|
|||
if msg.type == aiohttp.WSMsgType.CLOSED:
|
||||
retry = backoff.delay()
|
||||
await asyncio.sleep(retry)
|
||||
|
||||
if not self.is_connected:
|
||||
self._bot.loop.create_task(self.connect())
|
||||
else:
|
||||
|
|
@ -220,7 +218,7 @@ class Node:
|
|||
async def send(self, **data):
|
||||
if not self._available:
|
||||
raise NodeNotAvailable(
|
||||
f"The node '{self.identifier}' is unavailable."
|
||||
f"The node '{self._identifier}' is unavailable."
|
||||
)
|
||||
|
||||
await self._websocket.send_str(json.dumps(data))
|
||||
|
|
@ -240,6 +238,11 @@ class Node:
|
|||
self._task = self._bot.loop.create_task(self._listen())
|
||||
self._available = True
|
||||
return self
|
||||
|
||||
except aiohttp.ClientConnectorError:
|
||||
raise NodeConnectionFailure(
|
||||
f"The connection to node '{self._identifier}' failed."
|
||||
)
|
||||
except aiohttp.WSServerHandshakeError:
|
||||
raise NodeConnectionFailure(
|
||||
f"The password for node '{self._identifier}' is invalid."
|
||||
|
|
@ -248,10 +251,6 @@ class Node:
|
|||
raise NodeConnectionFailure(
|
||||
f"The URI for node '{self._identifier}' is invalid."
|
||||
)
|
||||
except socket.gaierror:
|
||||
raise NodeConnectionFailure(
|
||||
f"The node '{self._identifier}' failed to connect."
|
||||
)
|
||||
|
||||
async def disconnect(self):
|
||||
"""Disconnects a connected Lavalink node and removes it from the node pool.
|
||||
|
|
|
|||
|
|
@ -7,10 +7,10 @@ class Album:
|
|||
def __init__(self, data: dict) -> None:
|
||||
self.name = data["name"]
|
||||
self.artists = ", ".join(artist["name"] for artist in data["artists"])
|
||||
self.tracks = [Track(track) for track in data["tracks"]["items"]]
|
||||
self.image = data["images"][0]["url"]
|
||||
self.tracks = [Track(track, image=self.image) for track in data["tracks"]["items"]]
|
||||
self.total_tracks = data["total_tracks"]
|
||||
self.id = data["id"]
|
||||
self.image = data["images"][0]["url"]
|
||||
self.uri = data["external_urls"]["spotify"]
|
||||
|
||||
def __repr__(self) -> str:
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
class Track:
|
||||
"""The base class for a Spotify Track"""
|
||||
|
||||
def __init__(self, data: dict) -> None:
|
||||
def __init__(self, data: dict, image = None) -> None:
|
||||
self.name = data["name"]
|
||||
self.artists = ", ".join(artist["name"] for artist in data["artists"])
|
||||
self.length = data["duration_ms"]
|
||||
|
|
@ -10,7 +10,7 @@ class Track:
|
|||
if data.get("album") and data["album"].get("images"):
|
||||
self.image = data["album"]["images"][0]["url"]
|
||||
else:
|
||||
self.image = None
|
||||
self.image = image
|
||||
|
||||
if data["is_local"]:
|
||||
self.uri = None
|
||||
|
|
|
|||
Loading…
Reference in New Issue