mirror of
https://github.com/Cog-Creators/Red-DiscordBot.git
synced 2025-11-07 11:48:55 -05:00
Merge remote-tracking branch 'upstream/develop' into develop
This commit is contained in:
commit
7fd83ecaf0
@ -13,6 +13,7 @@ import re
|
|||||||
import aiohttp
|
import aiohttp
|
||||||
from bs4 import BeautifulSoup
|
from bs4 import BeautifulSoup
|
||||||
import json
|
import json
|
||||||
|
import time
|
||||||
|
|
||||||
if not discord.opus.is_loaded():
|
if not discord.opus.is_loaded():
|
||||||
discord.opus.load_opus('libopus-0.dll')
|
discord.opus.load_opus('libopus-0.dll')
|
||||||
@ -42,6 +43,7 @@ class Audio:
|
|||||||
self.current = -1 #current track index in self.playlist
|
self.current = -1 #current track index in self.playlist
|
||||||
self.downloader = {"DONE" : False, "TITLE" : False, "ID" : False, "URL" : False, "DURATION" : False, "DOWNLOADING" : False}
|
self.downloader = {"DONE" : False, "TITLE" : False, "ID" : False, "URL" : False, "DURATION" : False, "DOWNLOADING" : False}
|
||||||
self.skip_votes = []
|
self.skip_votes = []
|
||||||
|
self.cleanup_timer = int(time.perf_counter())
|
||||||
|
|
||||||
self.sing = ["https://www.youtube.com/watch?v=zGTkAVsrfg8", "https://www.youtube.com/watch?v=cGMWL8cOeAU",
|
self.sing = ["https://www.youtube.com/watch?v=zGTkAVsrfg8", "https://www.youtube.com/watch?v=cGMWL8cOeAU",
|
||||||
"https://www.youtube.com/watch?v=vFrjMq4aL-g", "https://www.youtube.com/watch?v=WROI5WYBU_A",
|
"https://www.youtube.com/watch?v=vFrjMq4aL-g", "https://www.youtube.com/watch?v=WROI5WYBU_A",
|
||||||
@ -344,7 +346,7 @@ class Audio:
|
|||||||
|
|
||||||
@audioset.command()
|
@audioset.command()
|
||||||
async def maxlength(self, length : int):
|
async def maxlength(self, length : int):
|
||||||
"""Maximum track length for requested links"""
|
"""Maximum track length (seconds) for requested links"""
|
||||||
self.settings["MAX_LENGTH"] = length
|
self.settings["MAX_LENGTH"] = length
|
||||||
await self.bot.say("Maximum length is now " + str(length) + " seconds.")
|
await self.bot.say("Maximum length is now " + str(length) + " seconds.")
|
||||||
fileIO("data/audio/settings.json", "save", self.settings)
|
fileIO("data/audio/settings.json", "save", self.settings)
|
||||||
@ -359,6 +361,45 @@ class Audio:
|
|||||||
else:
|
else:
|
||||||
await self.bot.say("Volume must be between 0 and 1. Example: 0.40")
|
await self.bot.say("Volume must be between 0 and 1. Example: 0.40")
|
||||||
|
|
||||||
|
@audioset.command()
|
||||||
|
@checks.is_owner()
|
||||||
|
async def maxcache(self, size : int):
|
||||||
|
"""Sets the maximum audio cache size (megabytes)
|
||||||
|
|
||||||
|
If set to 0, auto cleanup is disabled."""
|
||||||
|
self.settings["MAX_CACHE"] = size
|
||||||
|
fileIO("data/audio/settings.json", "save", self.settings)
|
||||||
|
if not size:
|
||||||
|
await self.bot.say("Auto audio cache cleanup disabled.")
|
||||||
|
else:
|
||||||
|
await self.bot.say("Maximum audio cache size has been set to " + str(size) + "MB.")
|
||||||
|
|
||||||
|
|
||||||
|
@commands.group(pass_context=True)
|
||||||
|
@checks.is_owner()
|
||||||
|
async def cache(self, ctx):
|
||||||
|
"""Audio cache management"""
|
||||||
|
if ctx.invoked_subcommand is None:
|
||||||
|
await self.bot.say("Current audio cache size: " + str(self.cache_size()) + "MB" )
|
||||||
|
|
||||||
|
@cache.command(name="empty")
|
||||||
|
async def cache_delete(self):
|
||||||
|
"""Empties audio cache"""
|
||||||
|
self.empty_cache()
|
||||||
|
await self.bot.say("Cache emptied.")
|
||||||
|
|
||||||
|
def empty_cache(self):
|
||||||
|
files = os.listdir("data/audio/cache")
|
||||||
|
for f in files:
|
||||||
|
os.unlink("data/audio/cache/" + f)
|
||||||
|
|
||||||
|
def cache_size(self):
|
||||||
|
total = [os.path.getsize("data/audio/cache/" + f) for f in os.listdir("data/audio/cache")]
|
||||||
|
size = 0
|
||||||
|
for f in total:
|
||||||
|
size += f
|
||||||
|
return int(size / (1024*1024.0))
|
||||||
|
|
||||||
async def play_video(self, link):
|
async def play_video(self, link):
|
||||||
self.downloader = {"DONE" : False, "TITLE" : False, "ID" : False, "URL": False, "DURATION" : False, "DOWNLOADING" : False}
|
self.downloader = {"DONE" : False, "TITLE" : False, "ID" : False, "URL": False, "DURATION" : False, "DOWNLOADING" : False}
|
||||||
if "https://" in link or "http://" in link:
|
if "https://" in link or "http://" in link:
|
||||||
@ -452,6 +493,15 @@ class Audio:
|
|||||||
|
|
||||||
async def incoming_messages(self, msg): # Workaround, need to fix
|
async def incoming_messages(self, msg): # Workaround, need to fix
|
||||||
if msg.author.id != self.bot.user.id:
|
if msg.author.id != self.bot.user.id:
|
||||||
|
|
||||||
|
if self.settings["MAX_CACHE"] != 0:
|
||||||
|
if abs(self.cleanup_timer - int(time.perf_counter())) >= 900 and not self.music_player.is_playing() and not self.downloader["DOWNLOADING"]: # checks cache's size every 15 minutes
|
||||||
|
self.cleanup_timer = int(time.perf_counter())
|
||||||
|
if self.cache_size() >= self.settings["MAX_CACHE"]:
|
||||||
|
self.empty_cache()
|
||||||
|
print("Cache emptied.")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if msg.channel.is_private and msg.attachments != []:
|
if msg.channel.is_private and msg.attachments != []:
|
||||||
await self.transfer_playlist(msg)
|
await self.transfer_playlist(msg)
|
||||||
@ -580,11 +630,21 @@ def check_folders():
|
|||||||
|
|
||||||
def check_files():
|
def check_files():
|
||||||
|
|
||||||
settings = {"VOLUME" : 0.5, "MAX_LENGTH" : 3700, "QUEUE_MODE" : True}
|
default = {"VOLUME" : 0.5, "MAX_LENGTH" : 3700, "QUEUE_MODE" : True, "MAX_CACHE" : 0}
|
||||||
|
settings_path = "data/audio/settings.json"
|
||||||
|
|
||||||
if not os.path.isfile("data/audio/settings.json"):
|
if not os.path.isfile(settings_path):
|
||||||
print("Creating default audio settings.json...")
|
print("Creating default audio settings.json...")
|
||||||
fileIO("data/audio/settings.json", "save", settings)
|
fileIO(settings_path, "save", default)
|
||||||
|
else: #consistency check
|
||||||
|
current = fileIO(settings_path, "load")
|
||||||
|
if current.keys() != default.keys():
|
||||||
|
for key in default.keys():
|
||||||
|
if key not in current.keys():
|
||||||
|
current[key] = default[key]
|
||||||
|
print("Adding " + str(key) + " field to audio settings.json")
|
||||||
|
fileIO(settings_path, "save", current)
|
||||||
|
|
||||||
|
|
||||||
allowed = ["^(https:\/\/www\\.youtube\\.com\/watch\\?v=...........*)", "^(https:\/\/youtu.be\/...........*)",
|
allowed = ["^(https:\/\/www\\.youtube\\.com\/watch\\?v=...........*)", "^(https:\/\/youtu.be\/...........*)",
|
||||||
"^(https:\/\/youtube\\.com\/watch\\?v=...........*)", "^(https:\/\/soundcloud\\.com\/.*)"]
|
"^(https:\/\/youtube\\.com\/watch\\?v=...........*)", "^(https:\/\/soundcloud\\.com\/.*)"]
|
||||||
|
|||||||
@ -12,8 +12,8 @@ class CustomCommands:
|
|||||||
self.bot = bot
|
self.bot = bot
|
||||||
self.c_commands = fileIO("data/customcom/commands.json", "load")
|
self.c_commands = fileIO("data/customcom/commands.json", "load")
|
||||||
|
|
||||||
@checks.mod_or_permissions()
|
|
||||||
@commands.command(pass_context=True, no_pm=True)
|
@commands.command(pass_context=True, no_pm=True)
|
||||||
|
@checks.mod_or_permissions(manage_server=True)
|
||||||
async def addcom(self, ctx, command : str, *text):
|
async def addcom(self, ctx, command : str, *text):
|
||||||
"""Adds a custom command
|
"""Adds a custom command
|
||||||
|
|
||||||
@ -37,8 +37,8 @@ class CustomCommands:
|
|||||||
else:
|
else:
|
||||||
await self.bot.say("`This command already exists. Use editcom to edit it.`")
|
await self.bot.say("`This command already exists. Use editcom to edit it.`")
|
||||||
|
|
||||||
@checks.mod_or_permissions()
|
|
||||||
@commands.command(pass_context=True, no_pm=True)
|
@commands.command(pass_context=True, no_pm=True)
|
||||||
|
@checks.mod_or_permissions(manage_server=True)
|
||||||
async def editcom(self, ctx, command : str, *text):
|
async def editcom(self, ctx, command : str, *text):
|
||||||
"""Edits a custom command
|
"""Edits a custom command
|
||||||
|
|
||||||
@ -63,8 +63,8 @@ class CustomCommands:
|
|||||||
else:
|
else:
|
||||||
await self.bot.say("`There are no custom commands in this server. Use addcom [command] [text]`")
|
await self.bot.say("`There are no custom commands in this server. Use addcom [command] [text]`")
|
||||||
|
|
||||||
@checks.mod_or_permissions()
|
|
||||||
@commands.command(pass_context=True, no_pm=True)
|
@commands.command(pass_context=True, no_pm=True)
|
||||||
|
@checks.mod_or_permissions(manage_server=True)
|
||||||
async def delcom(self, ctx, command : str):
|
async def delcom(self, ctx, command : str):
|
||||||
"""Deletes a custom command
|
"""Deletes a custom command
|
||||||
|
|
||||||
|
|||||||
108
cogs/mod.py
108
cogs/mod.py
@ -12,6 +12,7 @@ class Mod:
|
|||||||
self.whitelist_list = fileIO("data/mod/whitelist.json", "load")
|
self.whitelist_list = fileIO("data/mod/whitelist.json", "load")
|
||||||
self.blacklist_list = fileIO("data/mod/blacklist.json", "load")
|
self.blacklist_list = fileIO("data/mod/blacklist.json", "load")
|
||||||
self.ignore_list = fileIO("data/mod/ignorelist.json", "load")
|
self.ignore_list = fileIO("data/mod/ignorelist.json", "load")
|
||||||
|
self.filter = fileIO("data/mod/filter.json", "load")
|
||||||
|
|
||||||
@commands.command(no_pm=True)
|
@commands.command(no_pm=True)
|
||||||
@checks.admin_or_permissions(kick_members=True)
|
@checks.admin_or_permissions(kick_members=True)
|
||||||
@ -261,6 +262,105 @@ class Mod:
|
|||||||
msg += str(len(self.ignore_list["SERVERS"])) + " servers\n```\n"
|
msg += str(len(self.ignore_list["SERVERS"])) + " servers\n```\n"
|
||||||
return msg
|
return msg
|
||||||
|
|
||||||
|
@commands.group(name="filter", pass_context=True, no_pm=True)
|
||||||
|
@checks.mod_or_permissions(manage_messages=True)
|
||||||
|
async def _filter(self, ctx):
|
||||||
|
"""Adds/removes words from filter
|
||||||
|
|
||||||
|
Use double quotes to add/remove sentences
|
||||||
|
Using this command with no subcommands will send
|
||||||
|
the list of the server's filtered words."""
|
||||||
|
if ctx.invoked_subcommand is None:
|
||||||
|
await self.bot.say("Type help filter for info.")
|
||||||
|
server = ctx.message.server
|
||||||
|
author = ctx.message.author
|
||||||
|
msg = ""
|
||||||
|
if server.id in self.filter.keys():
|
||||||
|
if self.filter[server.id] != []:
|
||||||
|
word_list = self.filter[server.id]
|
||||||
|
for w in word_list:
|
||||||
|
msg += '"' + w + '" '
|
||||||
|
await self.bot.send_message(author, "Words filtered in this server: " + msg)
|
||||||
|
|
||||||
|
@_filter.command(name="add", pass_context=True)
|
||||||
|
async def filter_add(self, ctx, *words : str):
|
||||||
|
"""Adds words to the filter
|
||||||
|
|
||||||
|
Use double quotes to add sentences
|
||||||
|
Examples:
|
||||||
|
filter add word1 word2 word3
|
||||||
|
filter add \"This is a sentence\""""
|
||||||
|
if words == ():
|
||||||
|
await self.bot.say("Type help filter add for info.")
|
||||||
|
return
|
||||||
|
server = ctx.message.server
|
||||||
|
added = 0
|
||||||
|
if server.id not in self.filter.keys():
|
||||||
|
self.filter[server.id] = []
|
||||||
|
for w in words:
|
||||||
|
if w.lower() not in self.filter[server.id] and w != "":
|
||||||
|
self.filter[server.id].append(w.lower())
|
||||||
|
added += 1
|
||||||
|
if added:
|
||||||
|
fileIO("data/mod/filter.json", "save", self.filter)
|
||||||
|
await self.bot.say("Words added to filter.")
|
||||||
|
else:
|
||||||
|
await self.bot.say("Words already in the filter.")
|
||||||
|
|
||||||
|
@_filter.command(name="remove", pass_context=True)
|
||||||
|
async def filter_remove(self, ctx, *words : str):
|
||||||
|
"""Remove words from the filter
|
||||||
|
|
||||||
|
Use double quotes to remove sentences
|
||||||
|
Examples:
|
||||||
|
filter remove word1 word2 word3
|
||||||
|
filter remove \"This is a sentence\""""
|
||||||
|
if words == ():
|
||||||
|
await self.bot.say("Type help filter remove for info.")
|
||||||
|
return
|
||||||
|
server = ctx.message.server
|
||||||
|
removed = 0
|
||||||
|
if server.id not in self.filter.keys():
|
||||||
|
await self.bot.say("There are no filtered words in this server.")
|
||||||
|
return
|
||||||
|
for w in words:
|
||||||
|
if w.lower() in self.filter[server.id]:
|
||||||
|
self.filter[server.id].remove(w.lower())
|
||||||
|
removed += 1
|
||||||
|
if removed:
|
||||||
|
fileIO("data/mod/filter.json", "save", self.filter)
|
||||||
|
await self.bot.say("Words removed from filter.")
|
||||||
|
else:
|
||||||
|
await self.bot.say("Those words weren't in the filter.")
|
||||||
|
|
||||||
|
def immune_from_filter(self, message):
|
||||||
|
user = message.author
|
||||||
|
if user.id == checks.settings["OWNER"]:
|
||||||
|
return True
|
||||||
|
elif discord.utils.get(user.roles, name=checks.settings["ADMIN_ROLE"]):
|
||||||
|
return True
|
||||||
|
elif discord.utils.get(user.roles, name=checks.settings["MOD_ROLE"]):
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
async def check_filter(self, message):
|
||||||
|
if message.channel.is_private:
|
||||||
|
return
|
||||||
|
server = message.server
|
||||||
|
can_delete = message.channel.permissions_for(server.me).manage_messages
|
||||||
|
|
||||||
|
if message.author.id == self.bot.user.id or self.immune_from_filter(message) or not can_delete: # Owner, admins and mods are immune to the filter
|
||||||
|
return
|
||||||
|
|
||||||
|
if server.id in self.filter.keys():
|
||||||
|
for w in self.filter[server.id]:
|
||||||
|
if w in message.content.lower():
|
||||||
|
try: # Something else in discord.py is throwing a 404 error after deletion
|
||||||
|
await self.bot.delete_message(message)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
print("Message deleted. Filtered: " + w )
|
||||||
|
|
||||||
def check_folders():
|
def check_folders():
|
||||||
folders = ("data", "data/mod/")
|
folders = ("data", "data/mod/")
|
||||||
@ -284,7 +384,13 @@ def check_files():
|
|||||||
print("Creating empty ignorelist.json...")
|
print("Creating empty ignorelist.json...")
|
||||||
fileIO("data/mod/ignorelist.json", "save", ignore_list)
|
fileIO("data/mod/ignorelist.json", "save", ignore_list)
|
||||||
|
|
||||||
|
if not os.path.isfile("data/mod/filter.json"):
|
||||||
|
print("Creating empty filter.json...")
|
||||||
|
fileIO("data/mod/filter.json", "save", {})
|
||||||
|
|
||||||
def setup(bot):
|
def setup(bot):
|
||||||
check_folders()
|
check_folders()
|
||||||
check_files()
|
check_files()
|
||||||
bot.add_cog(Mod(bot))
|
n = Mod(bot)
|
||||||
|
bot.add_listener(n.check_filter, "on_message")
|
||||||
|
bot.add_cog(n)
|
||||||
|
|||||||
@ -2,7 +2,6 @@ from discord.ext import commands
|
|||||||
import discord.utils
|
import discord.utils
|
||||||
import os.path
|
import os.path
|
||||||
import json
|
import json
|
||||||
import __main__
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# This is a modified version of checks.py, originally made by Rapptz
|
# This is a modified version of checks.py, originally made by Rapptz
|
||||||
@ -11,16 +10,14 @@ import __main__
|
|||||||
# https://github.com/Rapptz/RoboDanny/tree/async
|
# https://github.com/Rapptz/RoboDanny/tree/async
|
||||||
#
|
#
|
||||||
|
|
||||||
main_path = os.path.dirname(os.path.realpath(__main__.__file__))
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with open(main_path + "/data/red/settings.json", "r") as f:
|
with open("data/red/settings.json", "r") as f:
|
||||||
settings = json.loads(f.read())
|
settings = json.loads(f.read())
|
||||||
except:
|
except:
|
||||||
settings = {"OWNER" : False, "ADMIN_ROLE" : False, "MOD_ROLE" : False}
|
settings = {"OWNER" : False, "ADMIN_ROLE" : False, "MOD_ROLE" : False}
|
||||||
|
|
||||||
def is_owner_check(ctx):
|
def is_owner_check(ctx):
|
||||||
return ctx.message.author.id == owner
|
return ctx.message.author.id == settings["OWNER"]
|
||||||
|
|
||||||
def is_owner():
|
def is_owner():
|
||||||
return commands.check(is_owner_check)
|
return commands.check(is_owner_check)
|
||||||
|
|||||||
25
red.py
25
red.py
@ -58,7 +58,9 @@ async def on_message(message):
|
|||||||
@bot.command()
|
@bot.command()
|
||||||
@checks.is_owner()
|
@checks.is_owner()
|
||||||
async def load(*, module : str):
|
async def load(*, module : str):
|
||||||
"""Loads a module"""
|
"""Loads a module
|
||||||
|
|
||||||
|
Example: load cogs.mod"""
|
||||||
module = module.strip()
|
module = module.strip()
|
||||||
if not module in list_cogs():
|
if not module in list_cogs():
|
||||||
await bot.say("That module doesn't exist.")
|
await bot.say("That module doesn't exist.")
|
||||||
@ -74,7 +76,9 @@ async def load(*, module : str):
|
|||||||
@bot.command()
|
@bot.command()
|
||||||
@checks.is_owner()
|
@checks.is_owner()
|
||||||
async def unload(*, module : str):
|
async def unload(*, module : str):
|
||||||
"""Unloads a module"""
|
"""Unloads a module
|
||||||
|
|
||||||
|
Example: unload cogs.mod"""
|
||||||
module = module.strip()
|
module = module.strip()
|
||||||
if not module in list_cogs():
|
if not module in list_cogs():
|
||||||
await bot.say("That module doesn't exist.")
|
await bot.say("That module doesn't exist.")
|
||||||
@ -90,7 +94,9 @@ async def unload(*, module : str):
|
|||||||
@bot.command(name="reload")
|
@bot.command(name="reload")
|
||||||
@checks.is_owner()
|
@checks.is_owner()
|
||||||
async def _reload(*, module : str):
|
async def _reload(*, module : str):
|
||||||
"""Reloads a module"""
|
"""Reloads a module
|
||||||
|
|
||||||
|
Example: reload cogs.mod"""
|
||||||
module = module.strip()
|
module = module.strip()
|
||||||
if not module in list_cogs():
|
if not module in list_cogs():
|
||||||
await bot.say("That module doesn't exist.")
|
await bot.say("That module doesn't exist.")
|
||||||
@ -168,6 +174,19 @@ async def join(invite_url : discord.Invite):
|
|||||||
except discord.HTTPException:
|
except discord.HTTPException:
|
||||||
await bot.say("I wasn't able to accept the invite. Try again.")
|
await bot.say("I wasn't able to accept the invite. Try again.")
|
||||||
|
|
||||||
|
@bot.command(pass_context=True)
|
||||||
|
@checks.is_owner()
|
||||||
|
async def leave(ctx):
|
||||||
|
"""Leaves server"""
|
||||||
|
message = ctx.message
|
||||||
|
await bot.say("Are you sure you want me to leave this server? Type yes to confirm")
|
||||||
|
response = await bot.wait_for_message(author=message.author)
|
||||||
|
if response.content.lower().strip() == "yes":
|
||||||
|
await bot.say("Alright. Bye :wave:")
|
||||||
|
await bot.leave_server(message.server)
|
||||||
|
else:
|
||||||
|
await bot.say("Ok I'll stay here then.")
|
||||||
|
|
||||||
@bot.command()
|
@bot.command()
|
||||||
@checks.is_owner()
|
@checks.is_owner()
|
||||||
async def setprefix(*text):
|
async def setprefix(*text):
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user