From 0f22f1253cfcfa594abc411a494e57fad10238db Mon Sep 17 00:00:00 2001 From: aliasless Date: Sat, 11 Apr 2020 02:51:42 +0000 Subject: [PATCH] queue --- ticker.py | 121 +++++++++++++++++++++++++++++++++++------------------- 1 file changed, 79 insertions(+), 42 deletions(-) diff --git a/ticker.py b/ticker.py index cf05f49..0d01ef3 100644 --- a/ticker.py +++ b/ticker.py @@ -8,79 +8,116 @@ import asyncio import hashlib import os.path -ROOT = "/home/bot/ticker" +ROOT = "/home/bot/wife" SEGUIS = 665399296522321942 -GOONS = 369294266905657345 -RETARD_DIMENSION = 695090043609415740 MATT = 150791815723876352 client = discord.Client() -s = AsyncIOScheduler(event_loop = client.loop) c = CurrencyRates() +ticker_queue = asyncio.Queue() + +# returns a file path from the cache +def to_tts(message, lang = 'ja'): + # the file we save to is based on the hash of the message + message_hash = hashlib.md5(message.encode('utf-8')).hexdigest() + file_name = ROOT + "/cache/" + message_hash + ".mp3" + + # if the hash matches and existing file, well... + if not os.path.isfile(file_name): + print("file does not exist, cacheing") + tts = gTTS(message, lang = lang) + tts.save(file_name) + + return file_name + +# coroutine responsible for handling the queue as events come in +async def ticker_update(): + while True: + # blocks until there is a message in the queue + announce_file, target_voice_channel = await ticker_queue.get() + print("ticker event has been removed from queue") + + # there are three scenarios here + # 1. we are not connected to a voice channel. we should CONNECT to the target voice channel + # 2. we are connected to the wrong channel. we should MOVE to the target channel + # 3. we are already in the correct channel. we should do nothing + + guild = target_voice_channel.guild # the guild this ticker event is for + voice_client = guild.voice_client # the voice client for this guild, may be None + + # there is no connection, nor an existing voice client + if not voice_client: + voice_client = await target_voice_channel.connect() + + # there is a voice client, but there is no connection + if not voice_client.is_connected(): + voice_client = await target_voice_channel.connect() + + if not target_voice_channel.id == voice_client.channel.id: + await voice_client.move_to(target_voice_channel.id) + + # load and play supplied message + source = discord.FFmpegOpusAudio(announce_file) + voice_client.play(source) + + # block while the message is playing + while voice_client.is_playing(): + await asyncio.sleep(0.1) + + # once all ticker events have completed, dc + if ticker_queue.empty(): + await voice_client.disconnect() + @client.event async def on_ready(): print(client.user.name) -async def say(filename, channel): - source = discord.FFmpegOpusAudio(filename) - voice_client = await channel.connect() - voice_client.play(source) +@client.event +async def on_voice_state_update(member, before, after): + # only run on moves + if before.channel and after.channel: + # moves to the afk channel + if after.channel.id == member.guild.afk_channel.id: + filename = to_tts(member.display_name + "はretard dimensionに移動しました") + await ticker_queue.put((filename, before.channel)) + print("ticker event has been added to queue") - while voice_client.is_playing(): - await asyncio.sleep(0.1) - await voice_client.disconnect() +client.loop.create_task(ticker_update()) - print(filename + " played at " + str(datetime.now())) - -def update(trigger, guild_id): +def update(guild_id): def decorator(func): async def wrapper(): filename = await func() await client.wait_until_ready() - guild = client.get_guild(guild_id) # id of seguis III + guild = client.get_guild(guild_id) + matt = discord.utils.find(lambda m: m.id == MATT, guild.members) - matt_voice = next(filter(lambda member: member.id == MATT, guild.members)).voice + # why the fuck does python still not have safe navigation operators? + matt_voice = ((matt.voice.channel if matt.voice.channel else None) if matt.voice else None) if matt else None + top_channel = sorted(guild.voice_channels, key = lambda chan: len(chan.members), reverse = True)[0] - channel = matt_voice.channel if matt_voice else top_channel + channel = matt_voice if matt_voice else top_channel - await say(filename, channel) + ticker_queue.put((filename, channel)) - s.add_job(wrapper, trigger = trigger) return wrapper return decorator -def to_tts(message, lang = 'ja'): - message_hash = hashlib.md5(message.encode('utf-8')).hexdigest() - file_name = ROOT + "/cache/" + message_hash + ".mp3" - if not os.path.isfile(file_name): - print("file does not exist, cacheing") - tts = gTTS(message, lang = lang) - tts.save(file_name) - return file_name - -@update(CronTrigger(hour = '0-19,21-23'), SEGUIS) +@update(SEGUIS) async def ticker(): - return to_tts("The current JPY exchange rate is " + str(c.get_rate('USD', 'JPY')) + " yen to one dollar") + return to_tts("The current JPY exchange rate is " + str(c.get_rate('USD', 'JPY')) + " yen to a dollar") -@update(CronTrigger(hour = '20'), SEGUIS) +@update(SEGUIS) async def flatten(): return to_tts("Matt, it is time for your 4 PM dick flattening") -@update(CronTrigger(hour = '*/2', minute = '30'), GOONS) -async def drip(): - return to_tts("Cum drip, pussy slit") - -@client.event -async def on_voice_state_update(member, before, after): - await client.wait_until_ready() - - if after.channel == client.get_channel(RETARD_DIMENSION): - await say(to_tts(member.display_name + "はretard dimensionに移動しました"), before.channel) - +s = AsyncIOScheduler(event_loop = client.loop) +s.add_job(ticker, CronTrigger(hour = '0-19,21-23')) +s.add_job(flatten, CronTrigger(hour = '20')) s.start() with open(ROOT + "/priv/token") as file: