1
0
Fork 0
mirror of synced 2024-10-01 17:56:30 +13:00
This commit is contained in:
phxntxm 2016-08-19 01:13:15 -05:00
commit 4a436bb3ba
5 changed files with 106 additions and 23 deletions

View file

@ -19,6 +19,13 @@ class Owner:
def __init__(self, bot): def __init__(self, bot):
self.bot = bot self.bot = bot
@commands.command()
@commands.check(checks.is_owner)
async def testcommand(self, member: discord.Member):
roles = [discord.Object(id="183749087038930944")]
await self.bot.add_roles(member, *roles)
await self.bot.say("Just added the roles {} to {}".format(role, member.display_name))
@commands.command(pass_context=True) @commands.command(pass_context=True)
@commands.check(checks.is_owner) @commands.check(checks.is_owner)
async def saferestart(self, ctx): async def saferestart(self, ctx):

View file

@ -6,6 +6,7 @@ import json
log = logging.getLogger() log = logging.getLogger()
discord_bots_url = 'https://bots.discord.pw/api' discord_bots_url = 'https://bots.discord.pw/api'
carbonitex_url = 'https://www.carbonitex.net/discord/data/botdata.php'
class StatsUpdate: class StatsUpdate:
@ -19,6 +20,15 @@ class StatsUpdate:
config.loop.create_task(self.session.close()) config.loop.create_task(self.session.close())
async def update(self): async def update(self):
carbon_payload = {
'key': config.carbon_key,
'servercount': len(self.bot.servers)
}
async with self.session.post(carbonitex_url, data=carbon_payload) as resp:
log.info('Carbonitex statistics returned {} for {}'.format(resp.status, carbon_payload))
payload = json.dumps({ payload = json.dumps({
'server_count': len(self.bot.servers) 'server_count': len(self.bot.servers)
}) })
@ -28,9 +38,9 @@ class StatsUpdate:
'content-type': 'application/json' 'content-type': 'application/json'
} }
url = '{0}/bots/{1.user.id}/stats'.format(discord_bots_url, self.bot) url = '{}/bots/{}/stats'.format(discord_bots_url, self.bot.user.id)
async with self.session.post(url, data=payload, headers=headers) as resp: async with self.session.post(url, data=payload, headers=headers) as resp:
log.info('bots.discord.pw statistics returned {0.status} for {1}'.format(resp, payload)) log.info('bots.discord.pw statistics returned {} for {}'.format(resp.status, payload))
async def on_server_join(self, server): async def on_server_join(self, server):
await self.update() await self.update()

View file

@ -25,7 +25,7 @@ class Tags:
"""This can be used to call custom tags """This can be used to call custom tags
The format to call a custom tag is !tag <tag>""" The format to call a custom tag is !tag <tag>"""
tags = config.get_content('tags') or {} tags = config.get_content('tags') or {}
# Same generator as the method for tags, other than the second check to see get the tag that is provided # Same generator as the method for tags, other than the second check to get the tag that is provided
result = [t for t in tags if t['tag'] == tag and t['server_id'] == ctx.message.server.id] result = [t for t in tags if t['tag'] == tag and t['server_id'] == ctx.message.server.id]
if len(result) == 0: if len(result) == 0:
await self.bot.say('That tag does not exist!') await self.bot.say('That tag does not exist!')

View file

@ -9,10 +9,16 @@ import re
async def channel_online(channel: str): async def channel_online(channel: str):
# Check a specific channel's data, and get the response in text format
url = "https://api.twitch.tv/kraken/streams/{}".format(channel) url = "https://api.twitch.tv/kraken/streams/{}".format(channel)
with aiohttp.ClientSession() as s: with aiohttp.ClientSession() as s:
async with s.get(url) as r: async with s.get(url) as r:
response = await r.text() response = await r.text()
# For some reason Twitch's API call is not reliable, sometimes it returns stream as None
# That is what we're checking specifically, sometimes it doesn't exist in the returned JSON at all
# Sometimes it returns something that cannot be decoded with JSON
# In either error case, just assume they're offline, the next check will most likely work
try: try:
data = json.loads(response) data = json.loads(response)
return data['stream'] is not None return data['stream'] is not None
@ -32,27 +38,49 @@ class Twitch:
async def check_channels(self): async def check_channels(self):
await self.bot.wait_until_ready() await self.bot.wait_until_ready()
# Loop through as long as the bot is connected
while not self.bot.is_closed: while not self.bot.is_closed:
twitch = config.get_content('twitch') or {} twitch = config.get_content('twitch') or {}
for m_id, r in twitch.items(): # Online/offline is based on whether they are set to such, in the config file
# This means they were detected as online/offline before and we check for a change
online_users = {m_id: data for m_id, data in twitch.items() if data['notifications_on'] and data['live']}
offline_users = {m_id: data for m_id, data in twitch.items() if data['notifications_on'] and not data['live']}
for m_id, r in offline_users.items():
# Get their url and their user based on that url
url = r['twitch_url'] url = r['twitch_url']
live = r['live']
notify = r['notifications_on']
user = re.search("(?<=twitch.tv/)(.*)", url).group(1) user = re.search("(?<=twitch.tv/)(.*)", url).group(1)
online = await channel_online(user) # Check if they are online right now
if not live and notify and online: if await channel_online(user):
server = discord.utils.find(lambda s: s.id == r['server_id'], self.bot.servers) for server_id in r['servers']:
member = discord.utils.find(lambda m: m.id == m_id, server.members) # Get the channel to send the message to, based on the saved alert's channel
server = self.bot.get_server(server_id)
server_alerts = config.get_content('server_alerts') or {}
channel_id = server_alerts.get(server_id) or server_id
channel = self.bot.get_channel(channel_id)
# Get the member that has just gone live
member = discord.utils.get(server.members, id=m_id)
fmt = "{} has just gone live! View their stream at {}".format(member.display_name, url)
await self.bot.send_message(channel, fmt)
twitch[m_id]['live'] = 1 twitch[m_id]['live'] = 1
fmt = "{} has just gone live! View their stream at {}".format(member.name, url)
await self.bot.send_message(server, fmt)
config.save_content('twitch', twitch) config.save_content('twitch', twitch)
elif live and not online: for m_id, r in online_users.items():
server = discord.utils.find(lambda s: s.id == r['server_id'], self.bot.servers) # Get their url and their user based on that url
member = discord.utils.find(lambda m: m.id == m_id, server.members) url = r['twitch_url']
user = re.search("(?<=twitch.tv/)(.*)", url).group(1)
# Check if they are online right now
if not await channel_online(user):
for server_id in r['servers']:
# Get the channel to send the message to, based on the saved alert's channel
server = self.bot.get_server(server_id)
server_alerts = config.get_content('server_alerts') or {}
channel_id = server_alerts.get(server_id) or server_id
channel = self.bot.get_channel(channel_id)
# Get the member that has just gone live
member = discord.utils.get(server.members, id=m_id)
fmt = "{} has just gone offline! Catch them next time they stream at {}".format(member.display_name, url)
await self.bot.send_message(server, fmt)
twitch[m_id]['live'] = 0 twitch[m_id]['live'] = 0
fmt = "{} has just gone offline! Catch them next time they stream at {}".format(member.name, url)
await self.bot.send_message(server, fmt)
config.save_content('twitch', twitch) config.save_content('twitch', twitch)
await asyncio.sleep(30) await asyncio.sleep(30)
@ -86,6 +114,14 @@ class Twitch:
@checks.custom_perms(send_messages=True) @checks.custom_perms(send_messages=True)
async def add_twitch_url(self, ctx, url: str): async def add_twitch_url(self, ctx, url: str):
"""Saves your user's twitch URL""" """Saves your user's twitch URL"""
# This uses a lookbehind to check if twitch.tv exists in the url given
# If it does, it matches twitch.tv/user and sets the url as that
# Then (in the else) add https://www. to that
# Otherwise if it doesn't match, we'll hit an AttributeError due to .group(0)
# This means that the url was just given as a user (or something complete invalid)
# So set URL as https://www.twitch.tv/[url]
# Even if this was invalid such as https://www.twitch.tv/google.com/
# For example, our next check handles that
try: try:
url = re.search("((?<=://)?twitch.tv/)+(.*)", url).group(0) url = re.search("((?<=://)?twitch.tv/)+(.*)", url).group(0)
except AttributeError: except AttributeError:
@ -93,6 +129,7 @@ class Twitch:
else: else:
url = "https://www.{}".format(url) url = "https://www.{}".format(url)
# Try to find the channel provided, we'll get a 404 response if it does not exist
with aiohttp.ClientSession() as s: with aiohttp.ClientSession() as s:
async with s.get(url) as r: async with s.get(url) as r:
if not r.status == 200: if not r.status == 200:
@ -103,10 +140,13 @@ class Twitch:
twitch = config.get_content('twitch') or {} twitch = config.get_content('twitch') or {}
result = twitch.get(ctx.message.author.id) result = twitch.get(ctx.message.author.id)
# Check to see if this user has already saved a twitch URL
# If they have, update the URL, otherwise create a new entry
# Assuming they're not live, and notifications should be on
if result is not None: if result is not None:
twitch[ctx.message.author.id]['twitch_url'] = url twitch[ctx.message.author.id]['twitch_url'] = url
else: else:
twitch[ctx.message.author.id] = {'twitch_url': url, 'server_id': ctx.message.server.id, twitch[ctx.message.author.id] = {'twitch_url': url, 'servers': [ctx.message.server.id],
'notifications_on': 1, 'live': 0} 'notifications_on': 1, 'live': 0}
config.save_content('twitch', twitch) config.save_content('twitch', twitch)
await self.bot.say("I have just saved your twitch url {}".format(ctx.message.author.mention)) await self.bot.say("I have just saved your twitch url {}".format(ctx.message.author.mention))
@ -116,7 +156,9 @@ class Twitch:
async def remove_twitch_url(self, ctx): async def remove_twitch_url(self, ctx):
"""Removes your twitch URL""" """Removes your twitch URL"""
twitch = config.get_content('twitch') or {} twitch = config.get_content('twitch') or {}
# Make sure the user exists before trying to delete them from the list
if twitch.get(ctx.message.author.id) is not None: if twitch.get(ctx.message.author.id) is not None:
# Simply remove this user from the list, and save
del twitch[ctx.message.author.id] del twitch[ctx.message.author.id]
config.save_content('twitch', twitch) config.save_content('twitch', twitch)
await self.bot.say("I am no longer saving your twitch URL {}".format(ctx.message.author.mention)) await self.bot.say("I am no longer saving your twitch URL {}".format(ctx.message.author.mention))
@ -128,22 +170,36 @@ class Twitch:
@twitch.group(pass_context=True, no_pm=True, invoke_without_command=True) @twitch.group(pass_context=True, no_pm=True, invoke_without_command=True)
@checks.custom_perms(send_messages=True) @checks.custom_perms(send_messages=True)
async def notify(self, ctx): async def notify(self, ctx):
"""This can be used to turn notifications on or off""" """This can be used to modify notification settings for your twitch user
pass Call this command by itself to add 'this' server as one that will be notified when you on/offline"""
twitch = config.get_content('twitch') or {}
result = twitch.get(ctx.message.author.id)
# Check if this user is saved at all
if result is None:
await self.bot.say(
"I do not have your twitch URL added {}. You can save your twitch url with !twitch add".format(
ctx.message.author.mention))
# Otherwise we just need to append the server's ID to the servers list
else:
twitch[ctx.message.author.id]['servers'].append(ctx.message.server.id)
config.save_content('twitch', twitch)
@notify.command(name='on', aliases=['start,yes'], pass_context=True, no_pm=True) @notify.command(name='on', aliases=['start,yes'], pass_context=True, no_pm=True)
@checks.custom_perms(send_messages=True) @checks.custom_perms(send_messages=True)
async def notify_on(self, ctx): async def notify_on(self, ctx):
"""Turns twitch notifications on""" """Turns twitch notifications on"""
# Make sure this user is saved before we attempt to modify their information
twitch = config.get_content('twitch') or {} twitch = config.get_content('twitch') or {}
result = twitch.get(ctx.message.author.id) result = twitch.get(ctx.message.author.id)
if result is None: if result is None:
await self.bot.say( await self.bot.say(
"I do not have your twitch URL added {}. You can save your twitch url with !twitch add".format( "I do not have your twitch URL added {}. You can save your twitch url with !twitch add".format(
ctx.message.author.mention)) ctx.message.author.mention))
# Then check to see if notifications are already on
elif result['notifications_on']: elif result['notifications_on']:
await self.bot.say("What do you want me to do, send two notifications? Not gonna happen {}".format( await self.bot.say("What do you want me to do, send two notifications? Not gonna happen {}".format(
ctx.message.author.mention)) ctx.message.author.mention))
# Otherwise, turn on notifications
else: else:
twitch[ctx.message.author.id]['notifications_on'] = 1 twitch[ctx.message.author.id]['notifications_on'] = 1
config.save_content('twitch', twitch) config.save_content('twitch', twitch)
@ -154,6 +210,7 @@ class Twitch:
@checks.custom_perms(send_messages=True) @checks.custom_perms(send_messages=True)
async def notify_off(self, ctx): async def notify_off(self, ctx):
"""Turns twitch notifications off""" """Turns twitch notifications off"""
# This method is exactly the same, except for turning off notifcations instead of on
twitch = config.get_content('twitch') or {} twitch = config.get_content('twitch') or {}
if twitch.get(ctx.message.author.id) is None: if twitch.get(ctx.message.author.id) is None:
await self.bot.say( await self.bot.say(

View file

@ -4,6 +4,7 @@ import json
loop = asyncio.get_event_loop() loop = asyncio.get_event_loop()
# Ensure that the required config.yml file actually exists
try: try:
with open("config.yml", "r") as f: with open("config.yml", "r") as f:
global_config = yaml.load(f) global_config = yaml.load(f)
@ -11,13 +12,21 @@ except FileNotFoundError:
print("You have no config file setup! Please use config.yml.sample to setup a valid config file") print("You have no config file setup! Please use config.yml.sample to setup a valid config file")
quit() quit()
# Default bot's description
botDescription = global_config.get("description") botDescription = global_config.get("description")
# Bot's default prefix for commands
commandPrefix = global_config.get("command_prefix", "!") commandPrefix = global_config.get("command_prefix", "!")
# The key for bots.discord.pw and carbonitex
discord_bots_key = global_config.get('discord_bots_key', "") discord_bots_key = global_config.get('discord_bots_key', "")
carbon_key = global_config.get('carbon_key', "")
# The invite link for the server made for the bot
dev_server = global_config.get("dev_server", "") dev_server = global_config.get("dev_server", "")
# A list of all the outputs for the battle command
battleWins = global_config.get("battleWins", []) battleWins = global_config.get("battleWins", [])
# The default status the bot will use
defaultStatus = global_config.get("default_status", "") defaultStatus = global_config.get("default_status", "")
#
try: try:
botToken = global_config["bot_token"] botToken = global_config["bot_token"]
except KeyError: except KeyError: