Added new reset_filter() helper function, fixed bug with Spotify tracks not retaining thumbnails and some other QoL features

This commit is contained in:
cloudwithax 2021-12-05 16:29:01 -05:00
parent fcbca4e8e1
commit d1d2463680
8 changed files with 147 additions and 22 deletions

View File

@ -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"

View File

@ -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}>"

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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:

View File

@ -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

View File

@ -6,7 +6,7 @@ with open("README.md") as f:
setuptools.setup(
name="pomice",
author="cloudwithax",
version="1.1.5.1",
version="1.1.6",
url="https://github.com/cloudwithax/pomice",
packages=setuptools.find_packages(),
license="GPL",