ticker/ticker.py

157 lines
5.8 KiB
Python
Raw Normal View History

2020-04-09 08:55:54 +00:00
import discord
from datetime import datetime
from gtts import gTTS
from forex_python.converter import CurrencyRates
from apscheduler.schedulers.asyncio import AsyncIOScheduler
from apscheduler.triggers.cron import CronTrigger
2020-04-11 07:45:27 +00:00
from random import randint
2020-04-09 22:04:50 +00:00
import asyncio
2020-04-10 00:42:51 +00:00
import hashlib
import os.path
2020-04-09 08:55:54 +00:00
2020-04-11 02:52:38 +00:00
ROOT = "/home/bot/ticker"
2020-04-10 06:08:37 +00:00
SEGUIS = 665399296522321942
2020-04-11 07:08:53 +00:00
GOONS = 499822662281854996
2020-04-10 06:08:37 +00:00
MATT = 150791815723876352
2020-04-11 07:42:09 +00:00
DAD = 509547108907614208
SMOKEYS = 673203690672357422
RETARD = 695090043609415740
2020-04-10 06:08:37 +00:00
2020-04-09 08:55:54 +00:00
client = discord.Client()
2020-04-09 22:04:50 +00:00
c = CurrencyRates()
2020-04-09 08:55:54 +00:00
2020-04-11 02:51:42 +00:00
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:
2020-04-11 03:08:52 +00:00
await client.wait_until_ready()
2020-04-11 02:51:42 +00:00
# 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()
2020-04-11 05:43:38 +00:00
# we are not already in the correct channel
2020-04-11 02:51:42 +00:00
if not target_voice_channel.id == voice_client.channel.id:
2020-04-11 07:08:53 +00:00
await voice_client.move_to(target_voice_channel)
2020-04-11 02:51:42 +00:00
# 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()
2020-04-09 08:55:54 +00:00
@client.event
async def on_ready():
print(client.user.name)
2020-04-09 09:41:40 +00:00
2020-04-11 05:43:38 +00:00
# add afk message
2020-04-11 02:51:42 +00:00
@client.event
async def on_voice_state_update(member, before, after):
2020-04-11 07:42:09 +00:00
if member.id == MATT and after.channel and after.channel.id == SMOKEYS:
2020-04-11 07:45:27 +00:00
await asyncio.sleep(randint(3, 30))
2020-04-11 07:42:09 +00:00
await member.move_to(client.get_channel(RETARD))
2020-04-11 02:51:42 +00:00
# only run on moves
if before.channel and after.channel:
# moves to the afk channel
2020-04-11 06:22:57 +00:00
if member.guild.afk_channel and after.channel.id == member.guild.afk_channel.id:
2020-04-11 05:43:38 +00:00
file_name = to_tts(member.display_name + "はretard dimensionに移動しました")
2020-04-11 06:22:57 +00:00
await add_event(file_name, before.channel)
2020-04-11 05:43:38 +00:00
# ban league
@client.event
async def on_member_update(before, after):
2020-04-11 07:08:53 +00:00
# literally any of these fields might not exist and python has no safe navigation
# nor does it have pattern matching usable for this purpose
# guess i'll die
2020-04-11 07:42:09 +00:00
before_name = None
2020-04-11 06:22:57 +00:00
if before and before.activity and before.activity.type == discord.ActivityType.playing and before.activity.name:
before_name = before.activity.name
2020-04-11 07:42:09 +00:00
after_name = None
2020-04-11 06:22:57 +00:00
if after and after.activity and after.activity.type == discord.ActivityType.playing and after.activity.name:
2020-04-11 07:42:09 +00:00
after_name = after.activity.name
if before_name != after_name:
if after_name == "League of Legends" and after.voice:
file_name = to_tts("Stop playing League, " + after.display_name)
await add_event(file_name, after.voice.channel)
2020-04-11 02:51:42 +00:00
client.loop.create_task(ticker_update())
2020-04-10 06:08:37 +00:00
2020-04-11 03:08:52 +00:00
# either matts channel, or the most active channel
def get_best_channel(guild_id):
guild = client.get_guild(guild_id)
matt = discord.utils.find(lambda m: m.id == MATT, guild.members)
2020-04-09 08:55:54 +00:00
2020-04-11 03:08:52 +00:00
# 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]
return matt_voice if matt_voice else top_channel
2020-04-09 09:41:40 +00:00
2020-04-11 05:43:38 +00:00
async def add_event(file_name, voice_channel):
2020-04-11 03:08:52 +00:00
print("ticker event has been added to queue")
2020-04-11 05:43:38 +00:00
await ticker_queue.put((file_name, voice_channel))
async def ticker():
2020-04-11 07:08:53 +00:00
voice_channel = get_best_channel(SEGUIS)
2020-04-11 03:08:52 +00:00
file_name = to_tts("The current JPY exchange rate is " + str(c.get_rate('USD', 'JPY')) + " yen to a dollar")
2020-04-11 05:43:38 +00:00
await add_event(file_name, voice_channel)
2020-04-09 08:55:54 +00:00
async def flatten():
2020-04-11 07:08:53 +00:00
voice_channel = get_best_channel(SEGUIS)
2020-04-11 03:08:52 +00:00
file_name = to_tts("Matt, it is time for your 4 PM dick flattening")
2020-04-11 05:43:38 +00:00
await add_event(file_name, voice_channel)
2020-04-10 00:42:51 +00:00
2020-04-11 07:08:53 +00:00
async def cummies():
voice_channel = get_best_channel(GOONS)
2020-04-11 07:16:54 +00:00
file_name = to_tts("くむづりっぽぷっししりっと")
2020-04-11 07:08:53 +00:00
await add_event(file_name, voice_channel)
2020-04-11 02:51:42 +00:00
s = AsyncIOScheduler(event_loop = client.loop)
s.add_job(ticker, CronTrigger(hour = '0-19,21-23'))
s.add_job(flatten, CronTrigger(hour = '20'))
2020-04-11 07:08:53 +00:00
s.add_job(cummies, CronTrigger(hour = '*', minute = '30'))
2020-04-09 08:55:54 +00:00
s.start()
2020-04-10 06:08:37 +00:00
with open(ROOT + "/priv/token") as file:
2020-04-09 08:55:54 +00:00
token = file.readline()
client.run(token)