71 Commits
Author SHA1 Message Date
rich 1153d1919c fixing indents 2021-04-04 15:01:48 -04:00
rich 499d86459b Merge branch 'testing' of https://gitlab.rickelobe.com/Bots/r0b3BOT into testing 2021-04-04 14:54:55 -04:00
rich c053b58733 not properly handling non jason response 2021-04-04 14:54:38 -04:00
rich e018cfa05b Merge branch 'master' of https://gitlab.rickelobe.com/Bots/r0b3BOT into testing 2021-03-23 19:11:00 -04:00
rich 9f58177559 Merge branch 'dev' into 'master'
Bring in fix for displaying correct version number

See merge request Bots/r0b3BOT!63
2021-03-22 14:40:18 +00:00
rich 58e1781397 correctly fixing the version now (wish the documentation was better) 2021-03-22 00:10:35 +00:00
rich f08eb06db4 Fixing the version information displayed for the info command 2021-03-22 00:06:43 +00:00
rich 807bf17f61 Merge branch 'dev' into 'master'
Merge MMR checker into master for release

See merge request Bots/r0b3BOT!62
2021-03-21 23:42:04 +00:00
rich 3e354d3655 Merge MMR checker into master for release 2021-03-21 23:42:04 +00:00
rich fa38734869 Merge branch 'testing' into 'dev'
Merge MMR Checker into Dev

See merge request Bots/r0b3BOT!61
2021-03-21 23:29:08 +00:00
rich 66ed4fd4d1 Merge MMR Checker into Dev 2021-03-21 23:29:07 +00:00
rich c528e0f638 Added new feature 2021-03-21 17:19:27 +00:00
rich 41b1c73ff3 adding back bot.remove_command entry 2021-03-21 13:10:16 -04:00
rich b1d1a7b1cc Cleanup of code 2021-03-21 13:07:25 -04:00
rich 8bb132be24 Organizing 2021-03-21 12:44:49 -04:00
rich 15d0a01dcb typo 2021-03-21 12:37:56 -04:00
rich ad05b2f427 updating help command details 2021-03-21 12:37:20 -04:00
rich 2cbaef99c0 working on mmrstatus 2021-03-21 12:26:25 -04:00
rich a53cab8343 working on mmrstatus 2021-03-21 12:24:03 -04:00
rich e00da20870 Cleaning up output text 2021-03-21 12:17:00 -04:00
rich 45d8d5702c found typo 2021-03-21 12:11:24 -04:00
rich 86e7944837 editing output for clarity 2021-03-21 12:05:31 -04:00
rich e9a2165f78 found some issues 2021-03-21 11:41:45 -04:00
rich 9421b22cff was using wrong varibale... missed ong 2021-03-21 07:54:10 -04:00
rich 5767d2d606 was using wrong varibale 2021-03-21 07:53:06 -04:00
rich 3b5ecf4b6b more debug 2021-03-21 07:46:56 -04:00
rich d961698d40 typo 2021-03-21 07:45:15 -04:00
rich 37e9512d82 troubleshooting -list command 2021-03-21 07:44:27 -04:00
rich 5e1164d98c typo 2021-03-20 19:25:50 -04:00
rich 1e64e992dd let's try it this way 2021-03-20 19:25:05 -04:00
rich 667126c916 dunno 2021-03-20 19:18:31 -04:00
rich 5ada6cfb36 troubleshooting response check: welp, had that backwards 2021-03-20 19:13:08 -04:00
rich b6d5ce6836 troubleshooting response check: fixing syntax 2021-03-20 19:11:16 -04:00
rich 0077f1a80b troubleshooting response check 2021-03-20 19:09:34 -04:00
rich dfa82dbe96 correcting variable being used 2021-03-20 19:06:59 -04:00
rich ba014f4c98 fixing... 2021-03-20 19:05:27 -04:00
rich 6823161897 fixing... 2021-03-20 19:03:52 -04:00
rich fcb0051c87 fixing 2021-03-20 19:03:15 -04:00
rich 403aa9a362 check if handle was actually found 2021-03-20 19:00:42 -04:00
rich 8d91336b43 Added mmrstatus command 2021-03-20 18:31:41 -04:00
rich 25abfb2a59 updating info command 2021-03-20 18:23:30 -04:00
rich 3f9a976742 clarifying alert text 2021-03-20 17:17:49 -04:00
rich 8f41991a3d fixing assignment again... hopefully for the last time, again 2021-03-20 16:31:09 -04:00
rich 1785162cea fixing assignment again... hopefully for the last time 2021-03-20 16:30:15 -04:00
rich 0207424d32 fixing assignment again 2021-03-20 16:28:50 -04:00
rich ab7009e43f fixing assignment 2021-03-20 16:25:36 -04:00
rich 5c0e61d466 adding newlines 2021-03-20 12:51:43 -04:00
rich 2cabbbf6f1 more tweaks to output 2021-03-20 12:49:19 -04:00
rich 803e8d552d more tweaks to output 2021-03-20 12:48:19 -04:00
rich 0950092f6d more tweaks to output 2021-03-20 12:46:47 -04:00
rich f6e15d9c35 output formatting 2021-03-20 12:38:21 -04:00
rich 5b917e032f fixing minor typo 2021-03-20 12:16:36 -04:00
rich 7628f8d1ae setting variable to int 2021-03-20 12:14:52 -04:00
rich 1e496efbee added interval option for mmr checker, cleaned up some output 2021-03-20 12:11:30 -04:00
rich 0cf348570b tweaks 2021-03-20 11:39:17 -04:00
rich 55419dbafb correcting syntax error 2021-03-20 10:03:45 -04:00
rich cf3757ce11 added enable/disable check before starting mmr checker and statping monitor 2021-03-20 10:02:08 -04:00
rich 4cf45b2684 added enable/disable options for mmr checker and statping monitor 2021-03-20 10:01:34 -04:00
rich 544f7b5833 I think all of the necessary changes have been made to add the mmr checker... needs to test now? 2021-03-19 22:43:02 -04:00
rich fa2a34c951 adding mmr api variable 2021-03-19 22:24:04 -04:00
rich affbf366a1 adding base code for mmr_checker 2021-02-14 21:37:17 -05:00
rich 4056f60cd8 duplicated statping functions for mmr monitor 2021-01-20 21:55:42 -05:00
rich a7a36f123c Merge branch 'dev' of https://gitlab.rickelobe.com/Bots/r0b3BOT into mmr_checker 2021-01-20 21:27:43 -05:00
rich 6865041707 Added missing playtime value for rs command 2020-09-02 09:47:06 -04:00
rich 520758e2f2 Added Wiz Khalifa clip $big 2020-07-01 09:10:58 -04:00
rich cd74624747 added iran sound clip 2020-07-01 08:58:15 -04:00
rich 525f13b3e8 Merge branch 'dev' into 'master'
changing play delay to check if file is still being played

See merge request Bots/r0b3BOT!60
2020-06-22 11:36:18 -04:00
rich c82dc32ca2 changing play delay to check if file is still being played 2020-06-19 11:42:37 -04:00
rich ccb260c3f9 Merge branch 'master' into 'testing'
Make testing master again!

See merge request Bots/r0b3BOT!59
2020-04-15 15:27:09 -04:00
rich fa9fb6b27d Merge branch 'dev' into 'master'
Version 0.3

See merge request Bots/r0b3BOT!58
2020-04-15 15:09:06 -04:00
rich a8e62c5ce9 Merge branch 'dev' into 'master'
Version 0.2

See merge request Bots/r0b3BOT!47
2020-03-29 18:20:14 -04:00
5 changed files with 398 additions and 89 deletions

No files matched your search

+2 -1
View File
@@ -11,6 +11,7 @@ This is R0b3's Discord Bot. It's creation was basically a challenge posed a cow
* Query serivces states on StatPing using the `$spstatus` * Query serivces states on StatPing using the `$spstatus`
* Use `$spsub` to "Subscribe" to service change alerts for StatPing services. Subscribed alerts are persistent and are not lost on bot restart.<br> * Use `$spsub` to "Subscribe" to service change alerts for StatPing services. Subscribed alerts are persistent and are not lost on bot restart.<br>
![Example service alert](images/Service_alert.png) ![Example service alert](images/Service_alert.png)
* Use `$mmrsub` to "Subscribe" to a League of Legends handle's Ranked Average. As with the StatPing feature, the subscriptions are persistent.
* Play a selection of sound clips to voice channel members using the various commands (`$torololo`, `$oops`, `$promoted`, etc) * Play a selection of sound clips to voice channel members using the various commands (`$torololo`, `$oops`, `$promoted`, etc)
# Commands # Commands
@@ -24,4 +25,4 @@ This is R0b3's Discord Bot. It's creation was basically a challenge posed a cow
1. Create a Discord Bot via Developer tools<br> 1. Create a Discord Bot via Developer tools<br>
2. Enter configuration parameters in bot_config.conf.example<br> 2. Enter configuration parameters in bot_config.conf.example<br>
3. Enter OctoPrint config parameters in octoapi.conf.example<br> 3. Enter OctoPrint config parameters in octoapi.conf.example<br>
4. Rename *.example files as *.conf<br> 4. Rename *.example files as *.conf and setup your config<br>
+5 -1
View File
@@ -17,5 +17,9 @@ hass_url = <URL to HomeAssistant>
hass_token = <HomeAssistant Long Lived Access Token> hass_token = <HomeAssistant Long Lived Access Token>
hass_light = <Entity_ID of the light @ your printer> hass_light = <Entity_ID of the light @ your printer>
octoprint_ip_address = <OctoPrint IP Address> octoprint_ip_address = <OctoPrint IP Address>
statping_enable = <trues/false>
statping_url = <Statping URL> statping_url = <Statping URL>
statping_api_key = <Statping API Key> statping_api_key = <Statping API Key>
mmr_checker_enable = <true/false>
mmr_checker_interval = <number of seconds between checks>
mmr_api_url = <MMR API URL>
+391 -87
View File
@@ -2,45 +2,47 @@
import discord import discord
from discord.ext import commands from discord.ext import commands
from discord import FFmpegPCMAudio
from discord.utils import get
from discord.voice_client import VoiceClient
from datetime import datetime
import urllib.request import urllib.request
import random import random
import os import os
import sys import sys
import octoapi import octoapi
import time import time
from datetime import datetime
import configparser import configparser
import json import json
from discord import FFmpegPCMAudio
from discord.utils import get
from discord.voice_client import VoiceClient
import requests import requests
import asyncio import asyncio
#from aiofile import AIOFile
import aiofiles as aiof import aiofiles as aiof
import pickle import pickle
#Record the time the bot started #Record the time the bot started
start_time = time.time() start_time = time.time()
config = configparser.RawConfigParser() config = configparser.RawConfigParser()
configFilePath = r'bot_config.conf' configFilePath = r'bot_config.conf'
# Last error message variable used by $last_error command to display in discord
global last_error
last_error = "No errors have been recorded."
try: try:
config.read(configFilePath) config.read(configFilePath)
except: except:
print("Error loading config! Please check config file 'bot-config.conf'") print("Error loading config! Please check config file 'bot-config.conf'")
# Last error message variable used by $last_error command to display in discord
global last_error
last_error = "No errors have been recorded."
# #
# Read in bot configurations # Assign bot config from setting in config file
# #
# Setup HomeAssistant URL and Headers # Assign Bot core settings
DISCORD_AUTH_TOKEN = config.get('bot-config', 'discord_auth_token')
BOT_COMMAND_PREFIX = config.get('bot-config', 'bot_command_prefix')
# 3D Printer Setup - HomeAssistant URL and Headers & OctoPrint
HASS_TOKEN = config.get('bot-config', 'hass_token') HASS_TOKEN = config.get('bot-config', 'hass_token')
HASS_URL = config.get('bot-config', 'hass_url') HASS_URL = config.get('bot-config', 'hass_url')
HASS_LIGHT = config.get('bot-config', 'hass_light') HASS_LIGHT = config.get('bot-config', 'hass_light')
@@ -49,10 +51,10 @@ hassHEADERS = {
'Authorization': f"Bearer {HASS_TOKEN}", 'Authorization': f"Bearer {HASS_TOKEN}",
'content-type': 'application/json', 'content-type': 'application/json',
} }
OCTOPRINT_IP_ADDRESS = config.get('bot-config', 'octoprint_ip_address') OCTOPRINT_IP_ADDRESS = config.get('bot-config', 'octoprint_ip_address')
DISCORD_AUTH_TOKEN = config.get('bot-config', 'discord_auth_token')
BOT_COMMAND_PREFIX = config.get('bot-config', 'bot_command_prefix') # StatPing Monitor Settings
statping_enable = config.get('bot-config', 'statping_enable')
STATPING_URL = config.get('bot-config', 'statping_url') STATPING_URL = config.get('bot-config', 'statping_url')
STATPING_API_KEY = config.get('bot-config', 'statping_api_key') STATPING_API_KEY = config.get('bot-config', 'statping_api_key')
statpingURL = STATPING_URL + "/api/services" statpingURL = STATPING_URL + "/api/services"
@@ -61,27 +63,45 @@ statpingHEADERS = {
'content-type': 'application/json', 'content-type': 'application/json',
} }
# Configure bot #MMR Checker Settings
mmr_checker_enable = config.get('bot-config', 'mmr_checker_enable')
mmr_checker_interval = config.get('bot-config', 'mmr_checker_interval')
mmrURLBASE = config.get('bot-config', 'mmr_api_url')
mmrHEADERS = {
'User-Agent': 'Linux:com.r0b3bot:v.01a',
'content-type': 'application/json',
}
# Configure bot
bot = commands.Bot(command_prefix=BOT_COMMAND_PREFIX, description='A derpy derp of a bot.') bot = commands.Bot(command_prefix=BOT_COMMAND_PREFIX, description='A derpy derp of a bot.')
bot.remove_command('help')
# Printing configuration details to console # Printing configuration details to console
print(f"HomeAssistant URL: {hassURL}") print("=== 3D Printer Status config ===")
print(f"HomeAssistant URL HEADERS: {hassHEADERS}") print(f" HomeAssistant URL: {hassURL}")
print(f"HomeAssistant Light: {HASS_LIGHT}") print(f" HomeAssistant URL HEADERS: {hassHEADERS}")
print(f"OctoPrint IP Address: {OCTOPRINT_IP_ADDRESS}") print(f" HomeAssistant Light: {HASS_LIGHT}")
print(f"StatPing Server: {STATPING_URL}") print(f" OctoPrint IP Address: {OCTOPRINT_IP_ADDRESS}")
print(f"StatPing API Key: {STATPING_API_KEY}") print("\n=== StatPing Monitor Config ===")
print(f"StatPing URL Headers: {statpingHEADERS}") print(f" Enabled: {statping_enable}")
print(f" Server: {STATPING_URL}")
print(f" API Key: {STATPING_API_KEY}")
print(f" URL Headers: {statpingHEADERS}")
print("\n=== MMR Checker Config ===")
print(f" Enabled: {mmr_checker_enable}")
print(f" Checker Interval: {mmr_checker_interval}")
print(f" API URL BASE: {mmrURLBASE}")
# On Ready # On Ready
@bot.event @bot.event
async def on_ready(): async def on_ready():
print("\n:::: Config Loaded ::::\n")
print('Logged in as') print('Logged in as')
print(bot.user.name) print(f" User: {bot.user.name}")
print(bot.user.id) print(f" ID: {bot.user.id}")
print('------') print(f"\n\n")
print("Setting activity to 'Listenting to your commands'") print(f"Setting activity to 'Listenting to your {BOT_COMMAND_PREFIX}commands'")
activity = discord.Activity(name="your $commands",type=discord.ActivityType.listening) activity = discord.Activity(name=f"your {BOT_COMMAND_PREFIX}commands",type=discord.ActivityType.listening)
await bot.change_presence(activity=activity) await bot.change_presence(activity=activity)
@@ -89,11 +109,23 @@ async def on_ready():
runtime = time.time() - start_time runtime = time.time() - start_time
if runtime <= 15: if runtime <= 15:
#Run StatPing_Monitor #Run StatPing_Monitor
print("Starting StatPing Monitor.") if statping_enable == 'True':
await StatPing_Monitor() print("Statping Monitor enabled, starting StatPing Monitor.")
await StatPing_Monitor()
else: else:
print(f">> Bot has been running for more than {int(runtime)} seconds. Not restarting monitor.") print(f">> Bot has been running for more than {int(runtime)} seconds. Not starting StatPing Monitor.")
#Run MMR Montor
if runtime <= 15:
if mmr_checker_enable == 'True':
print("MMR Checker enabled, starting MMR Checker.")
await MMR_Monitor()
else:
print(f">> Bot has been running for more than {int(runtime)} seconds. Not starting MMR Checker.")
print(">> Startup complete.")
@bot.command() @bot.command()
async def greetings(ctx): async def greetings(ctx):
@@ -226,6 +258,16 @@ async def yaw(ctx, member : discord.Member="NONE"):
async def heavy(ctx, member : discord.Member="NONE"): async def heavy(ctx, member : discord.Member="NONE"):
await play_sound(ctx, member, "./sounds/heavy.mp3", "$heavy", 6) await play_sound(ctx, member, "./sounds/heavy.mp3", "$heavy", 6)
@bot.command()
@commands.cooldown(rate=1, per=10.0, type=commands.BucketType.user)
async def iran(ctx, member : discord.Member="NONE"):
await play_sound(ctx, member, "./sounds/iran.mp3", "$iran", 4)
@bot.command()
@commands.cooldown(rate=1, per=10.0, type=commands.BucketType.user)
async def big(ctx, member : discord.Member="NONE"):
await play_sound(ctx, member, "./sounds/big.mp3", "$big", 4)
@bot.command() @bot.command()
@commands.cooldown(rate=1, per=10.0, type=commands.BucketType.user) @commands.cooldown(rate=1, per=10.0, type=commands.BucketType.user)
async def rs(ctx, member : discord.Member="NONE"): async def rs(ctx, member : discord.Member="NONE"):
@@ -233,7 +275,7 @@ async def rs(ctx, member : discord.Member="NONE"):
datestring = datestring.strftime("%m/%d/%Y-%H:%M:%S") datestring = datestring.strftime("%m/%d/%Y-%H:%M:%S")
if ctx.message.channel.is_nsfw(): if ctx.message.channel.is_nsfw():
soundfiles = ["./sounds/leeroy.mp3","./sounds/monkey_bitch.mp3","./sounds/More_cowbell.mp3","./sounds/BoomBitch.mp3","./sounds/Promoted.mp3","./sounds/Trololo.mp3","./sounds/Oops.mp3"] soundfiles = ["./sounds/leeroy.mp3","./sounds/monkey_bitch.mp3","./sounds/More_cowbell.mp3","./sounds/BoomBitch.mp3","./sounds/Promoted.mp3","./sounds/Trololo.mp3","./sounds/Oops.mp3"]
await play_sound(ctx, member, random.choice(soundfiles), "$rs") await play_sound(ctx, member, random.choice(soundfiles), "$rs", 6)
else: else:
print(f"[{datestring}]: {ctx.message.author.display_name} called $rs, but is not in a NSFW channel") print(f"[{datestring}]: {ctx.message.author.display_name} called $rs, but is not in a NSFW channel")
await ctx.send("This command is too explicit for you!") await ctx.send("This command is too explicit for you!")
@@ -287,7 +329,9 @@ async def play_sound(ctx, member : discord.Member, soundFile, command, playtime)
print(f" - Playing {soundFile}") print(f" - Playing {soundFile}")
time.sleep(1) time.sleep(1)
voice.play(audio_source, after=None) voice.play(audio_source, after=None)
time.sleep(playtime) while voice.is_playing():
await asyncio.sleep(1)
#time.sleep(playtime)
print(f" - Disconnecting from '{channel}'") print(f" - Disconnecting from '{channel}'")
await voice.disconnect() await voice.disconnect()
### ###
@@ -523,7 +567,6 @@ async def updateStatus():
activity = discord.Activity(name="your commands",type=discord.ActivityType.listening) activity = discord.Activity(name="your commands",type=discord.ActivityType.listening)
await bot.change_presence(activity=activity) await bot.change_presence(activity=activity)
@bot.command() @bot.command()
async def info(ctx): async def info(ctx):
embed = discord.Embed(title="R0b3BOT", description="Derpy Derp of a Bot :P", color=0xeee657) embed = discord.Embed(title="R0b3BOT", description="Derpy Derp of a Bot :P", color=0xeee657)
@@ -551,22 +594,16 @@ async def info(ctx):
embed.add_field(name="Uptime [WW:DD:HH:MM:SS]:", value=f"{week:02d}:{day:02d}:{hour:02d}:{minute:02d}:{second:02d}", inline=False) embed.add_field(name="Uptime [WW:DD:HH:MM:SS]:", value=f"{week:02d}:{day:02d}:{hour:02d}:{minute:02d}:{second:02d}", inline=False)
print("Getting git describe data to display as version in info embed") print("Getting git describe data to display as version in info embed")
bot_version = await run('git describe') bot_version = await run('git describe --tags')
embed.add_field(name="Version:", value=f"{bot_version}", inline=False) embed.add_field(name="Version:", value=f"{bot_version}", inline=False)
# Gitlab link to source # Gitlab link to source
embed.add_field(name="Source Code:", value="[R0b3Bot on Gitlab](https://gitlab.rickelobe.com/Bots/r0b3BOT)", inline=False) embed.add_field(name="Source Code:", value="[R0b3Bot on Gitlab](https://gitlab.rickelobe.com/Bots/r0b3BOT)", inline=False)
await ctx.send(embed=embed) await ctx.send(embed=embed)
bot.remove_command('help')
@bot.command() @bot.command()
async def spstatus(ctx, service = "NONE"): async def spstatus(ctx, service = "NONE"):
#async def spalert(ctx, cmd = "NONE", arg = "NONE"):
# if cmd != "NONE":
# if cmd == "add":
# spalert +=
if service != "NONE": if service != "NONE":
#await get_stp_status(ctx, service.lower()) #await get_stp_status(ctx, service.lower())
@@ -584,8 +621,6 @@ async def spstatus(ctx, service = "NONE"):
else: else:
await ctx.send("Please speficy a service name to query.") await ctx.send("Please speficy a service name to query.")
@bot.command() @bot.command()
async def spsub(ctx, service = "NONE"): async def spsub(ctx, service = "NONE"):
@@ -834,45 +869,6 @@ async def StatPing_Monitor():
print(">> spsublist.dat does not exist, nothing to do.") print(">> spsublist.dat does not exist, nothing to do.")
await asyncio.sleep(60) await asyncio.sleep(60)
async def sp_monitor(sublist):
# Checks the services listed in spsublist for status change
# Sublist is a list of 3 items:
# - ctx (used to send alert to channel)
# - service (the name of the service to check)
# - status string (last status of the service, either 'online' or 'offline')
ctx = sublist[0]
while True:
status = await get_stp_status(spsublist[1])
if status['online'] and spsublist[2] == "online":
# nothing has changed, no alert needed
await asyncio.sleep(1)
elif not status['online'] and spsublist[2] == "offline":
# again, nothing has changed no alert needed
await asyncio.sleep(1)
else:
print(f"Status of {status['name']}' has changed")
if status['online']:
embed = discord.Embed(title=f"{status['name']} Service Alert", description=f"{spsublist[1]} is Online!", color=0x00ff40)
await ctx.send(embed=embed)
#await ctx.send(f"{spsublist[1]} is Online!")
spsublist[2] = "online"
elif not status['online']:
embed = discord.Embed(title=f"{status['name']} Service Alert", description=f"{spsublist[1]} is Offline!", color=0xff2200)
await ctx.send(embed=embed)
#await ctx.send(f"{spsublist[1]} is Offline!")
spsublist[2] = "offline"
else:
embed = discord.Embed(title=f"{status['name']} Service Alert", description=f"{spsublist[1]} is in an unknown state!", color=0xffff00)
await ctx.send(embed=embed)
#await ctx.send(f"Unknown state for service {spsublist[1]}")
await asyncio.sleep(60)
async def get_stp_status(service): async def get_stp_status(service):
@@ -893,10 +889,310 @@ async def get_stp_status(service):
if not found: if not found:
return "service not found" return "service not found"
#
# Begin functions for MMR sub/alerts
#
@bot.command()
async def mmrstatus(ctx, handle = "NONE"):
print(f">> {BOT_COMMAND_PREFIX}mmrstatus was called for {handle}")
if handle != "NONE":
#await get_stp_status(ctx, service.lower())
result = await get_mmr_status(handle)
if result == "handle not found":
print(f">> {handle} was not found")
await ctx.send(f"'{handle}' was not found. Try wrapping handle in double quotes")
else:
print(f">> {handle} found!")
await ctx.send(f"'{handle}'s Ranked Average is: {result}")
else:
print(f">> User did not speficy handle")
await ctx.send("Please speficy a service name to query.")
@bot.command()
async def mmrsub(ctx, handle = "NONE"):
mmrsublist = {} # MMR Subscription list to be read in from file
# Structure of spsublist nested dictionary
# spsublist[service name][list of channel ids][a state value]
# dict = {'Handle': {'AvgRank' : 'value', 'channels' : ['1232', '43234']}
# 'twtv iddosu2x' : {'AvgRank' : '1082', 'channels' : ['2343', '54563']}}
#
mmrcurrentsub_request = [] # list of elements detailing the current sub request
datestring = datetime.now()
datestring = datestring.strftime("%m/%d/%Y-%H:%M:%S")
# replace _ with sapces
handle = handle.replace("_"," ")
print(f"[{datestring}]: {ctx.message.author.display_name} called '$mmrsub '{handle}'''")
# Only work on this if the user has supplied a service name to monitor, a value of NONE
# means nothing was specified
if handle != "NONE" and handle != "-list" and not handle.startswith('-del '):
print(f">> Querying status of '{handle}' to see if it exists")
handle_state = await get_mmr_status(handle)
if handle != "NONE":
if handle == "-list":
# List the serivces that this channel is subscribed to
# Read in mmrsublist
mmrsublist = ''
async with aiof.open('mmrsublist.dat', 'rb') as datafile:
pickled_mmrsublist = await datafile.read()
sublist = pickle.loads(pickled_mmrsublist)
for handle in sublist.keys():
print(f"current handle: {handle}")
for channel in sublist[handle]['channels']:
print(f">> {channel}")
if channel == ctx.channel.id:
print(f">>>> {channel} == {ctx.channel.id}")
mmrsublist += f"'{handle}' "
await ctx.send(f"This channel is subscribed to: {mmrsublist}")
elif handle.startswith('-del:'):
# Delete the service from this channels subscriptions
handle_toremove = handle[5:]
print(f"{handle_toremove}")
# Open the data file for read in
async with aiof.open('mmrsublist.dat', 'rb') as datafile:
pickled_mmrsublist = await datafile.read()
mmrsublist = pickle.loads(pickled_mmrsublist)
# We haven't found either the channel or servic; mark as false
found_handle = False
found_channel = False
# Iterate through the service names in the data
for handle in mmrsublist.keys():
# If the service we want to unsub from is the same as the service in the data, we need to search for the channel
if handle.lower() == handle_toremove.lower():
# We've found the service match, mark as true
found_handle = True
# Iterate through the channels that are subbed to this service
for channel in mmrsublist[handle]['channels']:
# If a channel listed in the service matches the current users channel id, we've found our match
if channel == ctx.channel.id:
# Marking channel as found
found_channel = True
# Get the proper name of the service
handle_toremove = handle
#Remove the current users channel from this service
mmrsublist[handle]['channels'].remove(ctx.channel.id)
# Break since we're done.
break
# If we got to the point of finding the channel, we're done.
if found_channel:
break
if found_handle and found_channel:
print(">> Saving dictionary to mmrsublist.dat")
async with aiof.open('mmrsublist.dat', 'wb') as datafile:
pickled_mmrsublist = pickle.dumps(mmrsublist, protocol=4)
await datafile.write(pickled_mmrsublist)
#await datafile.fsync()
await datafile.flush()
await ctx.send(f"This channel is unsubscribed from '{handle}' alerts.")
else:
await ctx.send(f"This channel is not subscribed to alerts for '{handle_toremove}''")
# If the service exists, proceed with adding it to the list.
elif handle_state != "handle not found":
print(f">> '{handle}' is a valid Hanlde on Whatismymmr.com.")
print(f">> Checking if it has already been subscribed to")
#await ctx.send(f"'{service_state['name']}' added to monitored services")
mmrcurrentsub_request.append(ctx.channel.id)
mmrcurrentsub_request.append(handle)
mmrcurrentsub_request.append(handle_state)
print(f">> Channel ID: {mmrcurrentsub_request[0]}")
print(f">> Handle: {mmrcurrentsub_request[1]}")
print(f">> Current Ranked Average: {mmrcurrentsub_request[2]}")
# read in data file containing dict of subscriptions
print(">> Checking for mmrsublist.dat")
if os.path.exists('mmrsublist.dat'):
print(">> Data file exists, reading it in.")
# Read in mmrsublist
async with aiof.open('mmrsublist.dat', 'rb') as datafile:
pickled_mmrsublist = await datafile.read()
mmrsublist = pickle.loads(pickled_mmrsublist)
print(f">> Checking if handle is already in datafile")
found_handle = False
found_channel = False
for handle in mmrsublist.keys():
print(f">> Does '{handle}'' == '{mmrcurrentsub_request[1]}'?")
if handle == mmrcurrentsub_request[1]:
found_handle = True
# This service matched what the user is trying to subscribe to
# Now we need to check if this is for the same channel
print(f">> Yes, checking if channel {mmrcurrentsub_request[0]} is already subscribed")
for channel in mmrsublist[handle]['channels']:
if channel == mmrcurrentsub_request[0]:
print(f">> Channel ({mmrcurrentsub_request[0]}) is already subscribed to {handle}")
await ctx.send(f"This channel is already subscribed to {handle} alerts")
found_channel = True
break
if not found_channel:
# Append the current channel id to the list for this service
print(f">> Handle exists, channel not subbed, adding handle '{mmrcurrentsub_request[1]}' to {ctx.channel.id}")
await ctx.send(f"{handle} has been added to monitored handles for this channel")
mmrsublist[handle]['channels'].append(mmrcurrentsub_request[0])
break
if not found_handle:
# Append the current channel id to the list for this service
print(f">> Handle does not exist, adding new entry for '{mmrcurrentsub_request[1]}' to {ctx.channel.id}")
await ctx.send(f"{mmrcurrentsub_request[1]} has been added to monitored handle for this channel")
#newsub = {}
#newsub[currentsub_request[1]] = {'state' : 'online', 'channels' : [currentsub_request[0]]}
mmrsublist[mmrcurrentsub_request[1]] = {'AvgRank' : mmrcurrentsub_request[2], 'channels' : [mmrcurrentsub_request[0]]}
else:
print(">> mmrsublist.dat does not exist, new file will be created")
# append new subscription to dict
print(">> Creating new dictionary")
mmrsublist[mmrcurrentsub_request[1]] = {'AvgRank' : mmrcurrentsub_request[2], 'channels' : [mmrcurrentsub_request[0]]}
print(f">> {handle} subscription has been saved")
await ctx.send(f"{handle} has been added to monitored handles for this channel")
#Write updated array to data file
print(">> Saving dictionary to mmrsublist.dat")
async with aiof.open('mmrsublist.dat', 'wb') as datafile:
pickled_mmrsublist = pickle.dumps(mmrsublist, protocol=4)
await datafile.write(pickled_mmrsublist)
#await datafile.fsync()
await datafile.flush()
print(">> Done")
#await ctx.send(f"'{service_state['name']}' added to monitored services")
else:
print(f">> '{handle}' does not exist, cancelling subscription")
await ctx.send(f"{handle} was not found")
async def get_mmr_status(mmrhandle):
# Get MMR status status via API
#need to replace spaces with %20 before just inserting into URL
mmrhandle.replace(" ", "%20")
mmrURL = ''.join(mmrURLBASE) + mmrhandle
response = requests.get(mmrURL, headers=mmrHEADERS)
try:
mmr_stats = json.loads(response.text)
except ValueError as e:
return "handle not found"
return mmr_stats['ranked']['avg']
async def MMR_Monitor():
# reads in "mmrsublist.dat" every 3 hours then iterates
# through to check for mmr status changes. This function will need to check
# that "spsublist.dat" exists and is not empty. This function should be called
# in bot.on_ready
# read in data file containing list of subscriptions
while True:
print("MMR Monitor: Reading in mmrsublist.dat")
if os.path.exists('mmrsublist.dat'):
async with aiof.open('mmrsublist.dat', 'rb') as datafile:
pickled_mmrsublist = await datafile.read()
mmrsublist = pickle.loads(pickled_mmrsublist)
for handle in mmrsublist.keys():
# service used to be subscription
status = await get_mmr_status(handle)
print(f"{handle} | {mmrsublist[handle]}")
print(f">> '{handle}'s Average Rank: {status} | Previous state: {mmrsublist[handle]['AvgRank']}")
if status != 'handle not found':
if status == mmrsublist[handle]['AvgRank']:
# nothing has changed, no alert needed
await asyncio.sleep(1)
elif not status != mmrsublist[handle]['AvgRank']:
# again, nothing has changed no alert needed
await asyncio.sleep(1)
else:
print(f">> Status of '{handle}' has changed, notifying subscribed channels")
if status > mmrsublist[handle]['AvgRank']:
mmrsublist[handle]['AvgRank'] = status
for channel in mmrsublist[handle]['channels']:
ctx = bot.get_channel(channel)
print(f">> Alerting {ctx} that '{handle}'s Average Rank has Increased!")
embed = discord.Embed(title=f"MMR Alert", description=f"{handle}'s ranked average increased to {status}!", color=0x00ff40)
await ctx.send(embed=embed)
elif status < mmrsublist[handle]['AvgRank']:
mmrsublist[handle]['AvgRank'] = status
for channel in mmrsublist[handle]['channels']:
ctx = bot.get_channel(channel)
print(f">> Alerting {ctx} that '{handle}'s Average Rank has Decreased!")
embed = discord.Embed(title=f"MMR Alert", description=f"{handle}'s ranked average decreased to {status}!", color=0xff2200)
await ctx.send(embed=embed)
else:
for channel in mmrsublist[handle]['channels']:
ctx = bot.get_channel(channel)
print(f">> Alerting {ctx} that {handle}'s rank is an unknown state")
embed = discord.Embed(title=f"MMR Alert", description=f"{handle}'s rank is in an unknown state!", color=0xffff00)
await ctx.send(embed=embed)
print(">> Done")
#new_spsublist.append(subscription)
# Write status changes to spsublist.dat
async with aiof.open('mmrsublist.dat', 'wb') as datafile:
pickled_mmrsublist = pickle.dumps(mmrsublist)
await datafile.write(pickled_mmrsublist)
#await datafile.fsync()
await datafile.flush()
else:
print(">> mmrsublist.dat does not exist, nothing to do.")
# 10800 seconds == 3 hours :)
await asyncio.sleep(int(mmr_checker_interval))
#
#
#
@bot.command() @bot.command()
async def help(ctx): async def help(ctx):
embed = discord.Embed(title="R0b3BOT", description="List of commands are:", color=0xeee657) embed = discord.Embed(title='R0b3BOT Core & Debug Commands:', description="Core commands for info and debug", color=0xeee657)
embed.add_field(name=f"{BOT_COMMAND_PREFIX}info", value="Gives a little info about the bot", inline=False)
embed.add_field(name=f"{BOT_COMMAND_PREFIX}help", value="Gives this message", inline=False)
embed.add_field(name=f"{BOT_COMMAND_PREFIX}last_error", value="Will display the real error message the bot has last encountered for additional debugging info")
await ctx.send(embed=embed)
embed = discord.Embed(title="R0b3BOT Sound Commands", description="To play a sound in a chat channel, use one of the following:", color=0xeee657)
embed.add_field(name=f"{BOT_COMMAND_PREFIX}printstat", value="Uploads a snapshot of Rich's 3D printer and current stats", inline=False) embed.add_field(name=f"{BOT_COMMAND_PREFIX}printstat", value="Uploads a snapshot of Rich's 3D printer and current stats", inline=False)
embed.add_field(name=f"{BOT_COMMAND_PREFIX}explain", value="Displays Dalek EXPLAIN gif", inline=False) embed.add_field(name=f"{BOT_COMMAND_PREFIX}explain", value="Displays Dalek EXPLAIN gif", inline=False)
embed.add_field(name=f"{BOT_COMMAND_PREFIX}holyshit", value="Displays Marty McFly HOLY SHIT gif", inline=False) embed.add_field(name=f"{BOT_COMMAND_PREFIX}holyshit", value="Displays Marty McFly HOLY SHIT gif", inline=False)
@@ -910,14 +1206,22 @@ async def help(ctx):
embed.add_field(name=f"{BOT_COMMAND_PREFIX}trololo @member", value="Plays a clip of Trololo song", inline=False) embed.add_field(name=f"{BOT_COMMAND_PREFIX}trololo @member", value="Plays a clip of Trololo song", inline=False)
embed.add_field(name=f"{BOT_COMMAND_PREFIX}leeroy @member", value="Plays Leeeerrroooyyy Jenkins clip", inline=False) embed.add_field(name=f"{BOT_COMMAND_PREFIX}leeroy @member", value="Plays Leeeerrroooyyy Jenkins clip", inline=False)
embed.add_field(name=f"{BOT_COMMAND_PREFIX}eia @member", value="Plays 'Everything is Awesome' song clip") embed.add_field(name=f"{BOT_COMMAND_PREFIX}eia @member", value="Plays 'Everything is Awesome' song clip")
embed.add_field(name=f"{BOT_COMMAND_PREFIX}info", value="Gives a little info about the bot", inline=False) embed.add_field(name=f"{BOT_COMMAND_PREFIX}heavy @member", value="Plays 'Poppy ooo heavy'")
embed.add_field(name=f"{BOT_COMMAND_PREFIX}help", value="Gives this message", inline=False) embed.add_field(name=f"{BOT_COMMAND_PREFIX}iran @member", value="Plays Trump 'I Ran'")
embed.add_field(name=f"{BOT_COMMAND_PREFIX}last_error", value="Will display the real error message the bot has last encountered for additional debugging info") embed.add_field(name=f"{BOT_COMMAND_PREFIX}big @member", value="Plays 'Wiz Khalifa clip'")
await ctx.send(embed=embed)
embed = discord.Embed(title="A note about sound clips:", description="Sound clips are only played in voice channels. If a user is not specified when calling the command, the sound will played in the channel of that issuing user is currently joined to. When a username is specified, the bot will play the sound in the channel that user is currently in.")
await ctx.send(embed=embed)
embed = discord.Embed(title="StatPing Service Monitor Commands", description="Commands for managing the StatPing Service Monitor", color=0xeee657)
embed.add_field(name=f"{BOT_COMMAND_PREFIX}spstatus servicename", value="Retrieves status of service from StatPing") embed.add_field(name=f"{BOT_COMMAND_PREFIX}spstatus servicename", value="Retrieves status of service from StatPing")
embed.add_field(name=f"{BOT_COMMAND_PREFIX}spsub service", value="Allows user to subscribe to service status change alerts for the channel. Can replace <service> with -list and -del:service to manage alerts. NOTICE:Replace spaces in service names w/ '_'!") embed.add_field(name=f"{BOT_COMMAND_PREFIX}spsub service", value="Allows user to subscribe to service status change alerts for the channel. Can replace <service> with -list and -del:service to manage alerts. NOTICE:Replace spaces in service names w/ '_'!")
await ctx.send(embed=embed) await ctx.send(embed=embed)
embed = discord.Embed(title="A note about sound clips:", description="Sound clips are only played in voice channels. If a user is not specified when calling the command, the sound will played in the channel of that issuing user is currently joined to. When a username is specified, the bot will play the sound in the channel that user is currently in.") embed = discord.Embed(title="MMR Monitor Commands", description="Commands for managing the MMR Checker", color=0xeee657)
embed.add_field(name=f"{BOT_COMMAND_PREFIX}mmrstatus handle", value="Queries the MMR API for the handle specified and returns the current Ranked Average")
embed.add_field(name=f"{BOT_COMMAND_PREFIX}mmrsub handle", value="Subscribe to receive alerts of ranked average changes for the specified handle. Can run command with just '-list' to list handle the current channel is subbed to. Use -del:service to unsub from a handle. NOTICE:Replace spaces in service names w/ '_'!")
await ctx.send(embed=embed) await ctx.send(embed=embed)
# Function to run shell command and return stdout or sterr # Function to run shell command and return stdout or sterr
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.