mirror of
https://github.com/brandons209/Red-bot-Cogs.git
synced 2024-04-29 18:13:31 +12:00
big 3.4 update part 1, still need to add data removal handling
This commit is contained in:
parent
9146ce4efa
commit
e9f7b86be9
|
@ -1,11 +1,12 @@
|
|||
{
|
||||
"author": ["Malarne (Malarne#1418)"],
|
||||
"min_bot_version": "3.0.2",
|
||||
"min_bot_version": "3.4.0",
|
||||
"description": "A leveler cog for Red V3\nInspired by Stevy's v2 leveler cog\nPlease consult the docs at ayrobot.netlify.com for setup informations.\nThanks for using my cog !\nNB:Channel whitelist is enabled by default, you can manage that under `[p]levelerset channel whitelist` command !",
|
||||
"hidden": false,
|
||||
"install_msg": "Thank you for installing this leveler !\nPlease consult the docs at https://discord-cogs.readthedocs.io/en/latest/leveler.html for setup informations.\nPlease note that this cog come with bundled data, mostly the font for profile image.",
|
||||
"required_cogs": {},
|
||||
"requirements": ["pillow"],
|
||||
"short": "Leveler tool, better than MEE6",
|
||||
"tags": ["leveler", "pillow", "fun"]
|
||||
"tags": ["leveler", "pillow", "fun"],
|
||||
"end_user_data_statement": "Stores some level info like experience, profile description/picture, and message ID of user's last message in guild."
|
||||
}
|
||||
|
|
|
@ -287,6 +287,8 @@ class Leveler(commands.Cog):
|
|||
await ctx.send(file=discord.File(img))
|
||||
|
||||
async def listener(self, message):
|
||||
if await self.bot.cog_disabled_in_guild(self, message.guild):
|
||||
return
|
||||
if type(message.author) != discord.Member:
|
||||
# throws an error when webhooks talk, this fixes it
|
||||
return
|
||||
|
@ -330,7 +332,10 @@ class Leveler(commands.Cog):
|
|||
await self.profiles._set_user_lastmessage(message.author, timenow)
|
||||
lvl = await self.profiles._get_level(message.author)
|
||||
if lvl == oldlvl + 1 and await self.profiles.data.guild(message.guild).lvlup_announce():
|
||||
await message.channel.send(_("{} is now level {} !".format(message.author.mention, lvl)))
|
||||
await message.channel.send(
|
||||
_("{} is now level {} !".format(message.author.mention, lvl)),
|
||||
allowed_mentions=discord.AllowedMentions.all(),
|
||||
)
|
||||
await self.profiles._check_exp(message.author)
|
||||
await self.profiles._check_role_member(message.author)
|
||||
|
||||
|
@ -644,5 +649,7 @@ class Leveler(commands.Cog):
|
|||
# Listeners
|
||||
@commands.Cog.listener()
|
||||
async def on_member_remove(self, member):
|
||||
if await self.bot.cog_disabled_in_guild(self, member.guild):
|
||||
return
|
||||
# reset level stats on leave.
|
||||
await self.profiles.data.member(member).clear()
|
||||
|
|
|
@ -5,13 +5,14 @@ from redbot.core.data_manager import cog_data_path
|
|||
from redbot.core.utils.mod import is_mod_or_superior
|
||||
import discord
|
||||
|
||||
from .time_utils import *
|
||||
from .utils import *
|
||||
from datetime import datetime
|
||||
from dateutil.relativedelta import relativedelta
|
||||
import time
|
||||
import os
|
||||
import asyncio
|
||||
import glob
|
||||
import io
|
||||
|
||||
# plotting
|
||||
from bisect import bisect_left
|
||||
|
@ -46,66 +47,6 @@ DELETE_AUDIT_TEMPLATE = "@{0.name}#{0.discriminator}(id:{0.id}) deleted message
|
|||
MAX_LINES = 50000
|
||||
|
||||
|
||||
def get_all_names(guild_files, user):
|
||||
names = [str(user)]
|
||||
for log in guild_files:
|
||||
if not os.path.exists(log):
|
||||
continue
|
||||
with open(log, "r") as f:
|
||||
for line in f:
|
||||
if str(user.id) in line:
|
||||
# user change their name
|
||||
if "Member username:" in line:
|
||||
username = line.strip().split('"')
|
||||
discrim = username[1].split("#")[-1]
|
||||
username = username[-2] + "#" + discrim
|
||||
names.append(username)
|
||||
# user changed their 4 digit discriminator
|
||||
elif "Member discriminator:" in line:
|
||||
username = line.strip().split('"')[-2]
|
||||
names.append(username)
|
||||
# starting name
|
||||
elif "Member join:" in line:
|
||||
username = line.strip().split("@")[-1].split("#")
|
||||
username = username[0] + "#" + username[1].split(" ")[0]
|
||||
if username is not str(user):
|
||||
names.append(username)
|
||||
return set(names)
|
||||
|
||||
|
||||
def format_list(*items, join="and", delim=", "):
|
||||
if len(items) > 1:
|
||||
return (" %s " % join).join((delim.join(items[:-1]), items[-1]))
|
||||
elif items:
|
||||
return items[0]
|
||||
else:
|
||||
return ""
|
||||
|
||||
|
||||
class LogHandle:
|
||||
"""basic wrapper for logfile handles, used to keep track of stale handles"""
|
||||
|
||||
def __init__(self, path, time=None, mode="a", buf=1):
|
||||
self.handle = open(path, mode, buf, errors="backslashreplace")
|
||||
self.lock = asyncio.Lock()
|
||||
|
||||
if time:
|
||||
self.time = time
|
||||
else:
|
||||
self.time = datetime.fromtimestamp(os.path.getmtime(path))
|
||||
|
||||
async def write(self, value):
|
||||
async with self.lock:
|
||||
self._write(value)
|
||||
|
||||
def close(self):
|
||||
self.handle.close()
|
||||
|
||||
def _write(self, value):
|
||||
self.time = datetime.utcnow()
|
||||
self.handle.write(value)
|
||||
|
||||
|
||||
class ActivityLogger(commands.Cog):
|
||||
"""Log activity seen by bot"""
|
||||
|
||||
|
@ -259,7 +200,7 @@ class ActivityLogger(commands.Cog):
|
|||
|
||||
if is_mod:
|
||||
try:
|
||||
await ctx.send(embed=data)
|
||||
await ctx.send(embed=data, allowed_mentions=discord.AllowedMentions.all())
|
||||
except discord.HTTPException:
|
||||
await ctx.send("I need the `Embed links` permission to send this")
|
||||
else:
|
||||
|
@ -317,19 +258,10 @@ class ActivityLogger(commands.Cog):
|
|||
)
|
||||
msg += f"Bans: `{bans}`, Kicks: `{kicks}`, Mutes: `{mutes}`, Warnings: `{warns}`"
|
||||
if len(names) > 1:
|
||||
return msg, format_list(*names)
|
||||
return msg, humanize_list(names)
|
||||
|
||||
return msg, None
|
||||
|
||||
@commands.command(name="fixavglen")
|
||||
@checks.is_owner()
|
||||
async def fixavglen(self, ctx):
|
||||
for guild in self.bot.guilds:
|
||||
for member in guild.members:
|
||||
async with self.config.member(member).stats() as stats:
|
||||
stats["avg_len"] = stats["total_msg"] - stats["bot_cmd"]
|
||||
await ctx.tick()
|
||||
|
||||
@commands.command(name="graphstats")
|
||||
@checks.mod()
|
||||
@commands.guild_only()
|
||||
|
@ -1141,14 +1073,14 @@ class ActivityLogger(commands.Cog):
|
|||
await self.config.guild(ctx.guild).prefixes.set([ctx.clean_prefix])
|
||||
self.cache[ctx.guild.id]["prefixes"] = [ctx.clean_prefix]
|
||||
return
|
||||
await ctx.send("Current Prefixes: " + format_list(*curr, delim=", "))
|
||||
await ctx.send("Current Prefixes: " + humanize_list(curr))
|
||||
return
|
||||
|
||||
prefixes = [p for p in prefixes.split(" ")]
|
||||
await self.config.guild(ctx.guild).prefixes.set(prefixes)
|
||||
self.cache[ctx.guild.id]["prefixes"] = prefixes
|
||||
prefixes = [f"`{p}`" for p in prefixes]
|
||||
await ctx.send("Prefixes set to: " + format_list(*prefixes, delim=", "))
|
||||
await ctx.send("Prefixes set to: " + humanize_list(prefixes))
|
||||
|
||||
@logset.command(name="rotation")
|
||||
async def set_rotation(self, ctx, freq: str = None):
|
||||
|
@ -1434,16 +1366,22 @@ class ActivityLogger(commands.Cog):
|
|||
# Listeners
|
||||
@commands.Cog.listener()
|
||||
async def on_message(self, message):
|
||||
if await self.bot.cog_disabled_in_guild(self, message.guild):
|
||||
return
|
||||
await self.message_handler(message)
|
||||
|
||||
@commands.Cog.listener()
|
||||
async def on_message_edit(self, before, after):
|
||||
if await self.bot.cog_disabled_in_guild(self, after.guild):
|
||||
return
|
||||
timestamp = before.created_at.strftime(TIMESTAMP_FORMAT)
|
||||
entry = EDIT_TEMPLATE.format(before, after, timestamp)
|
||||
await self.log(after.channel, entry, after.edited_at)
|
||||
|
||||
@commands.Cog.listener()
|
||||
async def on_message_delete(self, message):
|
||||
if await self.bot.cog_disabled_in_guild(self, message.guild):
|
||||
return
|
||||
entry_s = None
|
||||
timestamp = message.created_at.strftime(TIMESTAMP_FORMAT)
|
||||
try:
|
||||
|
@ -1468,16 +1406,22 @@ class ActivityLogger(commands.Cog):
|
|||
|
||||
@commands.Cog.listener()
|
||||
async def on_guild_join(self, guild):
|
||||
if await self.bot.cog_disabled_in_guild(self, guild):
|
||||
return
|
||||
entry = "this bot joined the guild"
|
||||
await self.log(guild, entry)
|
||||
|
||||
@commands.Cog.listener()
|
||||
async def on_guild_remove(self, guild):
|
||||
if await self.bot.cog_disabled_in_guild(self, guild):
|
||||
return
|
||||
entry = "this bot left the guild"
|
||||
await self.log(guild, entry)
|
||||
|
||||
@commands.Cog.listener()
|
||||
async def on_guild_update(self, before, after):
|
||||
if await self.bot.cog_disabled_in_guild(self, after):
|
||||
return
|
||||
entries = []
|
||||
user = None
|
||||
try:
|
||||
|
@ -1535,6 +1479,8 @@ class ActivityLogger(commands.Cog):
|
|||
|
||||
@commands.Cog.listener()
|
||||
async def on_guild_role_create(self, role):
|
||||
if await self.bot.cog_disabled_in_guild(self, role.guild):
|
||||
return
|
||||
user = None
|
||||
try:
|
||||
async for entry in role.guild.audit_logs(limit=2):
|
||||
|
@ -1553,6 +1499,8 @@ class ActivityLogger(commands.Cog):
|
|||
|
||||
@commands.Cog.listener()
|
||||
async def on_guild_role_delete(self, role):
|
||||
if await self.bot.cog_disabled_in_guild(self, role.guild):
|
||||
return
|
||||
user = None
|
||||
try:
|
||||
async for entry in role.guild.audit_logs(limit=2):
|
||||
|
@ -1571,6 +1519,8 @@ class ActivityLogger(commands.Cog):
|
|||
|
||||
@commands.Cog.listener()
|
||||
async def on_guild_role_update(self, before, after):
|
||||
if await self.bot.cog_disabled_in_guild(self, after.guild):
|
||||
return
|
||||
entries = []
|
||||
user = None
|
||||
try:
|
||||
|
@ -1655,6 +1605,8 @@ class ActivityLogger(commands.Cog):
|
|||
|
||||
@commands.Cog.listener()
|
||||
async def on_member_join(self, member):
|
||||
if await self.bot.cog_disabled_in_guild(self, member.guild):
|
||||
return
|
||||
entry = "Member join: @{0} (id {0.id})".format(member)
|
||||
|
||||
async with self.config.user(member).past_names() as past_names:
|
||||
|
@ -1665,6 +1617,8 @@ class ActivityLogger(commands.Cog):
|
|||
|
||||
@commands.Cog.listener()
|
||||
async def on_member_remove(self, member):
|
||||
if await self.bot.cog_disabled_in_guild(self, member.guild):
|
||||
return
|
||||
user = None
|
||||
try:
|
||||
async for entry in member.guild.audit_logs(limit=2):
|
||||
|
@ -1688,6 +1642,8 @@ class ActivityLogger(commands.Cog):
|
|||
|
||||
@commands.Cog.listener()
|
||||
async def on_member_ban(self, guild, member):
|
||||
if await self.bot.cog_disabled_in_guild(self, guild):
|
||||
return
|
||||
user = None
|
||||
try:
|
||||
async for entry in guild.audit_logs(limit=2):
|
||||
|
@ -1706,6 +1662,8 @@ class ActivityLogger(commands.Cog):
|
|||
|
||||
@commands.Cog.listener()
|
||||
async def on_member_unban(self, guild, member):
|
||||
if await self.bot.cog_disabled_in_guild(self, guild):
|
||||
return
|
||||
user = None
|
||||
try:
|
||||
async for entry in guild.audit_logs(limit=2):
|
||||
|
@ -1724,6 +1682,8 @@ class ActivityLogger(commands.Cog):
|
|||
|
||||
@commands.Cog.listener()
|
||||
async def on_member_update(self, before, after):
|
||||
if await self.bot.cog_disabled_in_guild(self, after.guild):
|
||||
return
|
||||
entries = []
|
||||
user = None
|
||||
try:
|
||||
|
@ -1799,6 +1759,8 @@ class ActivityLogger(commands.Cog):
|
|||
|
||||
@commands.Cog.listener()
|
||||
async def on_guild_channel_create(self, channel):
|
||||
if await self.bot.cog_disabled_in_guild(self, channel.guild):
|
||||
return
|
||||
user = None
|
||||
try:
|
||||
async for entry in channel.guild.audit_logs(limit=2):
|
||||
|
@ -1819,6 +1781,8 @@ class ActivityLogger(commands.Cog):
|
|||
|
||||
@commands.Cog.listener()
|
||||
async def on_guild_channel_delete(self, channel):
|
||||
if await self.bot.cog_disabled_in_guild(self, channel.guild):
|
||||
return
|
||||
user = None
|
||||
try:
|
||||
async for entry in channel.guild.audit_logs(limit=2):
|
||||
|
@ -1839,6 +1803,8 @@ class ActivityLogger(commands.Cog):
|
|||
|
||||
@commands.Cog.listener()
|
||||
async def on_guild_channel_update(self, before, after):
|
||||
if await self.bot.cog_disabled_in_guild(self, after.guild):
|
||||
return
|
||||
user = None
|
||||
try:
|
||||
async for entry in after.guild.audit_logs(limit=2):
|
||||
|
@ -1900,6 +1866,8 @@ class ActivityLogger(commands.Cog):
|
|||
|
||||
@commands.Cog.listener()
|
||||
async def on_voice_state_update(self, member, before, after):
|
||||
if await self.bot.cog_disabled_in_guild(self, member.guild):
|
||||
return
|
||||
if not self.should_log(before.channel):
|
||||
return
|
||||
|
||||
|
@ -1958,3 +1926,19 @@ class ActivityLogger(commands.Cog):
|
|||
if before.self_video != after.self_video:
|
||||
verb = "start-video" if after.self_video else "stop-video"
|
||||
await self.log(before.channel, "guild self-{0}: {1} (id {1.id})".format(verb, member))
|
||||
|
||||
# async def red_get_data_for_user(self, user_id: int):
|
||||
# default_user = {"past_names": []}
|
||||
# default_member = {
|
||||
# "stats": {"total_msg": 0, "bot_cmd": 0, "avg_len": 0.0, "vc_time_sec": 0.0, "last_vc_time": None}
|
||||
# }
|
||||
# past_names = await self.config.user_from_id(user_id).past_names()
|
||||
# data = {"past_names": past_names}
|
||||
|
||||
# for guild in self.bot.guilds:
|
||||
# member = guild.get_member(user_id)
|
||||
# if member:
|
||||
# data[guild.name] = await self.config.member(member).stats()
|
||||
|
||||
async def red_delete_data_for_user(self, requester: str, user_id: int):
|
||||
pass
|
||||
|
|
|
@ -3,11 +3,6 @@
|
|||
"Brandons209",
|
||||
"calebj"
|
||||
],
|
||||
"bot_version": [
|
||||
3,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"description": "Log messages, dms, attachments, guild updates (roles, channels, bans, kicks etc) and be able to retrieve these logs for review. Saves these right to disk and customize then to rotate log files. Tracks user's stats; how many messages they send, how many are bot commands, time spent in VC, and moderator actions against them. Also provides an upgraded userinfo command that gives these stats alongside the information Red's userinfo command gives. This is rewritten from @calebj's V2 cog.",
|
||||
"hidden": false,
|
||||
"install_msg": "Thank you for using this cog! Make sure to set bot prefixes using [p]logset prefixes for proper stat logging.",
|
||||
|
@ -19,5 +14,6 @@
|
|||
"log",
|
||||
"activity"
|
||||
],
|
||||
"min_bot_version": "3.3.0"
|
||||
"min_bot_version": "3.4.0",
|
||||
"end_user_data_statement": "Depending on setup, can log user messages, voice channel activity, audit actions in guilds, activity statistics per guild, user name changes, and any moderation actions per guild."
|
||||
}
|
||||
|
|
|
@ -1,59 +0,0 @@
|
|||
# thanks to @Sinbad for time parsing!
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
from datetime import datetime as dt
|
||||
from typing import Optional
|
||||
|
||||
import pytz
|
||||
from dateutil import parser
|
||||
from dateutil.tz import gettz
|
||||
from dateutil.relativedelta import relativedelta
|
||||
|
||||
TIME_RE_STRING = r"\s?".join(
|
||||
[
|
||||
r"((?P<years>\d+?)\s?(years?|y))?",
|
||||
r"((?P<months>\d+?)\s?(months?|mt))?",
|
||||
r"((?P<weeks>\d+?)\s?(weeks?|w))?",
|
||||
r"((?P<days>\d+?)\s?(days?|d))?",
|
||||
r"((?P<hours>\d+?)\s?(hours?|hrs|hr?))?",
|
||||
r"((?P<minutes>\d+?)\s?(minutes?|mins?|m(?!o)))?", # prevent matching "months"
|
||||
r"((?P<seconds>\d+?)\s?(seconds?|secs?|s))?",
|
||||
]
|
||||
)
|
||||
|
||||
TIME_RE = re.compile(TIME_RE_STRING, re.I)
|
||||
|
||||
|
||||
def gen_tzinfos():
|
||||
for zone in pytz.common_timezones:
|
||||
try:
|
||||
tzdate = pytz.timezone(zone).localize(dt.utcnow(), is_dst=None)
|
||||
except pytz.NonExistentTimeError:
|
||||
pass
|
||||
else:
|
||||
tzinfo = gettz(zone)
|
||||
|
||||
if tzinfo:
|
||||
yield tzdate.tzname(), tzinfo
|
||||
|
||||
|
||||
def parse_time(datetimestring: str):
|
||||
tzinfo = dict(gen_tzinfos())
|
||||
ret = parser.parse(datetimestring, tzinfos=tzinfo)
|
||||
if ret.tzinfo is not None:
|
||||
ret = ret.astimezone(pytz.utc)
|
||||
return ret
|
||||
|
||||
|
||||
def parse_time_naive(datetimestring: str):
|
||||
return parser.parse(datetimestring)
|
||||
|
||||
|
||||
def parse_timedelta(argument: str) -> Optional[relativedelta]:
|
||||
matches = TIME_RE.match(argument)
|
||||
if matches:
|
||||
params = {k: int(v) for k, v in matches.groupdict().items() if v}
|
||||
if params:
|
||||
return relativedelta(**params)
|
||||
return None
|
112
activitylog/utils.py
Normal file
112
activitylog/utils.py
Normal file
|
@ -0,0 +1,112 @@
|
|||
# thanks to @Sinbad for time parsing!
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
from datetime import datetime as dt
|
||||
from typing import Optional
|
||||
import os
|
||||
import asyncio
|
||||
|
||||
import pytz
|
||||
from dateutil import parser
|
||||
from dateutil.tz import gettz
|
||||
from dateutil.relativedelta import relativedelta
|
||||
|
||||
TIME_RE_STRING = r"\s?".join(
|
||||
[
|
||||
r"((?P<years>\d+?)\s?(years?|y))?",
|
||||
r"((?P<months>\d+?)\s?(months?|mt))?",
|
||||
r"((?P<weeks>\d+?)\s?(weeks?|w))?",
|
||||
r"((?P<days>\d+?)\s?(days?|d))?",
|
||||
r"((?P<hours>\d+?)\s?(hours?|hrs|hr?))?",
|
||||
r"((?P<minutes>\d+?)\s?(minutes?|mins?|m(?!o)))?", # prevent matching "months"
|
||||
r"((?P<seconds>\d+?)\s?(seconds?|secs?|s))?",
|
||||
]
|
||||
)
|
||||
|
||||
TIME_RE = re.compile(TIME_RE_STRING, re.I)
|
||||
|
||||
|
||||
def gen_tzinfos():
|
||||
for zone in pytz.common_timezones:
|
||||
try:
|
||||
tzdate = pytz.timezone(zone).localize(dt.utcnow(), is_dst=None)
|
||||
except pytz.NonExistentTimeError:
|
||||
pass
|
||||
else:
|
||||
tzinfo = gettz(zone)
|
||||
|
||||
if tzinfo:
|
||||
yield tzdate.tzname(), tzinfo
|
||||
|
||||
|
||||
def parse_time(datetimestring: str):
|
||||
tzinfo = dict(gen_tzinfos())
|
||||
ret = parser.parse(datetimestring, tzinfos=tzinfo)
|
||||
if ret.tzinfo is not None:
|
||||
ret = ret.astimezone(pytz.utc)
|
||||
return ret
|
||||
|
||||
|
||||
def parse_time_naive(datetimestring: str):
|
||||
return parser.parse(datetimestring)
|
||||
|
||||
|
||||
def parse_timedelta(argument: str) -> Optional[relativedelta]:
|
||||
matches = TIME_RE.match(argument)
|
||||
if matches:
|
||||
params = {k: int(v) for k, v in matches.groupdict().items() if v}
|
||||
if params:
|
||||
return relativedelta(**params)
|
||||
return None
|
||||
|
||||
|
||||
def get_all_names(guild_files, user):
|
||||
names = [str(user)]
|
||||
for log in guild_files:
|
||||
if not os.path.exists(log):
|
||||
continue
|
||||
with open(log, "r") as f:
|
||||
for line in f:
|
||||
if str(user.id) in line:
|
||||
# user change their name
|
||||
if "Member username:" in line:
|
||||
username = line.strip().split('"')
|
||||
discrim = username[1].split("#")[-1]
|
||||
username = username[-2] + "#" + discrim
|
||||
names.append(username)
|
||||
# user changed their 4 digit discriminator
|
||||
elif "Member discriminator:" in line:
|
||||
username = line.strip().split('"')[-2]
|
||||
names.append(username)
|
||||
# starting name
|
||||
elif "Member join:" in line:
|
||||
username = line.strip().split("@")[-1].split("#")
|
||||
username = username[0] + "#" + username[1].split(" ")[0]
|
||||
if username is not str(user):
|
||||
names.append(username)
|
||||
return set(names)
|
||||
|
||||
|
||||
class LogHandle:
|
||||
"""basic wrapper for logfile handles, used to keep track of stale handles"""
|
||||
|
||||
def __init__(self, path, time=None, mode="a", buf=1):
|
||||
self.handle = open(path, mode, buf, errors="backslashreplace")
|
||||
self.lock = asyncio.Lock()
|
||||
|
||||
if time:
|
||||
self.time = time
|
||||
else:
|
||||
self.time = dt.fromtimestamp(os.path.getmtime(path))
|
||||
|
||||
async def write(self, value):
|
||||
async with self.lock:
|
||||
self._write(value)
|
||||
|
||||
def close(self):
|
||||
self.handle.close()
|
||||
|
||||
def _write(self, value):
|
||||
self.time = dt.utcnow()
|
||||
self.handle.write(value)
|
|
@ -63,6 +63,8 @@ class Birthday(commands.Cog):
|
|||
|
||||
async def check_bdays(self):
|
||||
for guild in self.bot.guilds:
|
||||
if await self.bot.cog_disabled_in_guild(self, guild):
|
||||
continue
|
||||
for member in guild.members:
|
||||
await self.check_member_bday(member)
|
||||
|
||||
|
@ -97,7 +99,7 @@ class Birthday(commands.Cog):
|
|||
else:
|
||||
embed.description = f"Happy Birthday to {member.mention}!"
|
||||
try:
|
||||
await channel.send(embed=embed)
|
||||
await channel.send(embed=embed, allow_mentions=True)
|
||||
except:
|
||||
pass
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
],
|
||||
"bot_version": [
|
||||
3,
|
||||
0,
|
||||
4,
|
||||
0
|
||||
],
|
||||
"description": "Cog used for setting birthdays and announcing them and giving people roles on their birthday",
|
||||
|
@ -17,5 +17,6 @@
|
|||
"tags": [
|
||||
"brandons209",
|
||||
"pancakesparkle"
|
||||
]
|
||||
],
|
||||
"end_user_data_statement": "This cog will store a user's birthday."
|
||||
}
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
{
|
||||
"author" : ["Brandons209", "Jinatku"],
|
||||
"bot_version": [3,0,0],
|
||||
"bot_version": [3,4,0],
|
||||
"install_msg" : "Let your users confess their terrible terrible crimes in secrecy!",
|
||||
"short" : "Confess secretly.",
|
||||
"description" : "Confess in a confession room to repent your crimes.",
|
||||
"tags" : ["confession", "crime", "secret"],
|
||||
"hidden" : false
|
||||
"hidden" : false,
|
||||
"end_user_data_statement": "This cog won't store anything for a user."
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
],
|
||||
"bot_version": [
|
||||
3,
|
||||
0,
|
||||
4,
|
||||
0
|
||||
],
|
||||
"description": "Allow setting up costs for any commands of your bot, with user, and role hierarchy. Also allows setting roles who do not have to pay for commands. Has receptions DMed and updated to allow users to track their spending.",
|
||||
|
@ -15,5 +15,6 @@
|
|||
"tags": [
|
||||
"brandons209",
|
||||
"redbot"
|
||||
]
|
||||
],
|
||||
"end_user_data_statement": "This cog won't store anything for a user."
|
||||
}
|
||||
|
|
|
@ -126,7 +126,8 @@ class CostManager(commands.Cog):
|
|||
except:
|
||||
if receipt != -1: # send mention if first time getting this message
|
||||
await ctx.send(
|
||||
f"Hey {member.mention}, please turn on DMs from server members in your settings so I can send you receipts for purchase of commands."
|
||||
f"Hey {member.mention}, please turn on DMs from server members in your settings so I can send you receipts for purchase of commands.",
|
||||
allowed_mentions=discord.AllowedMentions.all(),
|
||||
)
|
||||
|
||||
await self.config.member(member).receipt.set(-1)
|
||||
|
@ -400,7 +401,8 @@ class CostManager(commands.Cog):
|
|||
currency_name = await bank.get_currency_name(ctx.guild)
|
||||
balance = await bank.get_balance(ctx.author)
|
||||
message = await ctx.send(
|
||||
f"Sorry {ctx.author.name}, you do not have enough {currency_name} to use that command. (Cost: {cost}, Balance: {balance})"
|
||||
f"Sorry {ctx.author.name}, you do not have enough {currency_name} to use that command. (Cost: {cost}, Balance: {balance})",
|
||||
allowed_mentions=discord.AllowedMentions.all(),
|
||||
)
|
||||
await asyncio.sleep(10)
|
||||
await message.delete()
|
||||
|
|
|
@ -70,6 +70,8 @@ class Disable(commands.Cog):
|
|||
|
||||
@commands.Cog.listener()
|
||||
async def on_command_error(self, ctx, exception):
|
||||
if await self.bot.cog_disabled_in_guild(self, ctx.guild):
|
||||
return
|
||||
if isinstance(exception, DisabledError):
|
||||
msg = await self.config.guild(ctx.guild).disabled_message()
|
||||
await ctx.send(msg.format(ctx.command.name))
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
],
|
||||
"bot_version": [
|
||||
3,
|
||||
3,
|
||||
4,
|
||||
0
|
||||
],
|
||||
"description": "Small cog that allows disabling all bot commands for everyone except Admins/owner in a guild. Nice for things like bot setup. You can also set the error message when a person trys using a command when its disabled.",
|
||||
|
@ -15,5 +15,6 @@
|
|||
"tags": [
|
||||
"brandons209",
|
||||
"redbot"
|
||||
]
|
||||
],
|
||||
"end_user_data_statement": "This cog won't store any data for users."
|
||||
}
|
||||
|
|
|
@ -49,6 +49,8 @@ class EconomyTrickle(commands.Cog):
|
|||
|
||||
@commands.Cog.listener()
|
||||
async def on_message(self, message):
|
||||
if await self.bot.cog_disabled_in_guild(self, message.guild):
|
||||
return
|
||||
if message.guild and await self.config.guild(message.guild).active():
|
||||
self.recordhandler.proccess_message(message)
|
||||
|
||||
|
|
|
@ -10,5 +10,6 @@
|
|||
"short": "Trickle money into user's account on activity.",
|
||||
"description": "Trickle money into user's account on activity, modified by Brandons209 from Sinbad.",
|
||||
"hidden": false,
|
||||
"min_bot_version": "3.1.8"
|
||||
"min_bot_version": "3.4.0",
|
||||
"end_user_data_statement": "This cog only stores internal variables per user."
|
||||
}
|
||||
|
|
|
@ -6,5 +6,7 @@
|
|||
"INSTALL_MSG" : "Thanks for installing EveryoneEmoji.",
|
||||
"REQUIREMENTS" : [],
|
||||
"TAGS" : ["emoji", "EveryoneEmoji", "everyone"],
|
||||
"DISABLED" : false
|
||||
"DISABLED" : false,
|
||||
"min_bot_version": "3.4.0",
|
||||
"end_user_data_statement": "This cog stores no data."
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
],
|
||||
"bot_version": [
|
||||
3,
|
||||
0,
|
||||
4,
|
||||
0
|
||||
],
|
||||
"description": "Provides a way to quickly remove a user for all chats and isolate them to a single channel. Supports setting times, automatic removal of isolate, modlog integration, custom role overrides, automatic server setup, and a lot more. This is different from punish as it always remove all a user's roles and by default makes the user not read all channels.",
|
||||
|
@ -16,5 +16,6 @@
|
|||
"tags": [
|
||||
"brandons209",
|
||||
"isolate"
|
||||
]
|
||||
],
|
||||
"end_user_data_statement": "This cog stores members who are currently isolated for moderation purposes."
|
||||
}
|
||||
|
|
|
@ -1306,6 +1306,8 @@ class Isolate(commands.Cog):
|
|||
@commands.Cog.listener()
|
||||
async def on_guild_channel_create(self, channel):
|
||||
"""Run when new channels are created and set up role permissions"""
|
||||
if await self.bot.cog_disabled_in_guild(self, channel.guild):
|
||||
return
|
||||
role = await self.get_role(channel.guild, quiet=True)
|
||||
if not role:
|
||||
return
|
||||
|
@ -1315,6 +1317,8 @@ class Isolate(commands.Cog):
|
|||
@commands.Cog.listener()
|
||||
async def on_member_update(self, before, after):
|
||||
"""Remove scheduled unisolate when manually removed role"""
|
||||
if await self.bot.cog_disabled_in_guild(self, after.guild):
|
||||
return
|
||||
try:
|
||||
assert before.roles != after.roles
|
||||
guild_data = await self.config.guild(before.guild).ISOLATED()
|
||||
|
@ -1343,6 +1347,8 @@ class Isolate(commands.Cog):
|
|||
@commands.Cog.listener()
|
||||
async def on_member_join(self, member):
|
||||
"""Restore Isolation if isolated user leaves/rejoins"""
|
||||
if await self.bot.cog_disabled_in_guild(self, member.guild):
|
||||
return
|
||||
guild = member.guild
|
||||
isolated = await self.config.guild(guild).ISOLATED()
|
||||
data = isolated.get(str(member.id), {})
|
||||
|
@ -1366,6 +1372,8 @@ class Isolate(commands.Cog):
|
|||
|
||||
@commands.Cog.listener()
|
||||
async def on_voice_state_update(self, member, before, after):
|
||||
if await self.bot.cog_disabled_in_guild(self, after.guild):
|
||||
return
|
||||
if not after.channel:
|
||||
return
|
||||
|
||||
|
@ -1386,6 +1394,8 @@ class Isolate(commands.Cog):
|
|||
@commands.Cog.listener()
|
||||
async def on_member_ban(self, member):
|
||||
"""Remove Isolation record when member is banned."""
|
||||
if await self.bot.cog_disabled_in_guild(self, member.guild):
|
||||
return
|
||||
guild = member.guild
|
||||
data = await self.config.guild(guild).ISOLATED()
|
||||
member_data = data.get(str(member.id))
|
||||
|
|
|
@ -145,9 +145,9 @@ def role_from_string(guild, rolename, roles=None):
|
|||
|
||||
if role:
|
||||
return role
|
||||
|
||||
rolename = rolename.lower()
|
||||
role = discord.utils.find(lambda r: r.name.lower() == rolename, roles)
|
||||
else:
|
||||
rolename = rolename.lower()
|
||||
role = discord.utils.find(lambda r: r.name.lower() == rolename, roles)
|
||||
|
||||
return role
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
],
|
||||
"bot_version": [
|
||||
3,
|
||||
0,
|
||||
4,
|
||||
0
|
||||
],
|
||||
"description": "Uses markov chains to generate unique text in your guild! Text generated is based on what users say per channel. The markov model can be reset if needed as well per channel.",
|
||||
|
@ -18,5 +18,6 @@
|
|||
"markov",
|
||||
"generaton",
|
||||
"markov chain"
|
||||
]
|
||||
],
|
||||
"end_user_data_statement": "This doesn't store any user data."
|
||||
}
|
||||
|
|
|
@ -159,11 +159,13 @@ class Markov(commands.Cog):
|
|||
embed.set_thumbnail(url=avatar)
|
||||
|
||||
embed.set_footer(text=f"Generated by {member.display_name}")
|
||||
await ctx.send(embed=embed)
|
||||
await ctx.send(embed=embed, allowed_mentions=discord.AllowedMentions.all())
|
||||
|
||||
# Listener
|
||||
@commands.Cog.listener()
|
||||
async def on_message(self, message):
|
||||
if await self.bot.cog_disabled_in_guild(self, message.guild):
|
||||
return
|
||||
# updates model
|
||||
content = message.content
|
||||
guild = message.guild
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
],
|
||||
"bot_version": [
|
||||
3,
|
||||
0,
|
||||
4,
|
||||
0
|
||||
],
|
||||
"description": "More admin commands like purging inactive users, member count display for channel name, add roles based on author's current roles, log new user accounts joining, and more!",
|
||||
|
@ -15,5 +15,6 @@
|
|||
"tags": [
|
||||
"brandons209",
|
||||
"redbot"
|
||||
]
|
||||
],
|
||||
"end_user_data_statement": "This will store a user's last few messages (depending on configuration)"
|
||||
}
|
||||
|
|
|
@ -170,6 +170,8 @@ class MoreAdmin(commands.Cog):
|
|||
SLEEP_TIME = 300
|
||||
while True:
|
||||
for guild in self.bot.guilds:
|
||||
if await self.bot.cog_disabled_in_guild(self, guild):
|
||||
continue
|
||||
channel = await self.config.guild(guild).user_count_channel()
|
||||
if channel:
|
||||
channel = guild.get_channel(channel)
|
||||
|
@ -799,13 +801,13 @@ class MoreAdmin(commands.Cog):
|
|||
@commands.command(hidden=True)
|
||||
@commands.guild_only()
|
||||
async def say(self, ctx, *, content: str):
|
||||
await ctx.send(escape(content, mass_mentions=True), allowed_mentions=discord.AllowedMentions())
|
||||
await ctx.send(escape(content, mass_mentions=True), allowed_mentions=discord.AllowedMentions.all())
|
||||
|
||||
@commands.command(hidden=True)
|
||||
@commands.guild_only()
|
||||
async def selfdm(self, ctx, *, content: str):
|
||||
try:
|
||||
await ctx.author.send(content)
|
||||
await ctx.author.send(content, allowed_mentions=discord.AllowedMentions.all())
|
||||
except:
|
||||
await ctx.send(
|
||||
"I couldn't send you the DM, make sure to turn on messages from server members! Here is the message:"
|
||||
|
@ -827,7 +829,7 @@ class MoreAdmin(commands.Cog):
|
|||
return
|
||||
|
||||
try:
|
||||
await message.edit(content=msg)
|
||||
await message.edit(content=msg, allowed_mentions=discord.AllowedMentions.all())
|
||||
except:
|
||||
await ctx.send("Could not edit message.")
|
||||
|
||||
|
@ -839,7 +841,7 @@ class MoreAdmin(commands.Cog):
|
|||
Sends a message to a channel from Aurelia.
|
||||
"""
|
||||
try:
|
||||
await channel.send(msg) # , allowed_mentions=discord.AllowedMentions())
|
||||
await channel.send(msg, allowed_mentions=discord.AllowedMentions.all())
|
||||
except:
|
||||
await ctx.send("Could not send message in that channel.")
|
||||
|
||||
|
@ -974,6 +976,10 @@ class MoreAdmin(commands.Cog):
|
|||
|
||||
@commands.Cog.listener()
|
||||
async def on_member_join(self, member):
|
||||
if await self.bot.cog_disabled_in_guild(self, member.guild):
|
||||
return
|
||||
if await self.bot.cog_disabled_in_guild(self, member.guild):
|
||||
return
|
||||
sus_threshold = await self.config.guild(member.guild).sus_user_threshold()
|
||||
if not sus_threshold:
|
||||
return
|
||||
|
@ -1003,6 +1009,8 @@ class MoreAdmin(commands.Cog):
|
|||
|
||||
@commands.Cog.listener()
|
||||
async def on_message(self, message):
|
||||
if await self.bot.cog_disabled_in_guild(self, message.guild):
|
||||
return
|
||||
# Set user's last message
|
||||
if not message.guild:
|
||||
return
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
],
|
||||
"bot_version": [
|
||||
3,
|
||||
3,
|
||||
4,
|
||||
0
|
||||
],
|
||||
"description": "Allow nitro boosters to add an emoji to the server, with channel logging.",
|
||||
|
@ -17,5 +17,6 @@
|
|||
"nitro",
|
||||
"boost",
|
||||
"emoji"
|
||||
]
|
||||
],
|
||||
"end_user_data_statement": "This cog will store a user's custom emojis in each guild."
|
||||
}
|
||||
|
|
|
@ -285,6 +285,8 @@ class NitroEmoji(commands.Cog):
|
|||
|
||||
@commands.Cog.listener()
|
||||
async def on_member_update(self, before, after):
|
||||
if await self.bot.cog_disabled_in_guild(self, after.guild):
|
||||
return
|
||||
# check if they stopped boosting
|
||||
if (before.premium_since != after.premium_since and after.premium_since is None) or before.roles != after.roles:
|
||||
boosts = await self.get_boosts(after)
|
||||
|
@ -312,6 +314,8 @@ class NitroEmoji(commands.Cog):
|
|||
|
||||
@commands.Cog.listener()
|
||||
async def on_member_leave(self, member):
|
||||
if await self.bot.cog_disabled_in_guild(self, member.guild):
|
||||
return
|
||||
# remove all member emojis on leave
|
||||
emojis = await self.config.member(member).emojis()
|
||||
for emoji in emojis:
|
||||
|
@ -324,6 +328,8 @@ class NitroEmoji(commands.Cog):
|
|||
|
||||
@commands.Cog.listener()
|
||||
async def on_guild_emojis_update(self, guild, before, after):
|
||||
if await self.bot.cog_disabled_in_guild(self, guild):
|
||||
return
|
||||
b_e = set(before)
|
||||
a_e = set(after)
|
||||
diff = b_e - a_e
|
||||
|
|
|
@ -14,5 +14,7 @@
|
|||
],
|
||||
"requirements": [
|
||||
"tabulate"
|
||||
]
|
||||
],
|
||||
"min_bot_version": "3.4.0",
|
||||
"end_user_data_statement": "This will store what a user's custom role is if they have one."
|
||||
}
|
||||
|
|
|
@ -370,6 +370,8 @@ class PersonalRoles(commands.Cog):
|
|||
@commands.Cog.listener("on_member_join")
|
||||
async def role_persistance(self, member):
|
||||
"""Automatically give already assigned roles on join"""
|
||||
if await self.bot.cog_disabled_in_guild(self, member.guild):
|
||||
return
|
||||
role = await self.config.member(member).role()
|
||||
if role:
|
||||
role = member.guild.get_role(role)
|
||||
|
@ -382,6 +384,8 @@ class PersonalRoles(commands.Cog):
|
|||
@commands.Cog.listener("on_member_remove")
|
||||
async def remove_role(self, member):
|
||||
""" Delete personal role if member leaves."""
|
||||
if await self.bot.cog_disabled_in_guild(self, member.guild):
|
||||
return
|
||||
role = await self.config.member(member).role()
|
||||
auto = await self.config.member(member).auto_role()
|
||||
role = member.guild.get_role(role)
|
||||
|
@ -396,6 +400,8 @@ class PersonalRoles(commands.Cog):
|
|||
@commands.Cog.listener("on_member_update")
|
||||
async def modify_roles(self, before, after):
|
||||
""" Delete personal role if member looses their auto role or looses their personal role """
|
||||
if await self.bot.cog_disabled_in_guild(self, after.guild):
|
||||
return
|
||||
role = await self.config.member(after).role()
|
||||
role = before.guild.get_role(role)
|
||||
if not role:
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
],
|
||||
"bot_version": [
|
||||
3,
|
||||
0,
|
||||
4,
|
||||
0
|
||||
],
|
||||
"description": "Search derpibooru for images of ponies! Fully customizable filter list!",
|
||||
|
@ -20,5 +20,6 @@
|
|||
"pony",
|
||||
"mlp",
|
||||
"image"
|
||||
]
|
||||
],
|
||||
"end_user_data_statement": "This doesn't store any data."
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
],
|
||||
"bot_version": [
|
||||
3,
|
||||
0,
|
||||
4,
|
||||
0
|
||||
],
|
||||
"description": "Provides a way to quickly remove a user for all chats and isolate them to a single channel. Supports setting times, automatic removal of punish, modlog integration, removing roles so that role overrides work, custom role overrides, automatic server setup, and a lot more.",
|
||||
|
@ -16,5 +16,6 @@
|
|||
"tags": [
|
||||
"brandons209",
|
||||
"punish"
|
||||
]
|
||||
],
|
||||
"end_user_data_statement": "This will store who is currently punished."
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ import textwrap
|
|||
|
||||
log = logging.getLogger("red.punish")
|
||||
|
||||
__version__ = "3.0.0"
|
||||
__version__ = "3.3.0"
|
||||
|
||||
PURGE_MESSAGES = 1 # for cpunish
|
||||
|
||||
|
@ -1373,6 +1373,8 @@ class Punish(commands.Cog):
|
|||
# Listeners
|
||||
@commands.Cog.listener()
|
||||
async def on_guild_channel_create(self, channel):
|
||||
if await self.bot.cog_disabled_in_guild(self, channel.guild):
|
||||
return
|
||||
"""Run when new channels are created and set up role permissions"""
|
||||
role = await self.get_role(channel.guild, quiet=True)
|
||||
if not role:
|
||||
|
@ -1383,6 +1385,8 @@ class Punish(commands.Cog):
|
|||
@commands.Cog.listener()
|
||||
async def on_member_update(self, before, after):
|
||||
"""Remove scheduled unpunish when manually removed role"""
|
||||
if await self.bot.cog_disabled_in_guild(self, after.guild):
|
||||
return
|
||||
try:
|
||||
assert before.roles != after.roles
|
||||
guild_data = await self.config.guild(before.guild).PUNISHED()
|
||||
|
@ -1411,6 +1415,8 @@ class Punish(commands.Cog):
|
|||
@commands.Cog.listener()
|
||||
async def on_member_join(self, member):
|
||||
"""Restore punishment if punished user leaves/rejoins"""
|
||||
if await self.bot.cog_disabled_in_guild(self, member.guild):
|
||||
return
|
||||
guild = member.guild
|
||||
punished = await self.config.guild(guild).PUNISHED()
|
||||
data = punished.get(str(member.id), {})
|
||||
|
@ -1434,6 +1440,8 @@ class Punish(commands.Cog):
|
|||
|
||||
@commands.Cog.listener()
|
||||
async def on_voice_state_update(self, member, before, after):
|
||||
if await self.bot.cog_disabled_in_guild(self, after.guild):
|
||||
return
|
||||
if not after.channel:
|
||||
return
|
||||
|
||||
|
@ -1454,6 +1462,8 @@ class Punish(commands.Cog):
|
|||
@commands.Cog.listener()
|
||||
async def on_member_ban(self, member):
|
||||
"""Remove punishment record when member is banned."""
|
||||
if await self.bot.cog_disabled_in_guild(self, member.guild):
|
||||
return
|
||||
guild = member.guild
|
||||
data = await self.config.guild(guild).PUNISHED()
|
||||
member_data = data.get(str(member.id))
|
||||
|
|
|
@ -145,9 +145,9 @@ def role_from_string(guild, rolename, roles=None):
|
|||
|
||||
if role:
|
||||
return role
|
||||
|
||||
rolename = rolename.lower()
|
||||
role = discord.utils.find(lambda r: r.name.lower() == rolename, roles)
|
||||
else:
|
||||
rolename = rolename.lower()
|
||||
role = discord.utils.find(lambda r: r.name.lower() == rolename, roles)
|
||||
|
||||
return role
|
||||
|
||||
|
|
|
@ -6,5 +6,7 @@
|
|||
"INSTALL_MSG" : "Thanks for installing ReactPoll. Please make sure your bot has the 'Manage Messages' permission so it can manage emoji reactions on messages.",
|
||||
"REQUIREMENTS" : ["python-dateutil", "pytz"],
|
||||
"TAGS" : ["poll", "reaction", "emoji", "react"],
|
||||
"DISABLED" : false
|
||||
"DISABLED" : false,
|
||||
"min_bot_version": "3.4.0",
|
||||
"end_user_data_statement": "This cog won't store user data."
|
||||
}
|
||||
|
|
|
@ -135,6 +135,10 @@ class ReactPoll(commands.Cog):
|
|||
guild = self.bot.get_guild(payload.guild_id)
|
||||
if not guild:
|
||||
return
|
||||
|
||||
if await self.bot.cog_disabled_in_guild(self, guild):
|
||||
return
|
||||
|
||||
user = guild.get_member(payload.user_id)
|
||||
message = await self.bot.get_channel(payload.channel_id).fetch_message(payload.message_id)
|
||||
# Listener is required to remove bad reactions
|
||||
|
|
|
@ -43,6 +43,8 @@ class EventMixin(MixinMeta):
|
|||
Section has been optimized assuming member._roles
|
||||
remains an iterable containing snowflakes
|
||||
"""
|
||||
if await self.bot.cog_disabled_in_guild(self, after.guild):
|
||||
return
|
||||
await self.wait_for_ready()
|
||||
if before._roles == after._roles:
|
||||
return
|
||||
|
@ -85,6 +87,8 @@ class EventMixin(MixinMeta):
|
|||
@commands.Cog.listener()
|
||||
async def on_member_join(self, member: discord.Member):
|
||||
await self.wait_for_ready()
|
||||
if await self.bot.cog_disabled_in_guild(self, member.guild):
|
||||
return
|
||||
guild = member.guild
|
||||
if not guild.me.guild_permissions.manage_roles:
|
||||
return
|
||||
|
@ -134,6 +138,9 @@ class EventMixin(MixinMeta):
|
|||
await self.maybe_update_guilds(guild)
|
||||
else:
|
||||
return
|
||||
|
||||
if await self.bot.cog_disabled_in_guild(self, guild):
|
||||
return
|
||||
member = guild.get_member(payload.user_id)
|
||||
|
||||
if member is None or member.bot:
|
||||
|
@ -182,6 +189,8 @@ class EventMixin(MixinMeta):
|
|||
if not guild:
|
||||
# Where's it go?
|
||||
return
|
||||
if await self.bot.cog_disabled_in_guild(self, guild):
|
||||
return
|
||||
member = guild.get_member(payload.user_id)
|
||||
if not member or member.bot:
|
||||
return
|
||||
|
|
|
@ -17,5 +17,6 @@
|
|||
"massrole"
|
||||
],
|
||||
"hidden": false,
|
||||
"min_bot_version": "3.2.0a0.dev1"
|
||||
"min_bot_version": "3.4.0",
|
||||
"end_user_data_statement": "This will only store sticky roles for users."
|
||||
}
|
||||
|
|
|
@ -206,7 +206,11 @@ class MassManagementMixin(MixinMeta):
|
|||
embed = discord.Embed(description=description)
|
||||
if ctx.guild:
|
||||
embed.color = ctx.guild.me.color
|
||||
await ctx.send(embed=embed, content=f"Search results for {ctx.author.mention}")
|
||||
await ctx.send(
|
||||
embed=embed,
|
||||
content=f"Search results for {ctx.author.mention}",
|
||||
allowed_mentions=discord.AllowedMentions.all(),
|
||||
)
|
||||
|
||||
else:
|
||||
await self.send_maybe_chunked_csv(ctx, list(members))
|
||||
|
@ -251,6 +255,7 @@ class MassManagementMixin(MixinMeta):
|
|||
await ctx.send(
|
||||
content=f"Data for {ctx.author.mention}",
|
||||
files=[discord.File(data, filename=filename)],
|
||||
allowed_mentions=discord.AllowedMentions.all(),
|
||||
)
|
||||
csvf.close()
|
||||
data.close()
|
||||
|
|
19
roleplay/info.json
Normal file
19
roleplay/info.json
Normal file
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"author": [
|
||||
"TheBluekr"
|
||||
],
|
||||
"bot_version": [
|
||||
3,
|
||||
4,
|
||||
0
|
||||
],
|
||||
"description": "Roleplay commands for booping, hugging, etc.",
|
||||
"hidden": false,
|
||||
"install_msg": "Thanks for using my cog!",
|
||||
"requirements": [],
|
||||
"tags": [
|
||||
"brandons209",
|
||||
"Som3thing"
|
||||
],
|
||||
"end_user_data_statement": "No data is stored."
|
||||
}
|
|
@ -4,16 +4,16 @@
|
|||
],
|
||||
"bot_version": [
|
||||
3,
|
||||
0,
|
||||
4,
|
||||
0
|
||||
],
|
||||
"description": "",
|
||||
"description": "Tracks specified roles on when they are added, removed, and who updates them.",
|
||||
"hidden": false,
|
||||
"install_msg": "",
|
||||
"install_msg": "Thank you for using my cog!",
|
||||
"requirements": [],
|
||||
"short": "",
|
||||
"tags": [
|
||||
"brandons209",
|
||||
"pancakesparkle"
|
||||
]
|
||||
}
|
||||
],
|
||||
"end_user_data_statement": "Depending on setup, can log user messages, voice channel activity, audit actions in guilds, activity statistics per guild, user name changes, and any moderation actions per guild."
|
||||
}
|
||||
|
|
|
@ -200,6 +200,8 @@ class RoleTracker(commands.Cog):
|
|||
"""
|
||||
Listens for role updates and more
|
||||
"""
|
||||
if await self.bot.cog_disabled_in_guild(self, after.guild):
|
||||
return
|
||||
|
||||
if before.roles != after.roles:
|
||||
user = self.bot.user
|
||||
|
|
|
@ -5,9 +5,10 @@
|
|||
"install_msg": "Thanks for install.",
|
||||
"short": "Quickly list server and channel rules.",
|
||||
"description": "Quickly list server and channel rules.",
|
||||
"min_bot_version": "3.2.1",
|
||||
"min_bot_version": "3.4.0",
|
||||
"tags": [
|
||||
"rules",
|
||||
"rule"
|
||||
]
|
||||
],
|
||||
"end_user_data_statement": "This only stores rules added by admins of guilds."
|
||||
}
|
||||
|
|
|
@ -16,6 +16,6 @@
|
|||
"python-dateutil",
|
||||
"pytz"
|
||||
],
|
||||
"min_bot_version": "3.3.0",
|
||||
"min_bot_version": "3.4.0",
|
||||
"end_user_data_statement": "This cog does not persistently store data or metadata about users. It does store commands provided for intended later use along with the user ID of the person who scheduled it.\nUsers may delete their own data with or without making a data request."
|
||||
}
|
||||
|
|
|
@ -577,7 +577,7 @@ class Scheduler(commands.Cog):
|
|||
|
||||
@helpers.command(name="say")
|
||||
async def say(self, ctx: commands.GuildContext, *, content: str):
|
||||
await ctx.send(content, allowed_mentions=discord.AllowedMentions())
|
||||
await ctx.send(content, allowed_mentions=discord.AllowedMentions.all())
|
||||
|
||||
@helpers.command(name="selfwhisper")
|
||||
async def swhisp(self, ctx: commands.GuildContext, *, content: str):
|
||||
|
|
|
@ -5,11 +5,12 @@
|
|||
"install_msg": "Thanks for install.",
|
||||
"short": "Play sound effects!",
|
||||
"description": "Play sound effects, either via links or files. Integrates with economy and cost manager cog.",
|
||||
"min_bot_version": "3.3.0",
|
||||
"min_bot_version": "3.4.0",
|
||||
"requirements": ["tabulate"],
|
||||
"tags": [
|
||||
"sfx",
|
||||
"saysound",
|
||||
"audio"
|
||||
]
|
||||
],
|
||||
"end_user_data_statement": "This doesn't store any user data."
|
||||
}
|
||||
|
|
|
@ -6,5 +6,7 @@
|
|||
"INSTALL_MSG" : "Thanks for installing SmartReact.",
|
||||
"REQUIREMENTS" : [],
|
||||
"TAGS" : ["reaction", "smart", "auto"],
|
||||
"DISABLED" : false
|
||||
"DISABLED" : false,
|
||||
"min_bot_version": "3.4.0",
|
||||
"end_user_data_statement": "This doesn't store any user data."
|
||||
}
|
||||
|
|
|
@ -114,6 +114,8 @@ class SmartReact(commands.Cog):
|
|||
# Thanks irdumb#1229 for the help making this "more Pythonic"
|
||||
@commands.Cog.listener()
|
||||
async def on_message(self, message):
|
||||
if await self.bot.cog_disabled_in_guild(self, message.guild):
|
||||
return
|
||||
if not message.guild:
|
||||
return
|
||||
if message.author == self.bot.user:
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
],
|
||||
"bot_version": [
|
||||
3,
|
||||
0,
|
||||
4,
|
||||
0
|
||||
],
|
||||
"description": "Trick or treat! Sometimes you get some credits, sometimes you get tricked and lose them!",
|
||||
|
@ -14,4 +14,5 @@
|
|||
"tags": [
|
||||
"brandons209",
|
||||
"Halloween"
|
||||
]
|
||||
],
|
||||
"end_user_data_statement": "This doesn't store any user data."
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
{
|
||||
"author": [
|
||||
"tmerc"
|
||||
"tmerc",
|
||||
"brandons209"
|
||||
],
|
||||
"install_msg": "Thanks for installing!",
|
||||
"name": "Welcome",
|
||||
|
@ -13,5 +14,7 @@
|
|||
"leave",
|
||||
"ban",
|
||||
"utility"
|
||||
]
|
||||
],
|
||||
"min_bot_version": "3.4.0",
|
||||
"end_user_data_statement": "This cog doesn't store any user data."
|
||||
}
|
||||
|
|
|
@ -570,6 +570,8 @@ class Welcome(commands.Cog):
|
|||
@commands.Cog.listener()
|
||||
async def on_member_join(self, member: discord.Member) -> None:
|
||||
"""Listens for member joins."""
|
||||
if await self.bot.cog_disabled_in_guild(self, member.guild):
|
||||
return
|
||||
|
||||
guild: discord.Guild = member.guild
|
||||
guild_settings = self.config.guild(guild)
|
||||
|
@ -601,12 +603,16 @@ class Welcome(commands.Cog):
|
|||
@commands.Cog.listener()
|
||||
async def on_member_remove(self, member: discord.Member) -> None:
|
||||
"""Listens for member leaves."""
|
||||
if await self.bot.cog_disabled_in_guild(self, member.guild):
|
||||
return
|
||||
|
||||
await self.__handle_event(member.guild, member, "leave")
|
||||
|
||||
@commands.Cog.listener()
|
||||
async def on_member_ban(self, guild: discord.Guild, member: discord.Member) -> None:
|
||||
"""Listens for user bans."""
|
||||
if await self.bot.cog_disabled_in_guild(self, member.guild):
|
||||
return
|
||||
|
||||
await self.__handle_event(guild, member, "ban")
|
||||
|
||||
|
@ -804,7 +810,8 @@ class Welcome(commands.Cog):
|
|||
return await channel.send(
|
||||
format_str.format(
|
||||
member=user, server=guild, bot=user, count=count or "", plural=plural, roles=roles, stats=stats
|
||||
)
|
||||
),
|
||||
allowed_mentions=discord.AllowedMentions.all(),
|
||||
)
|
||||
except discord.Forbidden:
|
||||
log.error(
|
||||
|
@ -848,7 +855,10 @@ class Welcome(commands.Cog):
|
|||
message_format = await self.config.guild(member.guild).join.whisper.message()
|
||||
|
||||
try:
|
||||
await member.send(message_format.format(member=member, server=member.guild))
|
||||
await member.send(
|
||||
message_format.format(member=member, server=member.guild),
|
||||
allowed_mentions=discord.AllowedMentions.all(),
|
||||
)
|
||||
except discord.Forbidden:
|
||||
log.error(
|
||||
f"Failed to send DM to member ID {member.id} (server ID {member.guild.id}): insufficient permissions"
|
||||
|
|
Loading…
Reference in a new issue