added support for pitch= and tempo= to yt yts and sayen

This commit is contained in:
jenz 2024-08-06 14:42:15 +02:00
parent 2fbe20740f
commit 4b658e90d5
2 changed files with 133 additions and 111 deletions

View File

@ -10,106 +10,110 @@ from importlib import reload
from . import Commands from . import Commands
class CommandHandler(): class CommandHandler():
def __init__(self, Torchlight): def __init__(self, Torchlight):
self.Logger = logging.getLogger(__class__.__name__) self.Logger = logging.getLogger(__class__.__name__)
self.Torchlight = Torchlight self.Torchlight = Torchlight
self.Commands = [] self.Commands = []
self.NeedsReload = False self.NeedsReload = False
def Setup(self): def Setup(self):
Counter = len(self.Commands) Counter = len(self.Commands)
self.Commands.clear() self.Commands.clear()
if Counter: if Counter:
self.Logger.info(sys._getframe().f_code.co_name + " Unloaded {0} commands!".format(Counter)) self.Logger.info(sys._getframe().f_code.co_name + " Unloaded {0} commands!".format(Counter))
Counter = 0 Counter = 0
for subklass in sorted(Commands.BaseCommand.__subclasses__(), key = lambda x: x.Order, reverse = True): for subklass in sorted(Commands.BaseCommand.__subclasses__(), key = lambda x: x.Order, reverse = True):
try: try:
Command = subklass(self.Torchlight) Command = subklass(self.Torchlight)
if hasattr(Command, "_setup"): if hasattr(Command, "_setup"):
Command._setup() Command._setup()
except Exception as e: except Exception as e:
self.Logger.error(traceback.format_exc()) self.Logger.error(traceback.format_exc())
else: else:
self.Commands.append(Command) self.Commands.append(Command)
Counter += 1 Counter += 1
self.Logger.info(sys._getframe().f_code.co_name + " Loaded {0} commands!".format(Counter)) self.Logger.info(sys._getframe().f_code.co_name + " Loaded {0} commands!".format(Counter))
def Reload(self): def Reload(self):
try: try:
reload(Commands) reload(Commands)
except Exception as e: except Exception as e:
self.Logger.error(traceback.format_exc()) self.Logger.error(traceback.format_exc())
else: else:
self.Setup() self.Setup()
async def HandleCommand(self, line, player): async def HandleCommand(self, line, player):
Message = line.split(sep = ' ', maxsplit = 1) Message = line.split(sep = ' ', maxsplit = 1)
if len(Message) < 2: if len(Message) < 2:
Message.append("") Message.append("")
Message[1] = Message[1].strip() Message[1] = Message[1].strip()
if Message[1] and self.Torchlight().LastUrl: if Message[1] and self.Torchlight().LastUrl:
Message[1] = Message[1].replace("!last", self.Torchlight().LastUrl) Message[1] = Message[1].replace("!last", self.Torchlight().LastUrl)
line = Message[0] + ' ' + Message[1] line = Message[0] + ' ' + Message[1]
Level = 0 Level = 0
if player.Access: if player.Access:
Level = player.Access["level"] Level = player.Access["level"]
RetMessage = None RetMessage = None
Ret = None Ret = None
for Command in self.Commands: for Command in self.Commands:
for Trigger in Command.Triggers: for Trigger in Command.Triggers:
Match = False Match = False
RMatch = None RMatch = None
if isinstance(Trigger, tuple): if isinstance(Trigger, tuple):
if Message[0].lower().startswith(Trigger[0], 0, Trigger[1]): if Message[0].lower().startswith(Trigger[0], 0, Trigger[1]):
Match = True Match = True
elif isinstance(Trigger, str): elif isinstance(Trigger, str):
if Message[0].lower() == Trigger.lower(): if Message[0].lower() == Trigger.lower():
Match = True Match = True
else: # compiled regex else: # compiled regex
RMatch = Trigger.search(line) RMatch = Trigger.search(line)
if RMatch: if RMatch:
Match = True Match = True
if not Match: if not Match:
continue continue
self.Logger.debug(sys._getframe().f_code.co_name + " \"{0}\" Match -> {1} | {2}".format(player.Name, Command.__class__.__name__, Trigger)) self.Logger.debug(sys._getframe().f_code.co_name + " \"{0}\" Match -> {1} | {2}".format(player.Name, Command.__class__.__name__, Trigger))
if Level < Command.Level: if Level < Command.Level:
RetMessage = "You do not have access to this command! (You: {0} | Required: {1})".format(Level, Command.Level) RetMessage = "You do not have access to this command! (You: {0} | Required: {1})".format(Level, Command.Level)
continue continue
try: try:
if RMatch: if RMatch:
Ret = await Command._rfunc(line, RMatch, player) Ret = await Command._rfunc(line, RMatch, player)
else: else:
Ret = await Command._func(Message, player) #self.Logger.debug(f"_rfunc line: {line}")
except Exception as e: if line.startswith("!yt"): #transfering the line if its !yt or !yts in case people want to include pitch or tempo.
self.Logger.error(traceback.format_exc()) Ret = await Command._func(Message, player, line)
self.Torchlight().SayChat("Error: {0}".format(str(e))) else:
Ret = await Command._func(Message, player)
except Exception as e:
self.Logger.error(traceback.format_exc())
self.Torchlight().SayChat("Error: {0}".format(str(e)))
RetMessage = None RetMessage = None
if isinstance(Ret, str): if isinstance(Ret, str):
Message = Ret.split(sep = ' ', maxsplit = 1) Message = Ret.split(sep = ' ', maxsplit = 1)
Ret = None Ret = None
if Ret != None and Ret > 0: if Ret != None and Ret > 0:
break break
if Ret != None and Ret >= 0: if Ret != None and Ret >= 0:
break break
if RetMessage: if RetMessage:
self.Torchlight().SayPrivate(player, RetMessage) self.Torchlight().SayPrivate(player, RetMessage)
if self.NeedsReload: if self.NeedsReload:
self.NeedsReload = False self.NeedsReload = False
self.Reload() self.Reload()
return Ret return Ret

View File

@ -8,6 +8,28 @@ import math
from .Utils import Utils, DataHolder from .Utils import Utils, DataHolder
import traceback import traceback
def get_rubberBand(message):
rubberband = []
try:
for msg in message[1].split(" "): #checking if pitch= or tempo= is specified
if "tempo=" in msg:
tempo = float(msg.split("tempo=",1)[1])
if tempo < 0.0:
tempo = 0.01
if tempo > 20:
tempo = 20
rubberband.append(f"rubberband=tempo={tempo}")
elif "pitch=" in msg:
pitch = float(msg.split("pitch=",1)[1])
if pitch < 0.0:
pitch = 0.1
if pitch > 5.0:
pitch = 5.0
rubberband.append(f"rubberband=pitch={pitch}")
except Exception:
pass
return rubberband
class BaseCommand(): class BaseCommand():
Order = 0 Order = 0
def __init__(self, torchlight): def __init__(self, torchlight):
@ -525,25 +547,8 @@ class VoiceCommands(BaseCommand):
elif Level < 2: elif Level < 2:
return 0 return 0
rubberband = [] rubberband = get_rubberBand(message)
try:
for msg in message[1].split(" "): #checking if pitch= or tempo= is specified
if "tempo=" in msg:
tempo = float(msg.split("tempo=",1)[1])
if tempo < 0.0:
tempo = 0.01
if tempo > 20:
tempo = 20
rubberband.append(f"rubberband=tempo={tempo}")
elif "pitch=" in msg:
pitch = float(msg.split("pitch=",1)[1])
if pitch < 0.0:
pitch = 0.1
if pitch > 99:
pitch = 99
rubberband.append(f"rubberband=pitch={pitch}")
except Exception:
pass
if message[0] == "!random": if message[0] == "!random":
Trigger = self.random.choice(list(self.VoiceTriggers.values())) Trigger = self.random.choice(list(self.VoiceTriggers.values()))
if isinstance(Trigger, list): if isinstance(Trigger, list):
@ -561,6 +566,7 @@ class VoiceCommands(BaseCommand):
if isinstance(Sounds, list): if isinstance(Sounds, list):
if Num and Num > 0 and Num <= len(Sounds): if Num and Num > 0 and Num <= len(Sounds):
Sound = Sounds[Num - 1] Sound = Sounds[Num - 1]
elif message[1] and not message[1].startswith("tempo=") and not message[1].startswith("pitch="): #it does not start with pitch or with tempo, so must be a number or alias. elif message[1] and not message[1].startswith("tempo=") and not message[1].startswith("pitch="): #it does not start with pitch or with tempo, so must be a number or alias.
searching = message[1].startswith('?') searching = message[1].startswith('?')
search = message[1][1:] if searching else message[1].split(" ")[0] search = message[1][1:] if searching else message[1].split(" ")[0]
@ -617,7 +623,7 @@ class YouTube(BaseCommand):
self.Triggers = ["!yt"] self.Triggers = ["!yt"]
self.Level = 6 self.Level = 6
async def _func(self, message, player): async def _func(self, message, player, line = None):
self.Logger.debug(sys._getframe().f_code.co_name + ' ' + str(message)) self.Logger.debug(sys._getframe().f_code.co_name + ' ' + str(message))
if self.check_disabled(player): if self.check_disabled(player):
@ -637,8 +643,11 @@ class YouTube(BaseCommand):
AudioClip = self.Torchlight().AudioManager.AudioClip(player, message[1]) AudioClip = self.Torchlight().AudioManager.AudioClip(player, message[1])
if not AudioClip: if not AudioClip:
return 1 return 1
return AudioClip.Play(Time) #turning the string into a list where get_rubberband just picks the second element to search in
dline = ['', line.split(" ", 1)[1]]
rubberband = get_rubberBand(dline)
return AudioClip.Play(Time, rubberband = rubberband)
class YouTubeSearch(BaseCommand): class YouTubeSearch(BaseCommand):
import json import json
@ -648,7 +657,7 @@ class YouTubeSearch(BaseCommand):
self.Triggers = ["!yts"] self.Triggers = ["!yts"]
self.Level = 6 #adjusting to new levels self.Level = 6 #adjusting to new levels
async def _func(self, message, player): async def _func(self, message, player, line = None):
self.Logger.debug(sys._getframe().f_code.co_name + ' ' + str(message)) self.Logger.debug(sys._getframe().f_code.co_name + ' ' + str(message))
if self.check_disabled(player): if self.check_disabled(player):
@ -663,7 +672,8 @@ class YouTubeSearch(BaseCommand):
Time = Utils.ParseTime(TimeStr) Time = Utils.ParseTime(TimeStr)
message[1] = message[1][:Temp.value] message[1] = message[1][:Temp.value]
Proc = await asyncio.create_subprocess_exec("yt-dlp", "--dump-json", "--username", "oauth2", "--password", "''", "-xg", "ytsearch:" + message[1], search_term = message[1].split("pitch=")[0].split("tempo=")[0]
Proc = await asyncio.create_subprocess_exec("yt-dlp", "--dump-json", "--username", "oauth2", "--password", "''", "-xg", "ytsearch:" + search_term,
stdout = asyncio.subprocess.PIPE) stdout = asyncio.subprocess.PIPE)
Out, _ = await Proc.communicate() Out, _ = await Proc.communicate()
@ -679,7 +689,11 @@ class YouTubeSearch(BaseCommand):
if not AudioClip: if not AudioClip:
return 1 return 1
self.Torchlight().LastUrl = url self.Torchlight().LastUrl = url
return AudioClip.Play(Time)
#turning the string into a list where get_rubberband just picks the second element to search in
dline = ['', line.split(" ", 1)[1]]
rubberband = get_rubberBand(dline)
return AudioClip.Play(Time, rubberband = rubberband)
class Say(BaseCommand): class Say(BaseCommand):
@ -692,7 +706,8 @@ class Say(BaseCommand):
self.Level = 2 self.Level = 2
async def Say(self, player, language, message): async def Say(self, player, language, message):
GTTS = self.gtts.gTTS(text = message, lang = language) actual_message = message.split("pitch=")[0].split("tempo=")[0]
GTTS = self.gtts.gTTS(text = actual_message, lang = language)
TempFile = self.tempfile.NamedTemporaryFile(delete = False) TempFile = self.tempfile.NamedTemporaryFile(delete = False)
GTTS.write_to_fp(TempFile) GTTS.write_to_fp(TempFile)
@ -702,8 +717,11 @@ class Say(BaseCommand):
if not AudioClip: if not AudioClip:
os.unlink(TempFile.name) os.unlink(TempFile.name)
return 1 return 1
#turning the string into a list where get_rubberband just picks the second element to search in
dline = ['', message.split(" ", 1)[1]]
rubberband = get_rubberBand(dline)
if AudioClip.Play(): if AudioClip.Play(rubberband = rubberband):
AudioClip.AudioPlayer.AddCallback("Stop", lambda: os.unlink(TempFile.name)) AudioClip.AudioPlayer.AddCallback("Stop", lambda: os.unlink(TempFile.name))
return 0 return 0
else: else: