Data API Complicance (Red 3.4) (#136)
* Simple ones first * Less simple but still simple. * Slightly more complicated * use correct name * move to module * Black -l 120 * review * give users the proper feedback Co-authored-by: aikaterna <20862007+aikaterna@users.noreply.github.com>
This commit is contained in:
@@ -1,5 +1,7 @@
|
|||||||
from .antiphoneclapper import AntiPhoneClapper
|
from .antiphoneclapper import AntiPhoneClapper
|
||||||
|
|
||||||
|
__red_end_user_data_statement__ = "This cog does not persistently store data or metadata about users."
|
||||||
|
|
||||||
|
|
||||||
async def setup(bot):
|
async def setup(bot):
|
||||||
bot.add_cog(AntiPhoneClapper(bot))
|
bot.add_cog(AntiPhoneClapper(bot))
|
||||||
|
|||||||
@@ -13,9 +13,13 @@ log = logging.getLogger("red.aikaterna.antiphoneclapper")
|
|||||||
class AntiPhoneClapper(commands.Cog):
|
class AntiPhoneClapper(commands.Cog):
|
||||||
"""This cog deletes bad GIFs that will crash phone clients."""
|
"""This cog deletes bad GIFs that will crash phone clients."""
|
||||||
|
|
||||||
|
async def red_delete_data_for_user(self, **kwargs):
|
||||||
|
""" Nothing to delete """
|
||||||
|
return
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
self.session = aiohttp.ClientSession()
|
self.session = aiohttp.ClientSession()
|
||||||
self.config = Config.get_conf(self, 2719371001, force_registration=True)
|
self.config = Config.get_conf(self, 2719371001, force_registration=True)
|
||||||
|
|
||||||
default_guild = {"watching": []}
|
default_guild = {"watching": []}
|
||||||
@@ -60,9 +64,7 @@ class AntiPhoneClapper(commands.Cog):
|
|||||||
else:
|
else:
|
||||||
return await ctx.send("Channel is not being watched.")
|
return await ctx.send("Channel is not being watched.")
|
||||||
await self.config.guild(ctx.guild).watching.set(channel_list)
|
await self.config.guild(ctx.guild).watching.set(channel_list)
|
||||||
await ctx.send(
|
await ctx.send(f"{self.bot.get_channel(channel.id).mention} will not have bad gifs removed.")
|
||||||
f"{self.bot.get_channel(channel.id).mention} will not have bad gifs removed."
|
|
||||||
)
|
|
||||||
|
|
||||||
def is_phone_clapper(self, im):
|
def is_phone_clapper(self, im):
|
||||||
limit = im.size
|
limit = im.size
|
||||||
@@ -101,9 +103,7 @@ class AntiPhoneClapper(commands.Cog):
|
|||||||
if phone_clapper:
|
if phone_clapper:
|
||||||
try:
|
try:
|
||||||
await m.delete()
|
await m.delete()
|
||||||
await m.channel.send(
|
await m.channel.send(f"{m.author.mention} just tried to send a phone-killing GIF and I removed it.")
|
||||||
f"{m.author.mention} just tried to send a phone-killing GIF and I removed it."
|
|
||||||
)
|
|
||||||
return
|
return
|
||||||
except discord.errors.Forbidden:
|
except discord.errors.Forbidden:
|
||||||
await m.channel.send(f"Don't send GIFs that do that, {m.author.mention}")
|
await m.channel.send(f"Don't send GIFs that do that, {m.author.mention}")
|
||||||
|
|||||||
@@ -11,5 +11,6 @@
|
|||||||
"pillow"
|
"pillow"
|
||||||
],
|
],
|
||||||
"short": "Deletes messages with malformed GIFs.",
|
"short": "Deletes messages with malformed GIFs.",
|
||||||
"type": "COG"
|
"type": "COG",
|
||||||
|
"end_user_data_statement": "This cog does not persistently store data or metadata about users."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,16 @@
|
|||||||
from .away import Away
|
from .away import Away
|
||||||
|
|
||||||
|
__red_end_user_data_statement__ = (
|
||||||
|
"This cog stores data provided by users "
|
||||||
|
"for the express purpose of redisplaying. "
|
||||||
|
"It does not store user data which was not "
|
||||||
|
"provided through a command. "
|
||||||
|
"Users may remove their own content "
|
||||||
|
"without making a data removal request. "
|
||||||
|
"This cog does not support data requests, "
|
||||||
|
"but will respect deletion requests."
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def setup(bot):
|
def setup(bot):
|
||||||
bot.add_cog(Away(bot))
|
bot.add_cog(Away(bot))
|
||||||
|
|||||||
55
away/away.py
55
away/away.py
@@ -1,6 +1,6 @@
|
|||||||
import discord
|
import discord
|
||||||
from redbot.core import Config, commands, checks
|
from redbot.core import Config, commands, checks
|
||||||
from typing import Optional
|
from typing import Optional, Literal
|
||||||
import datetime
|
import datetime
|
||||||
import re
|
import re
|
||||||
|
|
||||||
@@ -22,6 +22,11 @@ class Away(commands.Cog):
|
|||||||
"LISTENING_MESSAGE": False,
|
"LISTENING_MESSAGE": False,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async def red_delete_data_for_user(
|
||||||
|
self, *, requester: Literal["discord", "owner", "user", "user_strict"], user_id: int,
|
||||||
|
):
|
||||||
|
await self._away.user_from_id(user_id).clear()
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
self._away = Config.get_conf(self, 8423491260, force_registration=True)
|
self._away = Config.get_conf(self, 8423491260, force_registration=True)
|
||||||
@@ -69,17 +74,14 @@ class Away(commands.Cog):
|
|||||||
em.set_author(name=f"{author.display_name} is currently idle", icon_url=avatar)
|
em.set_author(name=f"{author.display_name} is currently idle", icon_url=avatar)
|
||||||
elif state == "dnd":
|
elif state == "dnd":
|
||||||
em = discord.Embed(description=message, color=color)
|
em = discord.Embed(description=message, color=color)
|
||||||
em.set_author(
|
em.set_author(name=f"{author.display_name} is currently do not disturb", icon_url=avatar)
|
||||||
name=f"{author.display_name} is currently do not disturb", icon_url=avatar
|
|
||||||
)
|
|
||||||
elif state == "offline":
|
elif state == "offline":
|
||||||
em = discord.Embed(description=message, color=color)
|
em = discord.Embed(description=message, color=color)
|
||||||
em.set_author(name=f"{author.display_name} is currently offline", icon_url=avatar)
|
em.set_author(name=f"{author.display_name} is currently offline", icon_url=avatar)
|
||||||
elif state == "gaming":
|
elif state == "gaming":
|
||||||
em = discord.Embed(description=message, color=color)
|
em = discord.Embed(description=message, color=color)
|
||||||
em.set_author(
|
em.set_author(
|
||||||
name=f"{author.display_name} is currently playing {author.activity.name}",
|
name=f"{author.display_name} is currently playing {author.activity.name}", icon_url=avatar,
|
||||||
icon_url=avatar,
|
|
||||||
)
|
)
|
||||||
em.title = getattr(author.activity, "details", None)
|
em.title = getattr(author.activity, "details", None)
|
||||||
thumbnail = getattr(author.activity, "large_image_url", None)
|
thumbnail = getattr(author.activity, "large_image_url", None)
|
||||||
@@ -89,8 +91,7 @@ class Away(commands.Cog):
|
|||||||
status = [c for c in author.activities if c.type == discord.ActivityType.playing]
|
status = [c for c in author.activities if c.type == discord.ActivityType.playing]
|
||||||
em = discord.Embed(description=message, color=color)
|
em = discord.Embed(description=message, color=color)
|
||||||
em.set_author(
|
em.set_author(
|
||||||
name=f"{author.display_name} is currently playing {status[0].name}",
|
name=f"{author.display_name} is currently playing {status[0].name}", icon_url=avatar,
|
||||||
icon_url=avatar,
|
|
||||||
)
|
)
|
||||||
em.title = getattr(status[0], "details", None)
|
em.title = getattr(status[0], "details", None)
|
||||||
thumbnail = getattr(status[0], "large_image_url", None)
|
thumbnail = getattr(status[0], "large_image_url", None)
|
||||||
@@ -140,8 +141,7 @@ class Away(commands.Cog):
|
|||||||
em.description = message + "\n" + author.activity.url
|
em.description = message + "\n" + author.activity.url
|
||||||
em.title = getattr(author.activity, "details", None)
|
em.title = getattr(author.activity, "details", None)
|
||||||
em.set_author(
|
em.set_author(
|
||||||
name=f"{author.display_name} is currently streaming {author.activity.name}",
|
name=f"{author.display_name} is currently streaming {author.activity.name}", icon_url=avatar,
|
||||||
icon_url=avatar,
|
|
||||||
)
|
)
|
||||||
elif state == "streamingcustom":
|
elif state == "streamingcustom":
|
||||||
activity = [c for c in author.activities if c.type == discord.ActivityType.streaming]
|
activity = [c for c in author.activities if c.type == discord.ActivityType.streaming]
|
||||||
@@ -150,8 +150,7 @@ class Away(commands.Cog):
|
|||||||
em.description = message + "\n" + activity[0].url
|
em.description = message + "\n" + activity[0].url
|
||||||
em.title = getattr(author.activity, "details", None)
|
em.title = getattr(author.activity, "details", None)
|
||||||
em.set_author(
|
em.set_author(
|
||||||
name=f"{author.display_name} is currently streaming {activity[0].name}",
|
name=f"{author.display_name} is currently streaming {activity[0].name}", icon_url=avatar,
|
||||||
icon_url=avatar,
|
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
em = discord.Embed(color=color)
|
em = discord.Embed(color=color)
|
||||||
@@ -191,9 +190,7 @@ class Away(commands.Cog):
|
|||||||
status = [c for c in author.activities if c.type == discord.ActivityType.playing]
|
status = [c for c in author.activities if c.type == discord.ActivityType.playing]
|
||||||
msg = f"{author.display_name} is currently playing {status[0].name}"
|
msg = f"{author.display_name} is currently playing {status[0].name}"
|
||||||
elif state == "listening":
|
elif state == "listening":
|
||||||
artist_title = f"{author.activity.title} by " + ", ".join(
|
artist_title = f"{author.activity.title} by " + ", ".join(a for a in author.activity.artists)
|
||||||
a for a in author.activity.artists
|
|
||||||
)
|
|
||||||
currently_playing = self._draw_play(author.activity)
|
currently_playing = self._draw_play(author.activity)
|
||||||
msg = f"{author.display_name} is currently listening to {artist_title}\n{currently_playing}"
|
msg = f"{author.display_name} is currently listening to {artist_title}\n{currently_playing}"
|
||||||
elif state == "listeningcustom":
|
elif state == "listeningcustom":
|
||||||
@@ -313,9 +310,7 @@ class Away(commands.Cog):
|
|||||||
await message.channel.send(msg, delete_after=delete_after)
|
await message.channel.send(msg, delete_after=delete_after)
|
||||||
continue
|
continue
|
||||||
if streaming_msg and type(author.activity) is discord.CustomActivity:
|
if streaming_msg and type(author.activity) is discord.CustomActivity:
|
||||||
stream_status = [
|
stream_status = [c for c in author.activities if c.type == discord.ActivityType.streaming]
|
||||||
c for c in author.activities if c.type == discord.ActivityType.streaming
|
|
||||||
]
|
|
||||||
if not stream_status:
|
if not stream_status:
|
||||||
continue
|
continue
|
||||||
streaming_msg, delete_after = streaming_msg
|
streaming_msg, delete_after = streaming_msg
|
||||||
@@ -337,9 +332,7 @@ class Away(commands.Cog):
|
|||||||
await message.channel.send(msg, delete_after=delete_after)
|
await message.channel.send(msg, delete_after=delete_after)
|
||||||
continue
|
continue
|
||||||
if listening_msg and type(author.activity) is discord.CustomActivity:
|
if listening_msg and type(author.activity) is discord.CustomActivity:
|
||||||
listening_status = [
|
listening_status = [c for c in author.activities if c.type == discord.ActivityType.listening]
|
||||||
c for c in author.activities if c.type == discord.ActivityType.listening
|
|
||||||
]
|
|
||||||
if not listening_status:
|
if not listening_status:
|
||||||
continue
|
continue
|
||||||
listening_msg, delete_after = listening_msg
|
listening_msg, delete_after = listening_msg
|
||||||
@@ -364,9 +357,7 @@ class Away(commands.Cog):
|
|||||||
await message.channel.send(msg, delete_after=delete_after)
|
await message.channel.send(msg, delete_after=delete_after)
|
||||||
break
|
break
|
||||||
if gaming_msgs and type(author.activity) is discord.CustomActivity:
|
if gaming_msgs and type(author.activity) is discord.CustomActivity:
|
||||||
game_status = [
|
game_status = [c for c in author.activities if c.type == discord.ActivityType.playing]
|
||||||
c for c in author.activities if c.type == discord.ActivityType.playing
|
|
||||||
]
|
|
||||||
if not game_status:
|
if not game_status:
|
||||||
continue
|
continue
|
||||||
for game in gaming_msgs:
|
for game in gaming_msgs:
|
||||||
@@ -501,15 +492,11 @@ class Away(commands.Cog):
|
|||||||
msg = "The bot will no longer reply for you when you're mentioned while listening to Spotify."
|
msg = "The bot will no longer reply for you when you're mentioned while listening to Spotify."
|
||||||
else:
|
else:
|
||||||
await self._away.user(author).LISTENING_MESSAGE.set((message, delete_after))
|
await self._away.user(author).LISTENING_MESSAGE.set((message, delete_after))
|
||||||
msg = (
|
msg = "The bot will now reply for you when you're mentioned while listening to Spotify."
|
||||||
"The bot will now reply for you when you're mentioned while listening to Spotify."
|
|
||||||
)
|
|
||||||
await ctx.send(msg)
|
await ctx.send(msg)
|
||||||
|
|
||||||
@commands.command(name="gaming")
|
@commands.command(name="gaming")
|
||||||
async def gaming_(
|
async def gaming_(self, ctx, game: str, delete_after: Optional[int] = None, *, message: str = None):
|
||||||
self, ctx, game: str, delete_after: Optional[int] = None, *, message: str = None
|
|
||||||
):
|
|
||||||
"""
|
"""
|
||||||
Set an automatic reply when you're playing a specified game.
|
Set an automatic reply when you're playing a specified game.
|
||||||
|
|
||||||
@@ -567,7 +554,9 @@ class Away(commands.Cog):
|
|||||||
if text_only:
|
if text_only:
|
||||||
message = "Away messages will now be embedded or text only based on the bot's permissions for embed links."
|
message = "Away messages will now be embedded or text only based on the bot's permissions for embed links."
|
||||||
else:
|
else:
|
||||||
message = "Away messages are now forced to be text only, regardless of the bot's permissions for embed links."
|
message = (
|
||||||
|
"Away messages are now forced to be text only, regardless of the bot's permissions for embed links."
|
||||||
|
)
|
||||||
await self._away.guild(ctx.guild).TEXT_ONLY.set(not text_only)
|
await self._away.guild(ctx.guild).TEXT_ONLY.set(not text_only)
|
||||||
await ctx.send(message)
|
await ctx.send(message)
|
||||||
|
|
||||||
@@ -619,9 +608,7 @@ class Away(commands.Cog):
|
|||||||
|
|
||||||
if ctx.channel.permissions_for(ctx.me).embed_links:
|
if ctx.channel.permissions_for(ctx.me).embed_links:
|
||||||
em = discord.Embed(description=msg[:2048], color=author.color)
|
em = discord.Embed(description=msg[:2048], color=author.color)
|
||||||
em.set_author(
|
em.set_author(name=f"{author.display_name}'s away settings", icon_url=author.avatar_url)
|
||||||
name=f"{author.display_name}'s away settings", icon_url=author.avatar_url
|
|
||||||
)
|
|
||||||
await ctx.send(embed=em)
|
await ctx.send(embed=em)
|
||||||
else:
|
else:
|
||||||
await ctx.send(f"{author.display_name} away settings\n" + msg)
|
await ctx.send(f"{author.display_name} away settings\n" + msg)
|
||||||
|
|||||||
@@ -8,5 +8,6 @@
|
|||||||
"tags": [
|
"tags": [
|
||||||
"away"
|
"away"
|
||||||
],
|
],
|
||||||
"type": "COG"
|
"type": "COG",
|
||||||
|
"end_user_data_statement": "This cog stores data provided by users for the express purpose of redisplaying. It does not store user data which was not provided through a command. Users may remove their own content without making a data removal request. This cog does not support data requests, but will respect deletion requests."
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
from .blurplefy import Blurplefy
|
from .blurplefy import Blurplefy
|
||||||
|
|
||||||
|
__red_end_user_data_statement__ = "This cog does not persistently store data or metadata about users."
|
||||||
|
|
||||||
|
|
||||||
def setup(bot):
|
def setup(bot):
|
||||||
bot.add_cog(Blurplefy(bot))
|
bot.add_cog(Blurplefy(bot))
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ from PIL import Image, ImageEnhance, ImageSequence
|
|||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
import aiohttp
|
import aiohttp
|
||||||
import asyncio
|
import asyncio
|
||||||
import copy
|
|
||||||
import datetime
|
import datetime
|
||||||
import io
|
import io
|
||||||
import math
|
import math
|
||||||
@@ -15,12 +14,16 @@ from resizeimage import resizeimage
|
|||||||
from redbot.core import Config, commands, checks
|
from redbot.core import Config, commands, checks
|
||||||
|
|
||||||
blurple = (114, 137, 218)
|
blurple = (114, 137, 218)
|
||||||
blurplehex = 0x7289da
|
blurplehex = 0x7289DA
|
||||||
darkblurple = (78, 93, 148)
|
darkblurple = (78, 93, 148)
|
||||||
white = (255, 255, 255)
|
white = (255, 255, 255)
|
||||||
|
|
||||||
|
|
||||||
class Blurplefy(commands.Cog):
|
class Blurplefy(commands.Cog):
|
||||||
|
async def red_delete_data_for_user(self, **kwargs):
|
||||||
|
""" Nothing to delete """
|
||||||
|
return
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
"""Blurplefy images and check content of images."""
|
"""Blurplefy images and check content of images."""
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
@@ -38,9 +41,7 @@ class Blurplefy(commands.Cog):
|
|||||||
"""Toggle a role award for having a blurple profile picture."""
|
"""Toggle a role award for having a blurple profile picture."""
|
||||||
blurple_role_id = await self.config.guild(ctx.guild).blurple_role()
|
blurple_role_id = await self.config.guild(ctx.guild).blurple_role()
|
||||||
if blurple_role_id is None:
|
if blurple_role_id is None:
|
||||||
await ctx.send(
|
await ctx.send("Enter the role name to award: it needs to be a valid, already existing role.")
|
||||||
"Enter the role name to award: it needs to be a valid, already existing role."
|
|
||||||
)
|
|
||||||
|
|
||||||
def check(m):
|
def check(m):
|
||||||
return m.author == ctx.author
|
return m.author == ctx.author
|
||||||
@@ -140,11 +141,7 @@ class Blurplefy(commands.Cog):
|
|||||||
im = resizeimage.resize_width(im, (imsize[0] * downsizefraction))
|
im = resizeimage.resize_width(im, (imsize[0] * downsizefraction))
|
||||||
imsize = list(im.size)
|
imsize = list(im.size)
|
||||||
impixels = imsize[0] * imsize[1]
|
impixels = imsize[0] * imsize[1]
|
||||||
await ctx.send(
|
await ctx.send("{}, image resized smaller for easier processing.".format(ctx.message.author.display_name))
|
||||||
"{}, image resized smaller for easier processing.".format(
|
|
||||||
ctx.message.author.display_name
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
image = self.blurple_imager(im, imsize)
|
image = self.blurple_imager(im, imsize)
|
||||||
image = discord.File(fp=image, filename="image.png")
|
image = discord.File(fp=image, filename="image.png")
|
||||||
@@ -155,19 +152,11 @@ class Blurplefy(commands.Cog):
|
|||||||
percentwhite = round(((noofwhitepixels / noofpixels) * 100), 2)
|
percentwhite = round(((noofwhitepixels / noofpixels) * 100), 2)
|
||||||
|
|
||||||
embed = discord.Embed(title="", colour=0x7289DA)
|
embed = discord.Embed(title="", colour=0x7289DA)
|
||||||
|
embed.add_field(name="Total amount of Blurple", value="{}%".format(blurplenesspercentage), inline=False)
|
||||||
|
embed.add_field(name="Blurple (rgb(114, 137, 218))", value="{}%".format(percentblurple), inline=True)
|
||||||
|
embed.add_field(name="White (rgb(255, 255, 255))", value="{}\%".format(percentwhite), inline=True)
|
||||||
embed.add_field(
|
embed.add_field(
|
||||||
name="Total amount of Blurple", value="{}%".format(blurplenesspercentage), inline=False
|
name="Dark Blurple (rgb(78, 93, 148))", value="{}\%".format(percentdblurple), inline=True,
|
||||||
)
|
|
||||||
embed.add_field(
|
|
||||||
name="Blurple (rgb(114, 137, 218))", value="{}%".format(percentblurple), inline=True
|
|
||||||
)
|
|
||||||
embed.add_field(
|
|
||||||
name="White (rgb(255, 255, 255))", value="{}\%".format(percentwhite), inline=True
|
|
||||||
)
|
|
||||||
embed.add_field(
|
|
||||||
name="Dark Blurple (rgb(78, 93, 148))",
|
|
||||||
value="{}\%".format(percentdblurple),
|
|
||||||
inline=True,
|
|
||||||
)
|
)
|
||||||
embed.add_field(
|
embed.add_field(
|
||||||
name="Guide",
|
name="Guide",
|
||||||
@@ -247,20 +236,14 @@ class Blurplefy(commands.Cog):
|
|||||||
except Exception:
|
except Exception:
|
||||||
isgif = False
|
isgif = False
|
||||||
|
|
||||||
await ctx.send(
|
await ctx.send("{}, image fetched, analyzing image...".format(ctx.message.author.display_name))
|
||||||
"{}, image fetched, analyzing image...".format(ctx.message.author.display_name)
|
|
||||||
)
|
|
||||||
|
|
||||||
if impixels > maxpixelcount:
|
if impixels > maxpixelcount:
|
||||||
downsizefraction = math.sqrt(maxpixelcount / impixels)
|
downsizefraction = math.sqrt(maxpixelcount / impixels)
|
||||||
im = resizeimage.resize_width(im, (imsize[0] * downsizefraction))
|
im = resizeimage.resize_width(im, (imsize[0] * downsizefraction))
|
||||||
imsize = list(im.size)
|
imsize = list(im.size)
|
||||||
impixels = imsize[0] * imsize[1]
|
impixels = imsize[0] * imsize[1]
|
||||||
await ctx.send(
|
await ctx.send("{}, image resized smaller for easier processing".format(ctx.message.author.display_name))
|
||||||
"{}, image resized smaller for easier processing".format(
|
|
||||||
ctx.message.author.display_name
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
if isgif is False:
|
if isgif is False:
|
||||||
image = self.imager(im, imsize)
|
image = self.imager(im, imsize)
|
||||||
@@ -323,9 +306,7 @@ class Blurplefy(commands.Cog):
|
|||||||
for i in range(3):
|
for i in range(3):
|
||||||
if not (blurple[i] + colourbuffer > pixel[i] > blurple[i] - colourbuffer):
|
if not (blurple[i] + colourbuffer > pixel[i] > blurple[i] - colourbuffer):
|
||||||
checkblurple = 0
|
checkblurple = 0
|
||||||
if not (
|
if not (darkblurple[i] + colourbuffer > pixel[i] > darkblurple[i] - colourbuffer):
|
||||||
darkblurple[i] + colourbuffer > pixel[i] > darkblurple[i] - colourbuffer
|
|
||||||
):
|
|
||||||
checkdarkblurple = 0
|
checkdarkblurple = 0
|
||||||
if not (white[i] + colourbuffer > pixel[i] > white[i] - colourbuffer):
|
if not (white[i] + colourbuffer > pixel[i] > white[i] - colourbuffer):
|
||||||
checkwhite = 0
|
checkwhite = 0
|
||||||
@@ -397,19 +378,11 @@ class Blurplefy(commands.Cog):
|
|||||||
@commands.command()
|
@commands.command()
|
||||||
async def countdown(self, ctx):
|
async def countdown(self, ctx):
|
||||||
"""Countdown to Discord's 6th Anniversary."""
|
"""Countdown to Discord's 6th Anniversary."""
|
||||||
embed = discord.Embed(name="", colour=0x7289da)
|
embed = discord.Embed(name="", colour=0x7289DA)
|
||||||
timeleft = (
|
timeleft = datetime.datetime(2020, 5, 13) + datetime.timedelta(hours=7) - datetime.datetime.utcnow()
|
||||||
datetime.datetime(2020, 5, 13)
|
|
||||||
+ datetime.timedelta(hours=7)
|
|
||||||
- datetime.datetime.utcnow()
|
|
||||||
)
|
|
||||||
embed.set_author(name="Time left until Discord's 6th Anniversary")
|
embed.set_author(name="Time left until Discord's 6th Anniversary")
|
||||||
if int(timeleft.total_seconds()) < 0:
|
if int(timeleft.total_seconds()) < 0:
|
||||||
timeleft = (
|
timeleft = datetime.datetime(2021, 5, 13) + datetime.timedelta(hours=7) - datetime.datetime.utcnow()
|
||||||
datetime.datetime(2021, 5, 13)
|
|
||||||
+ datetime.timedelta(hours=7)
|
|
||||||
- datetime.datetime.utcnow()
|
|
||||||
)
|
|
||||||
embed.set_author(name="Time left until Discord's 6th Anniversary")
|
embed.set_author(name="Time left until Discord's 6th Anniversary")
|
||||||
embed.add_field(
|
embed.add_field(
|
||||||
name="Countdown to midnight, May 13, California time (UTC-7):",
|
name="Countdown to midnight, May 13, California time (UTC-7):",
|
||||||
|
|||||||
@@ -18,5 +18,6 @@
|
|||||||
"image",
|
"image",
|
||||||
"profile"
|
"profile"
|
||||||
],
|
],
|
||||||
"type": "COG"
|
"type": "COG",
|
||||||
|
"end_user_data_statement": "This cog does not persistently store data or metadata about users."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
from .cah import CardsAgainstHumanity
|
from .cah import CardsAgainstHumanity
|
||||||
|
|
||||||
|
__red_end_user_data_statement__ = "This cog does not persistently store data or metadata about users."
|
||||||
|
|
||||||
|
|
||||||
def setup(bot):
|
def setup(bot):
|
||||||
bot.add_cog(CardsAgainstHumanity(bot))
|
bot.add_cog(CardsAgainstHumanity(bot))
|
||||||
|
|||||||
109
cah/cah.py
109
cah/cah.py
@@ -10,19 +10,19 @@ from redbot.core.data_manager import bundled_data_path
|
|||||||
|
|
||||||
|
|
||||||
class CardsAgainstHumanity(commands.Cog):
|
class CardsAgainstHumanity(commands.Cog):
|
||||||
|
async def red_delete_data_for_user(self, **kwargs):
|
||||||
|
""" Nothing to delete """
|
||||||
|
return
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
self.games = []
|
self.games = []
|
||||||
self.maxBots = (
|
self.maxBots = 5 # Max number of bots that can be added to a game - don't count toward max players
|
||||||
5 # Max number of bots that can be added to a game - don't count toward max players
|
|
||||||
)
|
|
||||||
self.maxPlayers = 10 # Max players for ranjom joins
|
self.maxPlayers = 10 # Max players for ranjom joins
|
||||||
self.maxDeadTime = 3600 # Allow an hour of dead time before killing a game
|
self.maxDeadTime = 3600 # Allow an hour of dead time before killing a game
|
||||||
self.checkTime = 300 # 5 minutes between dead time checks
|
self.checkTime = 300 # 5 minutes between dead time checks
|
||||||
self.winAfter = 10 # 10 wins for the game
|
self.winAfter = 10 # 10 wins for the game
|
||||||
self.botWaitMin = (
|
self.botWaitMin = 5 # Minimum number of seconds before the bot makes a decision (default 5)
|
||||||
5 # Minimum number of seconds before the bot makes a decision (default 5)
|
|
||||||
)
|
|
||||||
self.botWaitMax = 30 # Max number of seconds before a bot makes a decision (default 30)
|
self.botWaitMax = 30 # Max number of seconds before a bot makes a decision (default 30)
|
||||||
self.userTimeout = 500 # 5 minutes to timeout
|
self.userTimeout = 500 # 5 minutes to timeout
|
||||||
self.utCheck = 30 # Check timeout every 30 seconds
|
self.utCheck = 30 # Check timeout every 30 seconds
|
||||||
@@ -196,8 +196,7 @@ class CardsAgainstHumanity(commands.Cog):
|
|||||||
member["Task"] = None
|
member["Task"] = None
|
||||||
continue
|
continue
|
||||||
await self.sendToUser(
|
await self.sendToUser(
|
||||||
member["User"],
|
member["User"], f"Game id: *{game['ID']}* has been closed due to inactivity.",
|
||||||
f"Game id: *{game['ID']}* has been closed due to inactivity.",
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Set running to false
|
# Set running to false
|
||||||
@@ -211,9 +210,7 @@ class CardsAgainstHumanity(commands.Cog):
|
|||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
# Not in PM
|
# Not in PM
|
||||||
await message.channel.send(
|
await message.channel.send("Cards Against Humanity commands must be run in Direct Messages with the bot.")
|
||||||
"Cards Against Humanity commands must be run in Direct Messages with the bot."
|
|
||||||
)
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def randomID(self, length=8):
|
def randomID(self, length=8):
|
||||||
@@ -310,8 +307,7 @@ class CardsAgainstHumanity(commands.Cog):
|
|||||||
if not newCreator["IsBot"]:
|
if not newCreator["IsBot"]:
|
||||||
newCreator["Creator"] = True
|
newCreator["Creator"] = True
|
||||||
await self.sendToUser(
|
await self.sendToUser(
|
||||||
newCreator["User"],
|
newCreator["User"], "The creator of this game left. **YOU** are now the creator.",
|
||||||
"The creator of this game left. **YOU** are now the creator.",
|
|
||||||
)
|
)
|
||||||
break
|
break
|
||||||
|
|
||||||
@@ -330,8 +326,7 @@ class CardsAgainstHumanity(commands.Cog):
|
|||||||
member["Task"] = None
|
member["Task"] = None
|
||||||
else:
|
else:
|
||||||
await self.sendToUser(
|
await self.sendToUser(
|
||||||
member["User"],
|
member["User"], f"**You were removed from game id:** ***{game['ID']}.***",
|
||||||
f"**You were removed from game id:** ***{game['ID']}.***",
|
|
||||||
)
|
)
|
||||||
# Removed, no need to finish the loop
|
# Removed, no need to finish the loop
|
||||||
break
|
break
|
||||||
@@ -456,9 +451,7 @@ class CardsAgainstHumanity(commands.Cog):
|
|||||||
name=f"Not enough players to continue! ({len(game['Members'])}/{self.minMembers})"
|
name=f"Not enough players to continue! ({len(game['Members'])}/{self.minMembers})"
|
||||||
)
|
)
|
||||||
prefix = await self.bot.get_valid_prefixes()
|
prefix = await self.bot.get_valid_prefixes()
|
||||||
stat_embed.set_footer(
|
stat_embed.set_footer(text=f"Have other users join with: {prefix[0]}joincah {game['ID']}")
|
||||||
text=f"Have other users join with: {prefix[0]}joincah {game['ID']}"
|
|
||||||
)
|
|
||||||
await self.sendToUser(member["User"], stat_embed, True)
|
await self.sendToUser(member["User"], stat_embed, True)
|
||||||
continue
|
continue
|
||||||
if member["IsBot"] == True:
|
if member["IsBot"] == True:
|
||||||
@@ -541,13 +534,9 @@ class CardsAgainstHumanity(commands.Cog):
|
|||||||
else:
|
else:
|
||||||
stat_embed.set_author(name=f"{winnerName} won!")
|
stat_embed.set_author(name=f"{winnerName} won!")
|
||||||
if len(winner["Cards"]) == 1:
|
if len(winner["Cards"]) == 1:
|
||||||
msg = "The **Winning** card was:\n\n{}".format(
|
msg = "The **Winning** card was:\n\n{}".format("{}".format(" - ".join(winner["Cards"])))
|
||||||
"{}".format(" - ".join(winner["Cards"]))
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
msg = "The **Winning** cards were:\n\n{}".format(
|
msg = "The **Winning** cards were:\n\n{}".format("{}".format(" - ".join(winner["Cards"])))
|
||||||
"{}".format(" - ".join(winner["Cards"]))
|
|
||||||
)
|
|
||||||
await self.sendToUser(member["User"], stat_embed, True)
|
await self.sendToUser(member["User"], stat_embed, True)
|
||||||
await self.sendToUser(member["User"], msg)
|
await self.sendToUser(member["User"], msg)
|
||||||
await asyncio.sleep(0.1)
|
await asyncio.sleep(0.1)
|
||||||
@@ -788,13 +777,9 @@ class CardsAgainstHumanity(commands.Cog):
|
|||||||
# Advances the game
|
# Advances the game
|
||||||
if len(game["Members"]) < self.minMembers:
|
if len(game["Members"]) < self.minMembers:
|
||||||
stat_embed = discord.Embed(color=discord.Color.red())
|
stat_embed = discord.Embed(color=discord.Color.red())
|
||||||
stat_embed.set_author(
|
stat_embed.set_author(name=f"Not enough players to continue! ({len(game['Members'])}/{self.minMembers})")
|
||||||
name=f"Not enough players to continue! ({len(game['Members'])}/{self.minMembers})"
|
|
||||||
)
|
|
||||||
prefix = await self.bot.get_valid_prefixes()
|
prefix = await self.bot.get_valid_prefixes()
|
||||||
stat_embed.set_footer(
|
stat_embed.set_footer(text=f"Have other users join with: {prefix[0]}joincah {game['ID']}")
|
||||||
text=f"Have other users join with: {prefix[0]}joincah {game['ID']}"
|
|
||||||
)
|
|
||||||
for member in game["Members"]:
|
for member in game["Members"]:
|
||||||
if member["IsBot"]:
|
if member["IsBot"]:
|
||||||
continue
|
continue
|
||||||
@@ -819,9 +804,7 @@ class CardsAgainstHumanity(commands.Cog):
|
|||||||
if member["IsBot"]:
|
if member["IsBot"]:
|
||||||
stat_embed.set_author(name=f"{self.botName} ({member['ID']}) is the WINNER!!")
|
stat_embed.set_author(name=f"{self.botName} ({member['ID']}) is the WINNER!!")
|
||||||
else:
|
else:
|
||||||
stat_embed.set_author(
|
stat_embed.set_author(name=f"{self.displayname(member['User'])} is the WINNER!!")
|
||||||
name=f"{self.displayname(member['User'])} is the WINNER!!"
|
|
||||||
)
|
|
||||||
stat_embed.set_footer(text="Congratulations!")
|
stat_embed.set_footer(text="Congratulations!")
|
||||||
break
|
break
|
||||||
if winner:
|
if winner:
|
||||||
@@ -935,9 +918,7 @@ class CardsAgainstHumanity(commands.Cog):
|
|||||||
user = member
|
user = member
|
||||||
index = userGame["Members"].index(member)
|
index = userGame["Members"].index(member)
|
||||||
if index == userGame["Judge"]:
|
if index == userGame["Judge"]:
|
||||||
await self.sendToUser(
|
await self.sendToUser(ctx.author, "You're the judge. You don't get to lay cards this round.")
|
||||||
ctx.author, "You're the judge. You don't get to lay cards this round."
|
|
||||||
)
|
|
||||||
return
|
return
|
||||||
for submit in userGame["Submitted"]:
|
for submit in userGame["Submitted"]:
|
||||||
if submit["By"]["User"] == ctx.author:
|
if submit["By"]["User"] == ctx.author:
|
||||||
@@ -954,9 +935,7 @@ class CardsAgainstHumanity(commands.Cog):
|
|||||||
stat_embed.set_author(
|
stat_embed.set_author(
|
||||||
name=f"Not enough players to continue! ({len(userGame['Members'])}/{self.minMembers})"
|
name=f"Not enough players to continue! ({len(userGame['Members'])}/{self.minMembers})"
|
||||||
)
|
)
|
||||||
stat_embed.set_footer(
|
stat_embed.set_footer(text=f"Have other users join with: {prefix[0]}joincah {userGame['ID']}")
|
||||||
text=f"Have other users join with: {prefix[0]}joincah {userGame['ID']}"
|
|
||||||
)
|
|
||||||
return await self.sendToUser(ctx.author, stat_embed, True)
|
return await self.sendToUser(ctx.author, stat_embed, True)
|
||||||
|
|
||||||
numberCards = userGame["BlackCard"]["Pick"]
|
numberCards = userGame["BlackCard"]["Pick"]
|
||||||
@@ -992,9 +971,7 @@ class CardsAgainstHumanity(commands.Cog):
|
|||||||
)
|
)
|
||||||
return await self.showHand(ctx, ctx.author)
|
return await self.showHand(ctx, ctx.author)
|
||||||
if c < 1 or c > len(user["Hand"]):
|
if c < 1 or c > len(user["Hand"]):
|
||||||
await self.sendToUser(
|
await self.sendToUser(ctx.author, f"Card numbers must be between 1 and {len(user['Hand'])}.")
|
||||||
ctx.author, f"Card numbers must be between 1 and {len(user['Hand'])}."
|
|
||||||
)
|
|
||||||
return await self.showHand(ctx, ctx.author)
|
return await self.showHand(ctx, ctx.author)
|
||||||
cards.append(user["Hand"][c - 1]["Text"])
|
cards.append(user["Hand"][c - 1]["Text"])
|
||||||
# Remove from user's hand
|
# Remove from user's hand
|
||||||
@@ -1009,14 +986,10 @@ class CardsAgainstHumanity(commands.Cog):
|
|||||||
try:
|
try:
|
||||||
card = int(card)
|
card = int(card)
|
||||||
except Exception:
|
except Exception:
|
||||||
await self.sendToUser(
|
await self.sendToUser(ctx.author, f"You need to lay a valid card with `{prefix[0]}lay [card number]`")
|
||||||
ctx.author, f"You need to lay a valid card with `{prefix[0]}lay [card number]`"
|
|
||||||
)
|
|
||||||
return await self.showHand(ctx, ctx.author)
|
return await self.showHand(ctx, ctx.author)
|
||||||
if card < 1 or card > len(user["Hand"]):
|
if card < 1 or card > len(user["Hand"]):
|
||||||
await self.sendToUser(
|
await self.sendToUser(ctx.author, f"Card numbers must be between 1 and {len(user['Hand'])}.")
|
||||||
ctx.author, f"Card numbers must be between 1 and {len(user['Hand'])}."
|
|
||||||
)
|
|
||||||
return await self.showHand(ctx, ctx.author)
|
return await self.showHand(ctx, ctx.author)
|
||||||
# Valid card
|
# Valid card
|
||||||
newSubmission = {"By": user, "Cards": [user["Hand"].pop(card - 1)["Text"]]}
|
newSubmission = {"By": user, "Cards": [user["Hand"].pop(card - 1)["Text"]]}
|
||||||
@@ -1068,9 +1041,7 @@ class CardsAgainstHumanity(commands.Cog):
|
|||||||
except Exception:
|
except Exception:
|
||||||
card = -1
|
card = -1
|
||||||
if card < 0 or card >= totalUsers:
|
if card < 0 or card >= totalUsers:
|
||||||
return await self.sendToUser(
|
return await self.sendToUser(ctx.author, f"Your pick must be between 1 and {totalUsers}.")
|
||||||
ctx.author, f"Your pick must be between 1 and {totalUsers}."
|
|
||||||
)
|
|
||||||
# Pick is good!
|
# Pick is good!
|
||||||
await self.winningCard(ctx, userGame, card)
|
await self.winningCard(ctx, userGame, card)
|
||||||
|
|
||||||
@@ -1099,9 +1070,7 @@ class CardsAgainstHumanity(commands.Cog):
|
|||||||
embed.set_author(name="**Setting up the game...**")
|
embed.set_author(name="**Setting up the game...**")
|
||||||
await ctx.author.send(embed=embed)
|
await ctx.author.send(embed=embed)
|
||||||
except discord.errors.Forbidden:
|
except discord.errors.Forbidden:
|
||||||
return await ctx.send(
|
return await ctx.send("You must allow Direct Messages from the bot for this game to work.")
|
||||||
"You must allow Direct Messages from the bot for this game to work."
|
|
||||||
)
|
|
||||||
|
|
||||||
# Check if the user is already in game
|
# Check if the user is already in game
|
||||||
userGame = await self.userGame(ctx.author)
|
userGame = await self.userGame(ctx.author)
|
||||||
@@ -1178,9 +1147,7 @@ class CardsAgainstHumanity(commands.Cog):
|
|||||||
embed.set_author(name="**Setting up the game...**")
|
embed.set_author(name="**Setting up the game...**")
|
||||||
await ctx.author.send(embed=embed)
|
await ctx.author.send(embed=embed)
|
||||||
except discord.errors.Forbidden:
|
except discord.errors.Forbidden:
|
||||||
return await ctx.send(
|
return await ctx.send("You must allow Direct Messages from the bot for this game to work.")
|
||||||
"You must allow Direct Messages from the bot for this game to work."
|
|
||||||
)
|
|
||||||
|
|
||||||
# Check if the user is already in game
|
# Check if the user is already in game
|
||||||
userGame = await self.userGame(ctx.author)
|
userGame = await self.userGame(ctx.author)
|
||||||
@@ -1253,9 +1220,7 @@ class CardsAgainstHumanity(commands.Cog):
|
|||||||
for member in game["Members"]:
|
for member in game["Members"]:
|
||||||
if member["IsBot"]:
|
if member["IsBot"]:
|
||||||
continue
|
continue
|
||||||
await self.sendToUser(
|
await self.sendToUser(member["User"], f"***{self.displayname(ctx.author)}*** **joined the game!**")
|
||||||
member["User"], f"***{self.displayname(ctx.author)}*** **joined the game!**"
|
|
||||||
)
|
|
||||||
|
|
||||||
# We got a user!
|
# We got a user!
|
||||||
currentTime = int(time.time())
|
currentTime = int(time.time())
|
||||||
@@ -1328,9 +1293,7 @@ class CardsAgainstHumanity(commands.Cog):
|
|||||||
# We are the creator - let's check the number of bots
|
# We are the creator - let's check the number of bots
|
||||||
if botCount >= self.maxBots:
|
if botCount >= self.maxBots:
|
||||||
# Too many bots!
|
# Too many bots!
|
||||||
return await self.sendToUser(
|
return await self.sendToUser(ctx.author, f"You already have enough bots (max is {self.maxBots}).")
|
||||||
ctx.author, f"You already have enough bots (max is {self.maxBots})."
|
|
||||||
)
|
|
||||||
# We can get another bot!
|
# We can get another bot!
|
||||||
botID = self.randomBotID(userGame)
|
botID = self.randomBotID(userGame)
|
||||||
lobot = {
|
lobot = {
|
||||||
@@ -1350,9 +1313,7 @@ class CardsAgainstHumanity(commands.Cog):
|
|||||||
for member in userGame["Members"]:
|
for member in userGame["Members"]:
|
||||||
if member["IsBot"]:
|
if member["IsBot"]:
|
||||||
continue
|
continue
|
||||||
await self.sendToUser(
|
await self.sendToUser(member["User"], f"***{self.botName} ({botID})*** **joined the game!**")
|
||||||
member["User"], f"***{self.botName} ({botID})*** **joined the game!**"
|
|
||||||
)
|
|
||||||
# await self.nextPlay(ctx, userGame)
|
# await self.nextPlay(ctx, userGame)
|
||||||
|
|
||||||
# Check if adding put us at minimum members
|
# Check if adding put us at minimum members
|
||||||
@@ -1391,9 +1352,7 @@ class CardsAgainstHumanity(commands.Cog):
|
|||||||
if member["User"] == ctx.author:
|
if member["User"] == ctx.author:
|
||||||
if not member["Creator"]:
|
if not member["Creator"]:
|
||||||
# You didn't make this game
|
# You didn't make this game
|
||||||
return await self.sendToUser(
|
return await self.sendToUser(ctx.author, "Only the player that created the game can add bots.")
|
||||||
ctx.author, "Only the player that created the game can add bots."
|
|
||||||
)
|
|
||||||
member["Time"] = int(time.time())
|
member["Time"] = int(time.time())
|
||||||
if number == None:
|
if number == None:
|
||||||
# No number specified - let's add the max number of bots
|
# No number specified - let's add the max number of bots
|
||||||
@@ -1407,9 +1366,7 @@ class CardsAgainstHumanity(commands.Cog):
|
|||||||
# We are the creator - let's check the number of bots
|
# We are the creator - let's check the number of bots
|
||||||
if botCount >= self.maxBots:
|
if botCount >= self.maxBots:
|
||||||
# Too many bots!
|
# Too many bots!
|
||||||
return await self.sendToUser(
|
return await self.sendToUser(ctx.author, f"You already have enough bots (max is {self.maxBots}).")
|
||||||
ctx.author, f"You already have enough bots (max is {self.maxBots})."
|
|
||||||
)
|
|
||||||
|
|
||||||
if number > (self.maxBots - botCount):
|
if number > (self.maxBots - botCount):
|
||||||
number = self.maxBots - botCount
|
number = self.maxBots - botCount
|
||||||
@@ -1483,9 +1440,7 @@ class CardsAgainstHumanity(commands.Cog):
|
|||||||
if member["User"] == ctx.author:
|
if member["User"] == ctx.author:
|
||||||
if not member["Creator"]:
|
if not member["Creator"]:
|
||||||
# You didn't make this game
|
# You didn't make this game
|
||||||
return await self.sendToUser(
|
return await self.sendToUser(ctx.author, "Only the player that created the game can remove bots.")
|
||||||
ctx.author, "Only the player that created the game can remove bots."
|
|
||||||
)
|
|
||||||
member["Time"] = int(time.time())
|
member["Time"] = int(time.time())
|
||||||
# We are the creator - let's check the number of bots
|
# We are the creator - let's check the number of bots
|
||||||
if id == None:
|
if id == None:
|
||||||
@@ -1761,9 +1716,7 @@ class CardsAgainstHumanity(commands.Cog):
|
|||||||
if member["User"] == ctx.author:
|
if member["User"] == ctx.author:
|
||||||
if not member["Creator"]:
|
if not member["Creator"]:
|
||||||
# You didn't make this game
|
# You didn't make this game
|
||||||
return await self.sendToUser(
|
return await self.sendToUser(ctx.author, "Only the player that created the game can remove bots.")
|
||||||
ctx.author, "Only the player that created the game can remove bots."
|
|
||||||
)
|
|
||||||
# We are the creator - let's check the number of bots
|
# We are the creator - let's check the number of bots
|
||||||
if setting == None:
|
if setting == None:
|
||||||
# Output idle kick status
|
# Output idle kick status
|
||||||
|
|||||||
@@ -14,5 +14,6 @@
|
|||||||
"cards",
|
"cards",
|
||||||
"games"
|
"games"
|
||||||
],
|
],
|
||||||
"type": "COG"
|
"type": "COG",
|
||||||
|
"end_user_data_statement": "This cog does not persistently store data or metadata about users."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
from .chatchart import Chatchart
|
from .chatchart import Chatchart
|
||||||
|
|
||||||
|
__red_end_user_data_statement__ = "This cog does not persistently store data or metadata about users."
|
||||||
|
|
||||||
|
|
||||||
def setup(bot):
|
def setup(bot):
|
||||||
bot.add_cog(Chatchart(bot))
|
bot.add_cog(Chatchart(bot))
|
||||||
|
|||||||
@@ -5,7 +5,6 @@
|
|||||||
# Thanks to violetnyte for suggesting this cog.
|
# Thanks to violetnyte for suggesting this cog.
|
||||||
import discord
|
import discord
|
||||||
import heapq
|
import heapq
|
||||||
import os
|
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
import matplotlib
|
import matplotlib
|
||||||
@@ -20,6 +19,10 @@ from redbot.core import commands
|
|||||||
class Chatchart(commands.Cog):
|
class Chatchart(commands.Cog):
|
||||||
"""Show activity."""
|
"""Show activity."""
|
||||||
|
|
||||||
|
async def red_delete_data_for_user(self, **kwargs):
|
||||||
|
""" Nothing to delete """
|
||||||
|
return
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
|
||||||
@@ -85,7 +88,7 @@ class Chatchart(commands.Cog):
|
|||||||
"""
|
"""
|
||||||
Generates a pie chart, representing the last 5000 messages in the specified channel.
|
Generates a pie chart, representing the last 5000 messages in the specified channel.
|
||||||
"""
|
"""
|
||||||
e = discord.Embed(description="Loading...", colour=0x00ccff)
|
e = discord.Embed(description="Loading...", colour=0x00CCFF)
|
||||||
e.set_thumbnail(url="https://i.imgur.com/vSp4xRk.gif")
|
e.set_thumbnail(url="https://i.imgur.com/vSp4xRk.gif")
|
||||||
em = await ctx.send(embed=e)
|
em = await ctx.send(embed=e)
|
||||||
|
|
||||||
@@ -119,9 +122,9 @@ class Chatchart(commands.Cog):
|
|||||||
msg_data["users"][whole_name]["msgcount"] = 1
|
msg_data["users"][whole_name]["msgcount"] = 1
|
||||||
msg_data["total count"] += 1
|
msg_data["total count"] += 1
|
||||||
|
|
||||||
if msg_data['users'] == {}:
|
if msg_data["users"] == {}:
|
||||||
await em.delete()
|
await em.delete()
|
||||||
return await ctx.message.channel.send(f'Only bots have sent messages in {channel.mention}')
|
return await ctx.message.channel.send(f"Only bots have sent messages in {channel.mention}")
|
||||||
|
|
||||||
for usr in msg_data["users"]:
|
for usr in msg_data["users"]:
|
||||||
pd = float(msg_data["users"][usr]["msgcount"]) / float(msg_data["total count"])
|
pd = float(msg_data["users"][usr]["msgcount"]) / float(msg_data["total count"])
|
||||||
@@ -129,12 +132,7 @@ class Chatchart(commands.Cog):
|
|||||||
|
|
||||||
top_ten = heapq.nlargest(
|
top_ten = heapq.nlargest(
|
||||||
20,
|
20,
|
||||||
[
|
[(x, msg_data["users"][x][y]) for x in msg_data["users"] for y in msg_data["users"][x] if y == "percent"],
|
||||||
(x, msg_data["users"][x][y])
|
|
||||||
for x in msg_data["users"]
|
|
||||||
for y in msg_data["users"][x]
|
|
||||||
if y == "percent"
|
|
||||||
],
|
|
||||||
key=lambda x: x[1],
|
key=lambda x: x[1],
|
||||||
)
|
)
|
||||||
others = 100 - sum(x[1] for x in top_ten)
|
others = 100 - sum(x[1] for x in top_ten)
|
||||||
|
|||||||
@@ -14,5 +14,6 @@
|
|||||||
"requirements": [
|
"requirements": [
|
||||||
"matplotlib"
|
"matplotlib"
|
||||||
],
|
],
|
||||||
"type": "COG"
|
"type": "COG",
|
||||||
|
"end_user_data_statement": "This cog does not persistently store data or metadata about users."
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
from .dadjokes import DadJokes
|
from .dadjokes import DadJokes
|
||||||
|
|
||||||
|
__red_end_user_data_statement__ = "This cog does not persistently store data or metadata about users."
|
||||||
|
|
||||||
|
|
||||||
def setup(bot):
|
def setup(bot):
|
||||||
bot.add_cog(DadJokes(bot))
|
bot.add_cog(DadJokes(bot))
|
||||||
|
|||||||
@@ -1,16 +1,21 @@
|
|||||||
from redbot.core import commands
|
from redbot.core import commands
|
||||||
import aiohttp
|
import aiohttp
|
||||||
|
|
||||||
|
|
||||||
class DadJokes(commands.Cog):
|
class DadJokes(commands.Cog):
|
||||||
"""Random dad jokes from icanhazdadjoke.com"""
|
"""Random dad jokes from icanhazdadjoke.com"""
|
||||||
|
|
||||||
|
async def red_delete_data_for_user(self, **kwargs):
|
||||||
|
""" Nothing to delete """
|
||||||
|
return
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
|
||||||
@commands.command()
|
@commands.command()
|
||||||
async def dadjoke(self, ctx):
|
async def dadjoke(self, ctx):
|
||||||
"""Gets a random dad joke."""
|
"""Gets a random dad joke."""
|
||||||
api = 'https://icanhazdadjoke.com/'
|
api = "https://icanhazdadjoke.com/"
|
||||||
async with aiohttp.request('GET', api, headers={'Accept': 'text/plain'}) as r:
|
async with aiohttp.request("GET", api, headers={"Accept": "text/plain"}) as r:
|
||||||
result = await r.text()
|
result = await r.text()
|
||||||
await ctx.send(f"`{result}`")
|
await ctx.send(f"`{result}`")
|
||||||
|
|||||||
@@ -6,5 +6,6 @@
|
|||||||
"install_msg": "Gets a random dad joke from icanhazdadjoke.com. Thanks for installing.",
|
"install_msg": "Gets a random dad joke from icanhazdadjoke.com. Thanks for installing.",
|
||||||
"short": "Random dad jokes",
|
"short": "Random dad jokes",
|
||||||
"tags": ["jokes", "dad", "dadjokes"],
|
"tags": ["jokes", "dad", "dadjokes"],
|
||||||
"type": "COG"
|
"type": "COG",
|
||||||
|
"end_user_data_statement": "This cog does not persistently store data or metadata about users."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
from .dictionary import Dictionary
|
from .dictionary import Dictionary
|
||||||
|
|
||||||
|
__red_end_user_data_statement__ = "This cog does not persistently store data or metadata about users."
|
||||||
|
|
||||||
|
|
||||||
def setup(bot):
|
def setup(bot):
|
||||||
bot.add_cog(Dictionary(bot))
|
bot.add_cog(Dictionary(bot))
|
||||||
|
|||||||
@@ -12,6 +12,10 @@ class Dictionary(commands.Cog):
|
|||||||
"""Word, yo
|
"""Word, yo
|
||||||
Parts of this cog are adapted from the PyDictionary library."""
|
Parts of this cog are adapted from the PyDictionary library."""
|
||||||
|
|
||||||
|
async def red_delete_data_for_user(self, **kwargs):
|
||||||
|
""" Nothing to delete """
|
||||||
|
return
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
self.session = aiohttp.ClientSession()
|
self.session = aiohttp.ClientSession()
|
||||||
|
|||||||
@@ -11,5 +11,6 @@
|
|||||||
"requirements": [
|
"requirements": [
|
||||||
"beautifulsoup4"
|
"beautifulsoup4"
|
||||||
],
|
],
|
||||||
"type": "COG"
|
"type": "COG",
|
||||||
|
"end_user_data_statement": "This cog does not persistently store data or metadata about users."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
from .dungeon import Dungeon
|
from .dungeon import Dungeon
|
||||||
|
|
||||||
|
__red_end_user_data_statement__ = (
|
||||||
|
"This cog does not persistently store end user data. " "This cog does store discord IDs as needed for operation. "
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def setup(bot):
|
def setup(bot):
|
||||||
bot.add_cog(Dungeon(bot))
|
bot.add_cog(Dungeon(bot))
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import asyncio
|
|
||||||
import datetime
|
import datetime
|
||||||
|
from typing import Literal
|
||||||
|
|
||||||
import discord
|
import discord
|
||||||
import logging
|
import logging
|
||||||
from redbot.core import Config, commands, checks, modlog
|
from redbot.core import Config, commands, checks, modlog
|
||||||
@@ -12,6 +13,20 @@ log = logging.getLogger("red.aikaterna.dungeon")
|
|||||||
class Dungeon(commands.Cog):
|
class Dungeon(commands.Cog):
|
||||||
"""Auto-quarantine suspicious users."""
|
"""Auto-quarantine suspicious users."""
|
||||||
|
|
||||||
|
async def red_delete_data_for_user(
|
||||||
|
self, *, requester: Literal["discord", "owner", "user", "user_strict"], user_id: int,
|
||||||
|
):
|
||||||
|
if requester == "discord":
|
||||||
|
# user is deleted, just comply
|
||||||
|
|
||||||
|
data = await self.config.all_guilds()
|
||||||
|
for guild_id, guild_data in data.items():
|
||||||
|
if user_id in guild_data.get("bypass", []):
|
||||||
|
bypass = guild_data.get("bypass", [])
|
||||||
|
bypass = set(bypass)
|
||||||
|
bypass.discard(user_id)
|
||||||
|
await self.config.guild_from_id(guild_id).bypass.set(list(bypass))
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
self.config = Config.get_conf(self, 2700081001, force_registration=True)
|
self.config = Config.get_conf(self, 2700081001, force_registration=True)
|
||||||
@@ -58,17 +73,13 @@ class Dungeon(commands.Cog):
|
|||||||
return await ctx.send("No dungeon role set.")
|
return await ctx.send("No dungeon role set.")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
await user.edit(
|
await user.edit(roles=[], reason=f"Removing all roles, {ctx.message.author} is banishing user")
|
||||||
roles=[], reason=f"Removing all roles, {ctx.message.author} is banishing user"
|
|
||||||
)
|
|
||||||
except discord.Forbidden:
|
except discord.Forbidden:
|
||||||
return await ctx.send(
|
return await ctx.send(
|
||||||
"I need permission to manage roles or the role hierarchy might not allow me to do this. I need a role higher than the person you're trying to banish."
|
"I need permission to manage roles or the role hierarchy might not allow me to do this. I need a role higher than the person you're trying to banish."
|
||||||
)
|
)
|
||||||
|
|
||||||
await user.add_roles(
|
await user.add_roles(dungeon_role_obj, reason=f"Adding dungeon role, {ctx.message.author} is banishing user")
|
||||||
dungeon_role_obj, reason=f"Adding dungeon role, {ctx.message.author} is banishing user"
|
|
||||||
)
|
|
||||||
|
|
||||||
if blacklist:
|
if blacklist:
|
||||||
blacklist_msg = ", blacklisted from the bot,"
|
blacklist_msg = ", blacklisted from the bot,"
|
||||||
@@ -89,9 +100,7 @@ class Dungeon(commands.Cog):
|
|||||||
"""Sets the announcement channel for users moved to the dungeon."""
|
"""Sets the announcement channel for users moved to the dungeon."""
|
||||||
await self.config.guild(ctx.guild).announce_channel.set(channel.id)
|
await self.config.guild(ctx.guild).announce_channel.set(channel.id)
|
||||||
announce_channel_id = await self.config.guild(ctx.guild).announce_channel()
|
announce_channel_id = await self.config.guild(ctx.guild).announce_channel()
|
||||||
await ctx.send(
|
await ctx.send(f"User announcement channel set to: {self.bot.get_channel(announce_channel_id).mention}.")
|
||||||
f"User announcement channel set to: {self.bot.get_channel(announce_channel_id).mention}."
|
|
||||||
)
|
|
||||||
|
|
||||||
@dungeon.command()
|
@dungeon.command()
|
||||||
async def autoban(self, ctx):
|
async def autoban(self, ctx):
|
||||||
@@ -106,9 +115,7 @@ class Dungeon(commands.Cog):
|
|||||||
auto_ban = await self.config.guild(ctx.guild).auto_ban()
|
auto_ban = await self.config.guild(ctx.guild).auto_ban()
|
||||||
if not ban_message:
|
if not ban_message:
|
||||||
await self.config.guild(ctx.guild).auto_ban_message.set(None)
|
await self.config.guild(ctx.guild).auto_ban_message.set(None)
|
||||||
return await ctx.send(
|
return await ctx.send("Auto-ban message removed. No message will be sent on an auto-ban.")
|
||||||
"Auto-ban message removed. No message will be sent on an auto-ban."
|
|
||||||
)
|
|
||||||
await self.config.guild(ctx.guild).auto_ban_message.set(str(ban_message))
|
await self.config.guild(ctx.guild).auto_ban_message.set(str(ban_message))
|
||||||
await self.config.guild(ctx.guild).auto_ban.set(True)
|
await self.config.guild(ctx.guild).auto_ban.set(True)
|
||||||
await ctx.send(f"Auto-ban has been turned on.\nMessage to send on ban:\n{ban_message}")
|
await ctx.send(f"Auto-ban has been turned on.\nMessage to send on ban:\n{ban_message}")
|
||||||
@@ -254,13 +261,10 @@ class Dungeon(commands.Cog):
|
|||||||
role_check = True
|
role_check = True
|
||||||
try:
|
try:
|
||||||
await user.remove_roles(
|
await user.remove_roles(
|
||||||
dungeon_role_obj,
|
dungeon_role_obj, reason=f"Removing dungeon role, verified by {ctx.message.author}.",
|
||||||
reason=f"Removing dungeon role, verified by {ctx.message.author}.",
|
|
||||||
)
|
)
|
||||||
if not user_role_obj:
|
if not user_role_obj:
|
||||||
return await ctx.send(
|
return await ctx.send("Dungeon role removed, but no member role is set so I can't award one.")
|
||||||
"Dungeon role removed, but no member role is set so I can't award one."
|
|
||||||
)
|
|
||||||
await user.add_roles(user_role_obj, reason="Adding member role.")
|
await user.add_roles(user_role_obj, reason="Adding member role.")
|
||||||
except discord.Forbidden:
|
except discord.Forbidden:
|
||||||
return await ctx.send(
|
return await ctx.send(
|
||||||
@@ -281,9 +285,7 @@ class Dungeon(commands.Cog):
|
|||||||
try:
|
try:
|
||||||
await user.send(dm_message)
|
await user.send(dm_message)
|
||||||
except discord.Forbidden:
|
except discord.Forbidden:
|
||||||
await ctx.send(
|
await ctx.send(f"I couldn't DM {user} to let them know they've been verified, they've blocked me.")
|
||||||
f"I couldn't DM {user} to let them know they've been verified, they've blocked me."
|
|
||||||
)
|
|
||||||
|
|
||||||
@dungeon.command()
|
@dungeon.command()
|
||||||
async def autosetup(self, ctx):
|
async def autosetup(self, ctx):
|
||||||
@@ -291,11 +293,7 @@ class Dungeon(commands.Cog):
|
|||||||
You must deny the default role (@ everyone) from viewing or typing in other channels in your server manually.
|
You must deny the default role (@ everyone) from viewing or typing in other channels in your server manually.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
overwrites = {
|
overwrites = {ctx.guild.default_role: discord.PermissionOverwrite(send_messages=False, read_messages=False)}
|
||||||
ctx.guild.default_role: discord.PermissionOverwrite(
|
|
||||||
send_messages=False, read_messages=False
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
dungeon_role = await ctx.guild.create_role(name="Dungeon")
|
dungeon_role = await ctx.guild.create_role(name="Dungeon")
|
||||||
|
|
||||||
@@ -304,9 +302,7 @@ class Dungeon(commands.Cog):
|
|||||||
dungeon_role, read_messages=True, send_messages=False, read_message_history=True
|
dungeon_role, read_messages=True, send_messages=False, read_message_history=True
|
||||||
)
|
)
|
||||||
|
|
||||||
dungeon_channel = await ctx.guild.create_text_channel(
|
dungeon_channel = await ctx.guild.create_text_channel("Silenced", category=dungeon_category)
|
||||||
"Silenced", category=dungeon_category
|
|
||||||
)
|
|
||||||
await dungeon_channel.set_permissions(
|
await dungeon_channel.set_permissions(
|
||||||
dungeon_role, read_messages=True, send_messages=False, read_message_history=True
|
dungeon_role, read_messages=True, send_messages=False, read_message_history=True
|
||||||
)
|
)
|
||||||
@@ -409,8 +405,7 @@ class Dungeon(commands.Cog):
|
|||||||
user_role_obj = discord.utils.get(member.guild.roles, id=user_role_id)
|
user_role_obj = discord.utils.get(member.guild.roles, id=user_role_id)
|
||||||
try:
|
try:
|
||||||
await member.add_roles(
|
await member.add_roles(
|
||||||
user_role_obj,
|
user_role_obj, reason="User has bypassed Dungeon checks. Assigning member role.",
|
||||||
reason="User has bypassed Dungeon checks. Assigning member role.",
|
|
||||||
)
|
)
|
||||||
except discord.Forbidden:
|
except discord.Forbidden:
|
||||||
pass
|
pass
|
||||||
@@ -444,9 +439,7 @@ class Dungeon(commands.Cog):
|
|||||||
log.debug(perm_msg)
|
log.debug(perm_msg)
|
||||||
return
|
return
|
||||||
try:
|
try:
|
||||||
await member.guild.ban(
|
await member.guild.ban(member, reason="Dungeon auto-ban", delete_message_days=0)
|
||||||
member, reason="Dungeon auto-ban", delete_message_days=0
|
|
||||||
)
|
|
||||||
except discord.Forbidden:
|
except discord.Forbidden:
|
||||||
if announce_channel:
|
if announce_channel:
|
||||||
return await channel_object.send(
|
return await channel_object.send(
|
||||||
@@ -466,14 +459,7 @@ class Dungeon(commands.Cog):
|
|||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
await modlog.create_case(
|
await modlog.create_case(
|
||||||
self.bot,
|
self.bot, member.guild, now, "ban", member, member.guild.me, until=None, channel=None,
|
||||||
member.guild,
|
|
||||||
now,
|
|
||||||
"ban",
|
|
||||||
member,
|
|
||||||
member.guild.me,
|
|
||||||
until=None,
|
|
||||||
channel=None,
|
|
||||||
)
|
)
|
||||||
except RuntimeError:
|
except RuntimeError:
|
||||||
log.error(
|
log.error(
|
||||||
|
|||||||
@@ -15,5 +15,6 @@
|
|||||||
"dungeon",
|
"dungeon",
|
||||||
"autoban"
|
"autoban"
|
||||||
],
|
],
|
||||||
"type": "COG"
|
"type": "COG",
|
||||||
|
"end_user_data_statement": "This cog does not persistently store end user data. This cog does store discord IDs as needed for operation. "
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,14 @@
|
|||||||
from .hunting import Hunting
|
from .hunting import Hunting
|
||||||
|
|
||||||
|
__red_end_user_data_statement__ = (
|
||||||
|
"This cog does not persistently store end user data. "
|
||||||
|
"This cog does store discord IDs as needed for operation. "
|
||||||
|
"This cog does store user stats for the cog such as their score. "
|
||||||
|
"Users may remove their own content without making a data removal request."
|
||||||
|
"This cog does not support data requests, "
|
||||||
|
"but will respect deletion requests."
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
async def setup(bot):
|
async def setup(bot):
|
||||||
bot.add_cog(Hunting(bot))
|
bot.add_cog(Hunting(bot))
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
|
from typing import Literal
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
import discord
|
import discord
|
||||||
import datetime
|
import datetime
|
||||||
import itertools
|
|
||||||
import math
|
import math
|
||||||
import random
|
import random
|
||||||
import time
|
import time
|
||||||
@@ -11,12 +12,17 @@ from redbot.core.utils.chat_formatting import bold, box, humanize_list, humanize
|
|||||||
from redbot.core.utils.menus import menu, DEFAULT_CONTROLS
|
from redbot.core.utils.menus import menu, DEFAULT_CONTROLS
|
||||||
|
|
||||||
|
|
||||||
__version__ = "3.1.3"
|
__version__ = "3.1.4"
|
||||||
|
|
||||||
|
|
||||||
class Hunting(commands.Cog):
|
class Hunting(commands.Cog):
|
||||||
"""Hunting, it hunts birds and things that fly."""
|
"""Hunting, it hunts birds and things that fly."""
|
||||||
|
|
||||||
|
async def red_delete_data_for_user(
|
||||||
|
self, *, requester: Literal["discord", "owner", "user", "user_strict"], user_id: int,
|
||||||
|
):
|
||||||
|
await self.config.user_from_id(user_id).clear()
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
self.config = Config.get_conf(self, 2784481002, force_registration=True)
|
self.config = Config.get_conf(self, 2784481002, force_registration=True)
|
||||||
@@ -92,9 +98,7 @@ class Hunting(commands.Cog):
|
|||||||
header = "{score:{score_len}}{name:2}\n".format(
|
header = "{score:{score_len}}{name:2}\n".format(
|
||||||
score="# Birds Shot",
|
score="# Birds Shot",
|
||||||
score_len=score_len + 5,
|
score_len=score_len + 5,
|
||||||
name="Name"
|
name="Name" if not str(ctx.author.mobile_status) in ["online", "idle", "dnd"] else "Name",
|
||||||
if not str(ctx.author.mobile_status) in ["online", "idle", "dnd"]
|
|
||||||
else "Name",
|
|
||||||
)
|
)
|
||||||
temp_msg = header
|
temp_msg = header
|
||||||
for account in sorted_acc:
|
for account in sorted_acc:
|
||||||
@@ -124,9 +128,7 @@ class Hunting(commands.Cog):
|
|||||||
colour=await ctx.bot.get_embed_color(location=ctx.channel),
|
colour=await ctx.bot.get_embed_color(location=ctx.channel),
|
||||||
description=box(title, lang="prolog") + (box(page, lang="md")),
|
description=box(title, lang="prolog") + (box(page, lang="md")),
|
||||||
)
|
)
|
||||||
embed.set_footer(
|
embed.set_footer(text=f"Page {humanize_number(pages)}/{humanize_number(math.ceil(len(temp_msg) / 800))}")
|
||||||
text=f"Page {humanize_number(pages)}/{humanize_number(math.ceil(len(temp_msg) / 800))}"
|
|
||||||
)
|
|
||||||
pages += 1
|
pages += 1
|
||||||
page_list.append(embed)
|
page_list.append(embed)
|
||||||
if len(page_list) == 1:
|
if len(page_list) == 1:
|
||||||
@@ -252,7 +254,9 @@ class Hunting(commands.Cog):
|
|||||||
await self.config.guild(ctx.guild).hunt_interval_minimum.set(interval_min)
|
await self.config.guild(ctx.guild).hunt_interval_minimum.set(interval_min)
|
||||||
await self.config.guild(ctx.guild).hunt_interval_maximum.set(interval_max)
|
await self.config.guild(ctx.guild).hunt_interval_maximum.set(interval_max)
|
||||||
await self.config.guild(ctx.guild).wait_for_bang_timeout.set(bang_timeout)
|
await self.config.guild(ctx.guild).wait_for_bang_timeout.set(bang_timeout)
|
||||||
message += f"Timing has been set:\nMin time {interval_min}s\nMax time {interval_max}s\nBang timeout {bang_timeout}s"
|
message += (
|
||||||
|
f"Timing has been set:\nMin time {interval_min}s\nMax time {interval_max}s\nBang timeout {bang_timeout}s"
|
||||||
|
)
|
||||||
await ctx.send(bold(message))
|
await ctx.send(bold(message))
|
||||||
|
|
||||||
@hunting.command()
|
@hunting.command()
|
||||||
@@ -280,9 +284,7 @@ class Hunting(commands.Cog):
|
|||||||
if channel.id not in self.paused_games:
|
if channel.id not in self.paused_games:
|
||||||
self.paused_games.append(channel.id)
|
self.paused_games.append(channel.id)
|
||||||
await channel.send(
|
await channel.send(
|
||||||
bold(
|
bold("It seems there are no hunters here. The hunt will be resumed when someone treads here again.")
|
||||||
"It seems there are no hunters here. The hunt will be resumed when someone treads here again."
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@@ -306,9 +308,7 @@ class Hunting(commands.Cog):
|
|||||||
return False
|
return False
|
||||||
if channel != message.channel:
|
if channel != message.channel:
|
||||||
return False
|
return False
|
||||||
return (
|
return message.content.lower().split(" ")[0] == "bang" if message.content else False
|
||||||
message.content.lower().split(" ")[0] == "bang" if message.content else False
|
|
||||||
)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
bang_msg = await self.bot.wait_for("message", check=check, timeout=timeout)
|
bang_msg = await self.bot.wait_for("message", check=check, timeout=timeout)
|
||||||
@@ -346,9 +346,7 @@ class Hunting(commands.Cog):
|
|||||||
|
|
||||||
bang_now = time.time()
|
bang_now = time.time()
|
||||||
time_for_bang = "{:.3f}".format(bang_now - now)
|
time_for_bang = "{:.3f}".format(bang_now - now)
|
||||||
bangtime = (
|
bangtime = "" if not await self.config.guild(guild).bang_time() else f" in {time_for_bang}s"
|
||||||
"" if not await self.config.guild(guild).bang_time() else f" in {time_for_bang}s"
|
|
||||||
)
|
|
||||||
|
|
||||||
if random.randrange(0, 17) > 1:
|
if random.randrange(0, 17) > 1:
|
||||||
await self._add_score(guild, author, animal)
|
await self._add_score(guild, author, animal)
|
||||||
@@ -379,9 +377,7 @@ class Hunting(commands.Cog):
|
|||||||
self.in_game.append(message.channel.id)
|
self.in_game.append(message.channel.id)
|
||||||
|
|
||||||
guild_data = await self.config.guild(message.guild).all()
|
guild_data = await self.config.guild(message.guild).all()
|
||||||
wait_time = random.randrange(
|
wait_time = random.randrange(guild_data["hunt_interval_minimum"], guild_data["hunt_interval_maximum"])
|
||||||
guild_data["hunt_interval_minimum"], guild_data["hunt_interval_maximum"]
|
|
||||||
)
|
|
||||||
self.next_bang[message.guild.id] = datetime.datetime.fromtimestamp(
|
self.next_bang[message.guild.id] = datetime.datetime.fromtimestamp(
|
||||||
int(time.mktime(datetime.datetime.utcnow().timetuple())) + wait_time
|
int(time.mktime(datetime.datetime.utcnow().timetuple())) + wait_time
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -4,5 +4,6 @@
|
|||||||
"install_msg": "Check out [p]hunting to get started.",
|
"install_msg": "Check out [p]hunting to get started.",
|
||||||
"short": "A bird hunting game.",
|
"short": "A bird hunting game.",
|
||||||
"tags": ["hunting", "hunt", "game"],
|
"tags": ["hunting", "hunt", "game"],
|
||||||
"type": "COG"
|
"type": "COG",
|
||||||
|
"end_user_data_statement": "This cog does not persistently store end user data. This cog does store discord IDs as needed for operation. This cog does store user stats for the cog such as their score. Users may remove their own content without making a data removal request. This cog does not support data requests, but will respect deletion requests."
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
from .icyparser import IcyParser
|
from .icyparser import IcyParser
|
||||||
|
|
||||||
|
__red_end_user_data_statement__ = "This cog does not persistently store data or metadata about users."
|
||||||
|
|
||||||
|
|
||||||
def setup(bot):
|
def setup(bot):
|
||||||
bot.add_cog(IcyParser(bot))
|
bot.add_cog(IcyParser(bot))
|
||||||
|
|||||||
@@ -7,6 +7,10 @@ from redbot.core import commands
|
|||||||
|
|
||||||
|
|
||||||
class IcyParser(commands.Cog):
|
class IcyParser(commands.Cog):
|
||||||
|
async def red_delete_data_for_user(self, **kwargs):
|
||||||
|
""" Nothing to delete """
|
||||||
|
return
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
self.session = aiohttp.ClientSession()
|
self.session = aiohttp.ClientSession()
|
||||||
@@ -69,9 +73,7 @@ class IcyParser(commands.Cog):
|
|||||||
f"Can't read the stream information for <{player.current.uri if not url else url}>, it may not be an Icecast or Shoutcast radio station or there may be no stream information available."
|
f"Can't read the stream information for <{player.current.uri if not url else url}>, it may not be an Icecast or Shoutcast radio station or there may be no stream information available."
|
||||||
)
|
)
|
||||||
song = f"**[{icy[0]}]({player.current.uri if not url else url})**\n"
|
song = f"**[{icy[0]}]({player.current.uri if not url else url})**\n"
|
||||||
embed = discord.Embed(
|
embed = discord.Embed(colour=await ctx.embed_colour(), title="Now Playing", description=song)
|
||||||
colour=await ctx.embed_colour(), title="Now Playing", description=song
|
|
||||||
)
|
|
||||||
if icy[2]:
|
if icy[2]:
|
||||||
embed.set_thumbnail(url=icy[1])
|
embed.set_thumbnail(url=icy[1])
|
||||||
await ctx.send(embed=embed)
|
await ctx.send(embed=embed)
|
||||||
|
|||||||
@@ -10,5 +10,6 @@
|
|||||||
"icecast",
|
"icecast",
|
||||||
"shoutcast"
|
"shoutcast"
|
||||||
],
|
],
|
||||||
"type": "COG"
|
"type": "COG",
|
||||||
|
"end_user_data_statement": "This cog does not persistently store data or metadata about users."
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
from .inspirobot import Inspirobot
|
from .inspirobot import Inspirobot
|
||||||
|
|
||||||
|
__red_end_user_data_statement__ = "This cog does not persistently store data or metadata about users."
|
||||||
|
|
||||||
|
|
||||||
def setup(bot):
|
def setup(bot):
|
||||||
bot.add_cog(Inspirobot(bot))
|
bot.add_cog(Inspirobot(bot))
|
||||||
|
|||||||
@@ -12,5 +12,6 @@
|
|||||||
"inspire",
|
"inspire",
|
||||||
"inspirobot"
|
"inspirobot"
|
||||||
],
|
],
|
||||||
"type": "COG"
|
"type": "COG",
|
||||||
|
"end_user_data_statement": "This cog does not persistently store data or metadata about users."
|
||||||
}
|
}
|
||||||
@@ -5,6 +5,11 @@ from redbot.core import commands
|
|||||||
|
|
||||||
class Inspirobot(commands.Cog):
|
class Inspirobot(commands.Cog):
|
||||||
"""Posts images generated by https://inspirobot.me"""
|
"""Posts images generated by https://inspirobot.me"""
|
||||||
|
|
||||||
|
async def red_delete_data_for_user(self, **kwargs):
|
||||||
|
""" Nothing to delete """
|
||||||
|
return
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
self.session = aiohttp.ClientSession()
|
self.session = aiohttp.ClientSession()
|
||||||
@@ -13,9 +18,7 @@ class Inspirobot(commands.Cog):
|
|||||||
async def inspireme(self, ctx):
|
async def inspireme(self, ctx):
|
||||||
"""Fetch a random "inspirational message" from the bot."""
|
"""Fetch a random "inspirational message" from the bot."""
|
||||||
try:
|
try:
|
||||||
async with self.session.request(
|
async with self.session.request("GET", "http://inspirobot.me/api?generate=true") as page:
|
||||||
"GET", "http://inspirobot.me/api?generate=true"
|
|
||||||
) as page:
|
|
||||||
pic = await page.text(encoding="utf-8")
|
pic = await page.text(encoding="utf-8")
|
||||||
em = discord.Embed()
|
em = discord.Embed()
|
||||||
em.set_image(url=pic)
|
em.set_image(url=pic)
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
from .luigipoker import LuigiPoker
|
from .luigipoker import LuigiPoker
|
||||||
|
|
||||||
|
__red_end_user_data_statement__ = "This cog does not persistently store data or metadata about users."
|
||||||
|
|
||||||
|
|
||||||
def setup(bot):
|
def setup(bot):
|
||||||
bot.add_cog(LuigiPoker(bot))
|
bot.add_cog(LuigiPoker(bot))
|
||||||
|
|||||||
@@ -4,5 +4,6 @@
|
|||||||
"install_msg": "Thanks for installing.",
|
"install_msg": "Thanks for installing.",
|
||||||
"short": "A Luigi poker minigame.",
|
"short": "A Luigi poker minigame.",
|
||||||
"tags": ["poker", "game"],
|
"tags": ["poker", "game"],
|
||||||
"type": "COG"
|
"type": "COG",
|
||||||
|
"end_user_data_statement": "This cog does not persistently store data or metadata about users."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
import logging
|
import logging
|
||||||
from random import randint
|
from random import randint
|
||||||
from redbot.core import commands, checks
|
from redbot.core import commands
|
||||||
from redbot.core.utils.chat_formatting import box
|
from redbot.core.utils.chat_formatting import box
|
||||||
from redbot.core.utils.predicates import MessagePredicate
|
from redbot.core.utils.predicates import MessagePredicate
|
||||||
|
|
||||||
@@ -83,8 +83,11 @@ class Deck:
|
|||||||
|
|
||||||
|
|
||||||
class LuigiPoker(commands.Cog):
|
class LuigiPoker(commands.Cog):
|
||||||
|
async def red_delete_data_for_user(self, **kwargs):
|
||||||
|
""" Nothing to delete """
|
||||||
|
return
|
||||||
|
|
||||||
__version__ = "0.1.1"
|
__version__ = "0.1.2"
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
@@ -165,8 +168,7 @@ class LuigiPoker(commands.Cog):
|
|||||||
return await self.fold(ctx)
|
return await self.fold(ctx)
|
||||||
else:
|
else:
|
||||||
log.error(
|
log.error(
|
||||||
"LuigiPoker: Something broke unexpectedly in _play_response. Please report it.",
|
"LuigiPoker: Something broke unexpectedly in _play_response. Please report it.", exc_info=True,
|
||||||
exc_info=True,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
async def hit(self, ctx):
|
async def hit(self, ctx):
|
||||||
@@ -176,9 +178,7 @@ class LuigiPoker(commands.Cog):
|
|||||||
"Examples: `1,3,5` or `4, 5`"
|
"Examples: `1,3,5` or `4, 5`"
|
||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
user_resp = await ctx.bot.wait_for(
|
user_resp = await ctx.bot.wait_for("message", timeout=60, check=MessagePredicate.same_context(ctx))
|
||||||
"message", timeout=60, check=MessagePredicate.same_context(ctx)
|
|
||||||
)
|
|
||||||
except asyncio.TimeoutError:
|
except asyncio.TimeoutError:
|
||||||
await ctx.send("No response.")
|
await ctx.send("No response.")
|
||||||
return await self.fold(ctx)
|
return await self.fold(ctx)
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
from .noflippedtables import NoFlippedTables
|
from .noflippedtables import NoFlippedTables
|
||||||
|
|
||||||
|
__red_end_user_data_statement__ = "This cog does not persistently store data or metadata about users."
|
||||||
|
|
||||||
|
|
||||||
def setup(bot):
|
def setup(bot):
|
||||||
bot.add_cog(NoFlippedTables(bot))
|
bot.add_cog(NoFlippedTables(bot))
|
||||||
|
|||||||
@@ -5,5 +5,6 @@
|
|||||||
"description" : "Unflip all the flipped tables.",
|
"description" : "Unflip all the flipped tables.",
|
||||||
"install_msg" : "Usage: [p]help tableset",
|
"install_msg" : "Usage: [p]help tableset",
|
||||||
"tags" : ["noflippedtables", "no flip", "tables"],
|
"tags" : ["noflippedtables", "no flip", "tables"],
|
||||||
"disabled" : false
|
"disabled" : false,
|
||||||
|
"end_user_data_statement": "This cog does not persistently store data or metadata about users."
|
||||||
}
|
}
|
||||||
@@ -8,6 +8,10 @@ from redbot.core.utils.chat_formatting import box
|
|||||||
class NoFlippedTables(commands.Cog):
|
class NoFlippedTables(commands.Cog):
|
||||||
"""For the table sympathizers"""
|
"""For the table sympathizers"""
|
||||||
|
|
||||||
|
async def red_delete_data_for_user(self, **kwargs):
|
||||||
|
""" Nothing to delete """
|
||||||
|
return
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
self.config = Config.get_conf(self, 2712290002, force_registration=True)
|
self.config = Config.get_conf(self, 2712290002, force_registration=True)
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
from .nolinks import NoLinks
|
from .nolinks import NoLinks
|
||||||
|
|
||||||
|
__red_end_user_data_statement__ = "This cog does not persistently store data or metadata about users."
|
||||||
|
|
||||||
|
|
||||||
def setup(bot):
|
def setup(bot):
|
||||||
bot.add_cog(NoLinks(bot))
|
bot.add_cog(NoLinks(bot))
|
||||||
|
|||||||
@@ -13,5 +13,6 @@
|
|||||||
"links",
|
"links",
|
||||||
"automod"
|
"automod"
|
||||||
],
|
],
|
||||||
"type": "COG"
|
"type": "COG",
|
||||||
|
"end_user_data_statement": "This cog does not persistently store data or metadata about users."
|
||||||
}
|
}
|
||||||
@@ -3,10 +3,15 @@ import re
|
|||||||
from redbot.core import Config, commands, checks
|
from redbot.core import Config, commands, checks
|
||||||
|
|
||||||
LINKS = re.compile(
|
LINKS = re.compile(
|
||||||
"(([\w]+:)?//)?(([\d\w]|%[a-fA-f\d]{2,2})+(:([\d\w]|%[a-fA-f\d]{2,2})+)?@)?([\d\w][-\d\w]{0,253}[\d\w]\.)+[\w]{2,63}(:[\d]+)?(/([-+_~.\d\w]|%[a-fA-f\d]{2,2})*)*(\?(&?([-+_~.\d\w]|%[a-fA-f\d]{2,2})=?)*)?(#([-+_~.\d\w]|%[a-fA-f\d]{2,2})*)?"
|
"(([\w]+:)?//)?(([\d\w]|%[a-fA-f\d]{2,2})+(:([\d\w]|%[a-fA-f\d]{2,2})+)?@)?([\d\w][-\d\w]{0,253}[\d\w]\.)+[\w]{2,63}(:[\d]+)?(/([-+_~.\d\w]|%[a-fA-f\d]{2,2})*)*(\?(&?([-+_~.\d\w]|%[a-fA-f\d]{2,2})=?)*)?(#([-+_~.\d\w]|%[a-fA-f\d]{2,2})*)?"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class NoLinks(commands.Cog):
|
class NoLinks(commands.Cog):
|
||||||
|
async def red_delete_data_for_user(self, **kwargs):
|
||||||
|
""" Nothing to delete """
|
||||||
|
return
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
self.config = Config.get_conf(self, 2740131001, force_registration=True)
|
self.config = Config.get_conf(self, 2740131001, force_registration=True)
|
||||||
@@ -128,12 +133,8 @@ class NoLinks(commands.Cog):
|
|||||||
sentence = message.content.split()
|
sentence = message.content.split()
|
||||||
for word in sentence:
|
for word in sentence:
|
||||||
if self._match_url(word):
|
if self._match_url(word):
|
||||||
msg = "**Message Removed in** {} ({})\n".format(
|
msg = "**Message Removed in** {} ({})\n".format(message.channel.mention, message.channel.id)
|
||||||
message.channel.mention, message.channel.id
|
msg += "**Message sent by**: {} ({})\n".format(message.author.name, message.author.id)
|
||||||
)
|
|
||||||
msg += "**Message sent by**: {} ({})\n".format(
|
|
||||||
message.author.name, message.author.id
|
|
||||||
)
|
|
||||||
msg += "**Message content**:\n{}".format(message.content)
|
msg += "**Message content**:\n{}".format(message.content)
|
||||||
if message_channel:
|
if message_channel:
|
||||||
await message_channel.send(msg)
|
await message_channel.send(msg)
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
from .otherbot import Otherbot
|
from .otherbot import Otherbot
|
||||||
|
|
||||||
|
__red_end_user_data_statement__ = (
|
||||||
|
"This cog does not persistently store end user data. " "This cog does store discord IDs as needed for operation. "
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
async def setup(bot):
|
async def setup(bot):
|
||||||
cog = Otherbot(bot)
|
cog = Otherbot(bot)
|
||||||
|
|||||||
@@ -1,9 +1,16 @@
|
|||||||
{
|
{
|
||||||
"author": ["aikaterna", "Predä 。#1001"],
|
"author": [
|
||||||
"description": "Alerts a role when bot(s) go offline.",
|
"aikaterna", "Predä 。#1001"
|
||||||
"install_msg": "Thanks for installing, have fun.",
|
],
|
||||||
"permissions": ["manage_roles"],
|
"description": "Alerts a role when bot(s) go offline.",
|
||||||
"short": "Alerts a role when bot(s) go offline.",
|
"install_msg": "Thanks for installing, have fun.",
|
||||||
"tags": ["bots"],
|
"permissions" : [
|
||||||
"type": "COG"
|
"manage_roles"
|
||||||
|
],
|
||||||
|
"short": "Alerts a role when bot(s) go offline.",
|
||||||
|
"tags": [
|
||||||
|
"bots"
|
||||||
|
],
|
||||||
|
"type": "COG",
|
||||||
|
"end_user_data_statement": "This cog does not persistently store end user data. This cog does store discord IDs as needed for operation. "
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
from typing import Literal
|
||||||
|
|
||||||
import discord
|
import discord
|
||||||
from redbot.core.bot import Red
|
from redbot.core.bot import Red
|
||||||
from redbot.core import commands, checks, Config
|
from redbot.core import commands, checks, Config
|
||||||
@@ -10,7 +12,21 @@ DEFAULT_ONLINE_EMOJI = "\N{WHITE HEAVY CHECK MARK}"
|
|||||||
|
|
||||||
class Otherbot(commands.Cog):
|
class Otherbot(commands.Cog):
|
||||||
__author__ = ["aikaterna", "Predä 。#1001"]
|
__author__ = ["aikaterna", "Predä 。#1001"]
|
||||||
__version__ = "0.9"
|
__version__ = "0.10"
|
||||||
|
|
||||||
|
async def red_delete_data_for_user(
|
||||||
|
self, *, requester: Literal["discord", "owner", "user", "user_strict"], user_id: int,
|
||||||
|
):
|
||||||
|
if requester == "discord":
|
||||||
|
# user is deleted, just comply
|
||||||
|
|
||||||
|
data = await self.config.all_guilds()
|
||||||
|
for guild_id, guild_data in data.items():
|
||||||
|
if user_id in guild_data.get("watching", []):
|
||||||
|
bypass = guild_data.get("watching", [])
|
||||||
|
bypass = set(bypass)
|
||||||
|
bypass.discard(user_id)
|
||||||
|
await self.config.guild_from_id(guild_id).bypass.set(list(bypass))
|
||||||
|
|
||||||
def __init__(self, bot: Red):
|
def __init__(self, bot: Red):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
from .partycrash import PartyCrash
|
from .partycrash import PartyCrash
|
||||||
|
|
||||||
|
__red_end_user_data_statement__ = "This cog does not persistently store data or metadata about users."
|
||||||
|
|
||||||
|
|
||||||
def setup(bot):
|
def setup(bot):
|
||||||
bot.add_cog(PartyCrash(bot))
|
bot.add_cog(PartyCrash(bot))
|
||||||
|
|||||||
@@ -11,5 +11,6 @@
|
|||||||
"tags": [
|
"tags": [
|
||||||
"invite"
|
"invite"
|
||||||
],
|
],
|
||||||
"type": "COG"
|
"type": "COG",
|
||||||
|
"end_user_data_statement": "This cog does not persistently store data or metadata about users."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,10 @@ class PartyCrash(commands.Cog):
|
|||||||
"""Partycrash inspired by v2 Admin by Will
|
"""Partycrash inspired by v2 Admin by Will
|
||||||
Does not generate invites, only lists existing invites."""
|
Does not generate invites, only lists existing invites."""
|
||||||
|
|
||||||
|
async def red_delete_data_for_user(self, **kwargs):
|
||||||
|
""" Nothing to delete """
|
||||||
|
return
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
|
||||||
@@ -75,8 +79,6 @@ class PartyCrash(commands.Cog):
|
|||||||
try:
|
try:
|
||||||
await self._get_invites(guild, ctx)
|
await self._get_invites(guild, ctx)
|
||||||
except discord.errors.Forbidden:
|
except discord.errors.Forbidden:
|
||||||
return await ctx.send(
|
return await ctx.send(f"I don't have permission to get invites for {guild.name}.")
|
||||||
f"I don't have permission to get invites for {guild.name}."
|
|
||||||
)
|
|
||||||
except asyncio.TimeoutError:
|
except asyncio.TimeoutError:
|
||||||
return await ctx.send("No server number entered, try again later.")
|
return await ctx.send("No server number entered, try again later.")
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
from .pingtime import Pingtime
|
from .pingtime import Pingtime
|
||||||
|
|
||||||
|
__red_end_user_data_statement__ = "This cog does not persistently store data or metadata about users."
|
||||||
|
|
||||||
|
|
||||||
def setup(bot):
|
def setup(bot):
|
||||||
bot.add_cog(Pingtime(bot))
|
bot.add_cog(Pingtime(bot))
|
||||||
|
|||||||
@@ -9,5 +9,6 @@
|
|||||||
"pingtime",
|
"pingtime",
|
||||||
"latency"
|
"latency"
|
||||||
],
|
],
|
||||||
"type": "COG"
|
"type": "COG",
|
||||||
|
"end_user_data_statement": "This cog does not persistently store data or metadata about users."
|
||||||
}
|
}
|
||||||
@@ -3,8 +3,14 @@ from redbot.core import commands
|
|||||||
|
|
||||||
BaseCog = getattr(commands, "Cog", object)
|
BaseCog = getattr(commands, "Cog", object)
|
||||||
|
|
||||||
|
|
||||||
class Pingtime(BaseCog):
|
class Pingtime(BaseCog):
|
||||||
"""🏓"""
|
"""🏓"""
|
||||||
|
|
||||||
|
async def red_delete_data_for_user(self, **kwargs):
|
||||||
|
""" Nothing to delete """
|
||||||
|
return
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
from .pressf import PressF
|
from .pressf import PressF
|
||||||
|
|
||||||
|
__red_end_user_data_statement__ = "This cog does not persistently store data or metadata about users."
|
||||||
|
|
||||||
|
|
||||||
def setup(bot):
|
def setup(bot):
|
||||||
bot.add_cog(PressF(bot))
|
bot.add_cog(PressF(bot))
|
||||||
|
|||||||
@@ -9,5 +9,6 @@
|
|||||||
"pressf",
|
"pressf",
|
||||||
"respects"
|
"respects"
|
||||||
],
|
],
|
||||||
"type": "COG"
|
"type": "COG",
|
||||||
|
"end_user_data_statement": "This cog does not persistently store data or metadata about users."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,10 @@ from redbot.core.utils.common_filters import filter_mass_mentions
|
|||||||
class PressF(commands.Cog):
|
class PressF(commands.Cog):
|
||||||
"""Pay some respects."""
|
"""Pay some respects."""
|
||||||
|
|
||||||
|
async def red_delete_data_for_user(self, **kwargs):
|
||||||
|
""" Nothing to delete """
|
||||||
|
return
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
self.channels = {}
|
self.channels = {}
|
||||||
@@ -41,13 +45,13 @@ class PressF(commands.Cog):
|
|||||||
f"Everyone, let's pay respects to **{filter_mass_mentions(answer)}**! Press the f reaction on the this message to pay respects."
|
f"Everyone, let's pay respects to **{filter_mass_mentions(answer)}**! Press the f reaction on the this message to pay respects."
|
||||||
)
|
)
|
||||||
await message.add_reaction("\U0001f1eb")
|
await message.add_reaction("\U0001f1eb")
|
||||||
self.channels[str(ctx.channel.id)] = {'msg_id': message.id, 'reacted': []}
|
self.channels[str(ctx.channel.id)] = {"msg_id": message.id, "reacted": []}
|
||||||
await asyncio.sleep(120)
|
await asyncio.sleep(120)
|
||||||
try:
|
try:
|
||||||
await message.delete()
|
await message.delete()
|
||||||
except (discord.errors.NotFound, discord.errors.Forbidden):
|
except (discord.errors.NotFound, discord.errors.Forbidden):
|
||||||
pass
|
pass
|
||||||
amount = len(self.channels[str(ctx.channel.id)]['reacted'])
|
amount = len(self.channels[str(ctx.channel.id)]["reacted"])
|
||||||
word = "person has" if amount == 1 else "people have"
|
word = "person has" if amount == 1 else "people have"
|
||||||
await ctx.send(f"**{amount}** {word} paid respects to **{filter_mass_mentions(answer)}**.")
|
await ctx.send(f"**{amount}** {word} paid respects to **{filter_mass_mentions(answer)}**.")
|
||||||
del self.channels[str(ctx.channel.id)]
|
del self.channels[str(ctx.channel.id)]
|
||||||
@@ -56,11 +60,11 @@ class PressF(commands.Cog):
|
|||||||
async def on_reaction_add(self, reaction, user):
|
async def on_reaction_add(self, reaction, user):
|
||||||
if str(reaction.message.channel.id) not in self.channels:
|
if str(reaction.message.channel.id) not in self.channels:
|
||||||
return
|
return
|
||||||
if self.channels[str(reaction.message.channel.id)]['msg_id'] != reaction.message.id:
|
if self.channels[str(reaction.message.channel.id)]["msg_id"] != reaction.message.id:
|
||||||
return
|
return
|
||||||
if user.id == self.bot.user.id:
|
if user.id == self.bot.user.id:
|
||||||
return
|
return
|
||||||
if user.id not in self.channels[str(reaction.message.channel.id)]['reacted']:
|
if user.id not in self.channels[str(reaction.message.channel.id)]["reacted"]:
|
||||||
if str(reaction.emoji) == "\U0001f1eb":
|
if str(reaction.emoji) == "\U0001f1eb":
|
||||||
await reaction.message.channel.send(f"**{user.name}** has paid their respects.")
|
await reaction.message.channel.send(f"**{user.name}** has paid their respects.")
|
||||||
self.channels[str(reaction.message.channel.id)]['reacted'].append(user.id)
|
self.channels[str(reaction.message.channel.id)]["reacted"].append(user.id)
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
from .pupper import Pupper
|
from .pupper import Pupper
|
||||||
|
|
||||||
|
__red_end_user_data_statement__ = "This cog does not persistently store data or metadata about users."
|
||||||
|
|
||||||
|
|
||||||
async def setup(bot):
|
async def setup(bot):
|
||||||
bot.add_cog(Pupper(bot))
|
bot.add_cog(Pupper(bot))
|
||||||
|
|||||||
@@ -8,5 +8,6 @@
|
|||||||
"tags": [
|
"tags": [
|
||||||
"pets"
|
"pets"
|
||||||
],
|
],
|
||||||
"type": "COG"
|
"type": "COG",
|
||||||
|
"end_user_data_statement": "This cog does not persistently store data or metadata about users."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,10 @@ log = logging.getLogger("red.aikaterna.pupper")
|
|||||||
|
|
||||||
|
|
||||||
class Pupper(commands.Cog):
|
class Pupper(commands.Cog):
|
||||||
|
async def red_delete_data_for_user(self, **kwargs):
|
||||||
|
""" Nothing to delete """
|
||||||
|
return
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
self.config = Config.get_conf(self, 2767241393, force_registration=True)
|
self.config = Config.get_conf(self, 2767241393, force_registration=True)
|
||||||
@@ -47,9 +51,7 @@ class Pupper(commands.Cog):
|
|||||||
|
|
||||||
space = "\N{EN SPACE}"
|
space = "\N{EN SPACE}"
|
||||||
toggle = "Active" if guild_data["toggle"] else "Inactive"
|
toggle = "Active" if guild_data["toggle"] else "Inactive"
|
||||||
delete_after = (
|
delete_after = "No deletion" if not guild_data["delete_after"] else guild_data["delete_after"]
|
||||||
"No deletion" if not guild_data["delete_after"] else guild_data["delete_after"]
|
|
||||||
)
|
|
||||||
|
|
||||||
msg = f"[Channels]: {humanize_list(channel_names)}\n"
|
msg = f"[Channels]: {humanize_list(channel_names)}\n"
|
||||||
msg += f"[Cooldown]: {guild_data['cooldown']} seconds\n"
|
msg += f"[Cooldown]: {guild_data['cooldown']} seconds\n"
|
||||||
@@ -169,9 +171,7 @@ class Pupper(commands.Cog):
|
|||||||
async def addall(self, ctx):
|
async def addall(self, ctx):
|
||||||
"""Add all valid channels for the guild that the bot can speak in."""
|
"""Add all valid channels for the guild that the bot can speak in."""
|
||||||
bot_text_channels = [
|
bot_text_channels = [
|
||||||
c
|
c for c in ctx.guild.text_channels if c.permissions_for(ctx.guild.me).send_messages is True
|
||||||
for c in ctx.guild.text_channels
|
|
||||||
if c.permissions_for(ctx.guild.me).send_messages is True
|
|
||||||
]
|
]
|
||||||
channel_list = await self.config.guild(ctx.guild).channel()
|
channel_list = await self.config.guild(ctx.guild).channel()
|
||||||
channels_appended = []
|
channels_appended = []
|
||||||
@@ -189,13 +189,9 @@ class Pupper(commands.Cog):
|
|||||||
second_msg = ""
|
second_msg = ""
|
||||||
await self.config.guild(ctx.guild).channel.set(channel_list)
|
await self.config.guild(ctx.guild).channel.set(channel_list)
|
||||||
if len(channels_appended) > 0:
|
if len(channels_appended) > 0:
|
||||||
first_msg = (
|
first_msg = f"{humanize_list(channels_appended)} added to the valid petting channels.\n"
|
||||||
f"{humanize_list(channels_appended)} added to the valid petting channels.\n"
|
|
||||||
)
|
|
||||||
if len(channels_in_list) > 0:
|
if len(channels_in_list) > 0:
|
||||||
second_msg = (
|
second_msg = f"{humanize_list(channels_in_list)}: already in the list of petting channels."
|
||||||
f"{humanize_list(channels_in_list)}: already in the list of petting channels."
|
|
||||||
)
|
|
||||||
await ctx.send(f"{first_msg}{second_msg}")
|
await ctx.send(f"{first_msg}{second_msg}")
|
||||||
|
|
||||||
@channel.command()
|
@channel.command()
|
||||||
@@ -237,15 +233,10 @@ class Pupper(commands.Cog):
|
|||||||
if self.pets[message.guild.id]:
|
if self.pets[message.guild.id]:
|
||||||
return
|
return
|
||||||
|
|
||||||
last_time = datetime.datetime.strptime(
|
last_time = datetime.datetime.strptime(str(guild_data["last_pet"]), "%Y-%m-%d %H:%M:%S.%f")
|
||||||
str(guild_data["last_pet"]), "%Y-%m-%d %H:%M:%S.%f"
|
|
||||||
)
|
|
||||||
now = datetime.datetime.now(datetime.timezone.utc)
|
now = datetime.datetime.now(datetime.timezone.utc)
|
||||||
now = now.replace(tzinfo=None)
|
now = now.replace(tzinfo=None)
|
||||||
if (
|
if int((now - last_time).total_seconds()) > await self.config.guild(message.guild).cooldown():
|
||||||
int((now - last_time).total_seconds())
|
|
||||||
> await self.config.guild(message.guild).cooldown()
|
|
||||||
):
|
|
||||||
self._pet_lock(message.guild.id, True)
|
self._pet_lock(message.guild.id, True)
|
||||||
rando_channel = random.choice(guild_data["channel"])
|
rando_channel = random.choice(guild_data["channel"])
|
||||||
await asyncio.sleep(random.randint(60, 480))
|
await asyncio.sleep(random.randint(60, 480))
|
||||||
@@ -279,9 +270,7 @@ class Pupper(commands.Cog):
|
|||||||
if not large_bank
|
if not large_bank
|
||||||
else guild_data["borf_msg"]
|
else guild_data["borf_msg"]
|
||||||
)
|
)
|
||||||
await rando_channel_obj.send(
|
await rando_channel_obj.send(content=msg, delete_after=guild_data["delete_after"])
|
||||||
content=msg, delete_after=guild_data["delete_after"]
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
pass
|
pass
|
||||||
self._pet_lock(message.guild.id, False)
|
self._pet_lock(message.guild.id, False)
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
from .quiz import Quiz
|
from .quiz import Quiz
|
||||||
|
|
||||||
|
__red_end_user_data_statement__ = "This cog does not persistently store data or metadata about users."
|
||||||
|
|
||||||
|
|
||||||
def setup(bot):
|
def setup(bot):
|
||||||
bot.add_cog(Quiz(bot))
|
bot.add_cog(Quiz(bot))
|
||||||
|
|||||||
@@ -4,5 +4,6 @@
|
|||||||
"install_msg": "Thanks for installing.",
|
"install_msg": "Thanks for installing.",
|
||||||
"short": "Play a kahoot-like trivia game.",
|
"short": "Play a kahoot-like trivia game.",
|
||||||
"tags": ["trivia", "quiz"],
|
"tags": ["trivia", "quiz"],
|
||||||
"type": "COG"
|
"type": "COG",
|
||||||
|
"end_user_data_statement": "This cog does not persistently store data or metadata about users."
|
||||||
}
|
}
|
||||||
56
quiz/quiz.py
56
quiz/quiz.py
@@ -22,6 +22,10 @@ def check_global_setting_admin():
|
|||||||
either a bot admin or has the manage_guild permission.
|
either a bot admin or has the manage_guild permission.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
async def red_delete_data_for_user(self, **kwargs):
|
||||||
|
""" Nothing to delete """
|
||||||
|
return
|
||||||
|
|
||||||
async def pred(ctx: commands.Context):
|
async def pred(ctx: commands.Context):
|
||||||
author = ctx.author
|
author = ctx.author
|
||||||
if not await bank.is_global():
|
if not await bank.is_global():
|
||||||
@@ -102,9 +106,7 @@ class Quiz(commands.Cog):
|
|||||||
elif category_name_or_id.isdigit():
|
elif category_name_or_id.isdigit():
|
||||||
# cat id specified
|
# cat id specified
|
||||||
if 9 <= int(category_name_or_id) >= 32:
|
if 9 <= int(category_name_or_id) >= 32:
|
||||||
return await ctx.send(
|
return await ctx.send(f"Invalid category number. Use `{ctx.prefix}quiz categories` to see a list.")
|
||||||
f"Invalid category number. Use `{ctx.prefix}quiz categories` to see a list."
|
|
||||||
)
|
|
||||||
category_id = category_name_or_id
|
category_id = category_name_or_id
|
||||||
category_name = await self.category_name_from_id(int(category_name_or_id))
|
category_name = await self.category_name_from_id(int(category_name_or_id))
|
||||||
else:
|
else:
|
||||||
@@ -112,9 +114,7 @@ class Quiz(commands.Cog):
|
|||||||
try:
|
try:
|
||||||
category_name = await self.category_name_match(category_name_or_id)
|
category_name = await self.category_name_match(category_name_or_id)
|
||||||
except RuntimeError:
|
except RuntimeError:
|
||||||
return await ctx.send(
|
return await ctx.send(f"Invalid category name. Use `{ctx.prefix}quiz categories` to see a list.")
|
||||||
f"Invalid category name. Use `{ctx.prefix}quiz categories` to see a list."
|
|
||||||
)
|
|
||||||
category_id = await self.category_id_from_name(category_name)
|
category_id = await self.category_id_from_name(category_name)
|
||||||
|
|
||||||
if channel.id not in self.playing_channels:
|
if channel.id not in self.playing_channels:
|
||||||
@@ -221,9 +221,7 @@ class Quiz(commands.Cog):
|
|||||||
while True:
|
while True:
|
||||||
for channelid in list(self.playing_channels):
|
for channelid in list(self.playing_channels):
|
||||||
channelinfo = self.playing_channels[channelid]
|
channelinfo = self.playing_channels[channelid]
|
||||||
since_start = (
|
since_start = (datetime.datetime.utcnow() - channelinfo["Start"]).total_seconds()
|
||||||
datetime.datetime.utcnow() - channelinfo["Start"]
|
|
||||||
).total_seconds()
|
|
||||||
|
|
||||||
if since_start > 30 and not channelinfo["Started"]:
|
if since_start > 30 and not channelinfo["Started"]:
|
||||||
channel = self.bot.get_channel(channelid)
|
channel = self.bot.get_channel(channelid)
|
||||||
@@ -318,9 +316,7 @@ class Quiz(commands.Cog):
|
|||||||
assert answerdict[correct_letter] == html.unescape(dictionary["correct_answer"])
|
assert answerdict[correct_letter] == html.unescape(dictionary["correct_answer"])
|
||||||
|
|
||||||
if await self.config.guild(channel.guild).show_answer():
|
if await self.config.guild(channel.guild).show_answer():
|
||||||
message = (
|
message = f"Correct answer:```{correct_letter.upper()}. {answerdict[correct_letter]}```"
|
||||||
f"Correct answer:```{correct_letter.upper()}. {answerdict[correct_letter]}```"
|
|
||||||
)
|
|
||||||
await channel.send(message)
|
await channel.send(message)
|
||||||
|
|
||||||
# Assign scores
|
# Assign scores
|
||||||
@@ -350,11 +346,7 @@ class Quiz(commands.Cog):
|
|||||||
"""Ends a quiz game."""
|
"""Ends a quiz game."""
|
||||||
# non-linear credit earning .0002x^{2.9} where x is score/100
|
# non-linear credit earning .0002x^{2.9} where x is score/100
|
||||||
channelinfo = self.playing_channels[channel.id]
|
channelinfo = self.playing_channels[channel.id]
|
||||||
idlist = sorted(
|
idlist = sorted(list(channelinfo["Players"]), key=(lambda idnum: channelinfo["Players"][idnum]), reverse=True,)
|
||||||
list(channelinfo["Players"]),
|
|
||||||
key=(lambda idnum: channelinfo["Players"][idnum]),
|
|
||||||
reverse=True,
|
|
||||||
)
|
|
||||||
|
|
||||||
winner = channel.guild.get_member(idlist[0])
|
winner = channel.guild.get_member(idlist[0])
|
||||||
await channel.send(f"Game over! {winner.mention} won!")
|
await channel.send(f"Game over! {winner.mention} won!")
|
||||||
@@ -400,11 +392,7 @@ class Quiz(commands.Cog):
|
|||||||
"""Returns a scoreboard string to be sent to the text channel."""
|
"""Returns a scoreboard string to be sent to the text channel."""
|
||||||
channelinfo = self.playing_channels[channel.id]
|
channelinfo = self.playing_channels[channel.id]
|
||||||
scoreboard = "\n"
|
scoreboard = "\n"
|
||||||
idlist = sorted(
|
idlist = sorted(list(channelinfo["Players"]), key=(lambda idnum: channelinfo["Players"][idnum]), reverse=True,)
|
||||||
list(channelinfo["Players"]),
|
|
||||||
key=(lambda idnum: channelinfo["Players"][idnum]),
|
|
||||||
reverse=True,
|
|
||||||
)
|
|
||||||
max_score = channelinfo["Players"][idlist[0]]
|
max_score = channelinfo["Players"][idlist[0]]
|
||||||
end_len = len(str(max_score)) + 1
|
end_len = len(str(max_score)) + 1
|
||||||
rank = 1
|
rank = 1
|
||||||
@@ -457,21 +445,15 @@ class Quiz(commands.Cog):
|
|||||||
parameters["difficulty"] = difficulty
|
parameters["difficulty"] = difficulty
|
||||||
for _ in range(3):
|
for _ in range(3):
|
||||||
parameters["token"] = await self.get_token(server)
|
parameters["token"] = await self.get_token(server)
|
||||||
async with self.session.get(
|
async with self.session.get("https://opentdb.com/api.php", params=parameters) as response:
|
||||||
"https://opentdb.com/api.php", params=parameters
|
|
||||||
) as response:
|
|
||||||
response_json = await response.json()
|
response_json = await response.json()
|
||||||
response_code = response_json["response_code"]
|
response_code = response_json["response_code"]
|
||||||
if response_code == 0:
|
if response_code == 0:
|
||||||
return response_json
|
return response_json
|
||||||
elif response_code == 1:
|
elif response_code == 1:
|
||||||
raise RuntimeError(
|
raise RuntimeError("Question retrieval unsuccessful. Response code from OTDB: 1")
|
||||||
"Question retrieval unsuccessful. Response code from OTDB: 1"
|
|
||||||
)
|
|
||||||
elif response_code == 2:
|
elif response_code == 2:
|
||||||
raise RuntimeError(
|
raise RuntimeError("Question retrieval unsuccessful. Response code from OTDB: 2")
|
||||||
"Question retrieval unsuccessful. Response code from OTDB: 2"
|
|
||||||
)
|
|
||||||
elif response_code == 3:
|
elif response_code == 3:
|
||||||
# Token expired. Obtain new one.
|
# Token expired. Obtain new one.
|
||||||
log.debug("Quiz: Response code from OTDB: 3")
|
log.debug("Quiz: Response code from OTDB: 3")
|
||||||
@@ -487,9 +469,7 @@ class Quiz(commands.Cog):
|
|||||||
and saves one if one doesn't exist."""
|
and saves one if one doesn't exist."""
|
||||||
token = await self.config.guild(server).token()
|
token = await self.config.guild(server).token()
|
||||||
if not token:
|
if not token:
|
||||||
async with self.session.get(
|
async with self.session.get("https://opentdb.com/api_token.php", params={"command": "request"}) as response:
|
||||||
"https://opentdb.com/api_token.php", params={"command": "request"}
|
|
||||||
) as response:
|
|
||||||
response_json = await response.json()
|
response_json = await response.json()
|
||||||
token = response_json["token"]
|
token = response_json["token"]
|
||||||
await self.config.guild(server).token.set(token)
|
await self.config.guild(server).token.set(token)
|
||||||
@@ -503,17 +483,13 @@ class Quiz(commands.Cog):
|
|||||||
) as response:
|
) as response:
|
||||||
response_code = (await response.json())["response_code"]
|
response_code = (await response.json())["response_code"]
|
||||||
if response_code != 0:
|
if response_code != 0:
|
||||||
raise RuntimeError(
|
raise RuntimeError(f"Token reset was unsuccessful. Response code from OTDB: {response_code}")
|
||||||
f"Token reset was unsuccessful. Response code from OTDB: {response_code}"
|
|
||||||
)
|
|
||||||
|
|
||||||
async def category_selector(self):
|
async def category_selector(self):
|
||||||
"""Chooses a random category that has enough questions."""
|
"""Chooses a random category that has enough questions."""
|
||||||
for _ in range(10):
|
for _ in range(10):
|
||||||
category = random.randint(9, 32)
|
category = random.randint(9, 32)
|
||||||
async with self.session.get(
|
async with self.session.get("https://opentdb.com/api_count.php", params={"category": category}) as response:
|
||||||
"https://opentdb.com/api_count.php", params={"category": category}
|
|
||||||
) as response:
|
|
||||||
response_json = await response.json()
|
response_json = await response.json()
|
||||||
assert response_json["category_id"] == category
|
assert response_json["category_id"] == category
|
||||||
if response_json["category_question_count"]["total_question_count"] > 39:
|
if response_json["category_question_count"]["total_question_count"] > 39:
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
from .region import Region
|
from .region import Region
|
||||||
|
|
||||||
|
__red_end_user_data_statement__ = "This cog does not persistently store data or metadata about users."
|
||||||
|
|
||||||
|
|
||||||
def setup(bot):
|
def setup(bot):
|
||||||
bot.add_cog(Region())
|
bot.add_cog(Region())
|
||||||
|
|||||||
@@ -5,5 +5,6 @@
|
|||||||
"description" : "Change the Discord server's region with a command.",
|
"description" : "Change the Discord server's region with a command.",
|
||||||
"install_msg" : "Thanks for installing.",
|
"install_msg" : "Thanks for installing.",
|
||||||
"tags" : ["voice region", "region"],
|
"tags" : ["voice region", "region"],
|
||||||
"disabled" : false
|
"disabled" : false,
|
||||||
|
"end_user_data_statement": "This cog does not persistently store data or metadata about users."
|
||||||
}
|
}
|
||||||
@@ -6,6 +6,10 @@ from redbot.core.utils.chat_formatting import humanize_list
|
|||||||
class Region(commands.Cog):
|
class Region(commands.Cog):
|
||||||
"""Change the guild voice region."""
|
"""Change the guild voice region."""
|
||||||
|
|
||||||
|
async def red_delete_data_for_user(self, **kwargs):
|
||||||
|
""" Nothing to delete """
|
||||||
|
return
|
||||||
|
|
||||||
@checks.mod_or_permissions(administrator=True)
|
@checks.mod_or_permissions(administrator=True)
|
||||||
@commands.cooldown(1, 60, discord.ext.commands.BucketType.guild)
|
@commands.cooldown(1, 60, discord.ext.commands.BucketType.guild)
|
||||||
@commands.command()
|
@commands.command()
|
||||||
@@ -44,6 +48,4 @@ class Region(commands.Cog):
|
|||||||
return await ctx.send("I don't have permissions to edit this guild's settings.")
|
return await ctx.send("I don't have permissions to edit this guild's settings.")
|
||||||
except discord.errors.HTTPException:
|
except discord.errors.HTTPException:
|
||||||
return await ctx.send(f"Error: An invalid server region was passed: `{region}`")
|
return await ctx.send(f"Error: An invalid server region was passed: `{region}`")
|
||||||
await ctx.send(
|
await ctx.send(f"The voice server region for `{ctx.guild.name}` has been changed to `{region}`.")
|
||||||
f"The voice server region for `{ctx.guild.name}` has been changed to `{region}`."
|
|
||||||
)
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
from .retrosign import Retrosign
|
from .retrosign import Retrosign
|
||||||
|
|
||||||
|
__red_end_user_data_statement__ = "This cog does not persistently store data or metadata about users."
|
||||||
|
|
||||||
|
|
||||||
def setup(bot):
|
def setup(bot):
|
||||||
bot.add_cog(Retrosign(bot))
|
bot.add_cog(Retrosign(bot))
|
||||||
|
|||||||
@@ -15,5 +15,6 @@
|
|||||||
"retro",
|
"retro",
|
||||||
"80s"
|
"80s"
|
||||||
],
|
],
|
||||||
"type": "COG"
|
"type": "COG",
|
||||||
|
"end_user_data_statement": "This cog does not persistently store data or metadata about users."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ from bs4 import BeautifulSoup as bs
|
|||||||
import discord
|
import discord
|
||||||
from redbot.core import commands
|
from redbot.core import commands
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
import os
|
|
||||||
from random import choice
|
from random import choice
|
||||||
import re
|
import re
|
||||||
import unicodedata
|
import unicodedata
|
||||||
@@ -14,6 +13,11 @@ import unicodedata
|
|||||||
|
|
||||||
class Retrosign(commands.Cog):
|
class Retrosign(commands.Cog):
|
||||||
"""Make an 80s retro sign. Originally by Anismash"""
|
"""Make an 80s retro sign. Originally by Anismash"""
|
||||||
|
|
||||||
|
async def red_delete_data_for_user(self, **kwargs):
|
||||||
|
""" Nothing to delete """
|
||||||
|
return
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
self.session = aiohttp.ClientSession()
|
self.session = aiohttp.ClientSession()
|
||||||
@@ -26,47 +30,27 @@ class Retrosign(commands.Cog):
|
|||||||
if len(texts) == 1:
|
if len(texts) == 1:
|
||||||
lenstr = len(texts[0])
|
lenstr = len(texts[0])
|
||||||
if lenstr <= 15:
|
if lenstr <= 15:
|
||||||
data = dict(
|
data = dict(bcg=choice([1, 2, 3, 4, 5]), txt=choice([1, 2, 3, 4]), text1="", text2=texts[0], text3="",)
|
||||||
bcg=choice([1, 2, 3, 4, 5]),
|
|
||||||
txt=choice([1, 2, 3, 4]),
|
|
||||||
text1="",
|
|
||||||
text2=texts[0],
|
|
||||||
text3="",
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
return await ctx.send("\N{CROSS MARK} Your line is too long (14 character limit)")
|
return await ctx.send("\N{CROSS MARK} Your line is too long (14 character limit)")
|
||||||
elif len(texts) == 3:
|
elif len(texts) == 3:
|
||||||
texts[0] = unicodedata.normalize('NFD', texts[0]).encode('ascii', 'ignore')
|
texts[0] = unicodedata.normalize("NFD", texts[0]).encode("ascii", "ignore")
|
||||||
texts[0] = texts[0].decode('UTF-8')
|
texts[0] = texts[0].decode("UTF-8")
|
||||||
texts[0] = re.sub(r'[^A-Za-z0-9 ]', '', texts[0])
|
texts[0] = re.sub(r"[^A-Za-z0-9 ]", "", texts[0])
|
||||||
if len(texts[0]) >= 15:
|
if len(texts[0]) >= 15:
|
||||||
return await ctx.send(
|
return await ctx.send("\N{CROSS MARK} Your first line is too long (14 character limit)")
|
||||||
"\N{CROSS MARK} Your first line is too long (14 character limit)"
|
|
||||||
)
|
|
||||||
if len(texts[1]) >= 13:
|
if len(texts[1]) >= 13:
|
||||||
return await ctx.send(
|
return await ctx.send("\N{CROSS MARK} Your second line is too long (12 character limit)")
|
||||||
"\N{CROSS MARK} Your second line is too long (12 character limit)"
|
|
||||||
)
|
|
||||||
if len(texts[2]) >= 26:
|
if len(texts[2]) >= 26:
|
||||||
return await ctx.send(
|
return await ctx.send("\N{CROSS MARK} Your third line is too long (25 character limit)")
|
||||||
"\N{CROSS MARK} Your third line is too long (25 character limit)"
|
|
||||||
)
|
|
||||||
data = dict(
|
data = dict(
|
||||||
bcg=choice([1, 2, 3, 4, 5]),
|
bcg=choice([1, 2, 3, 4, 5]), txt=choice([1, 2, 3, 4]), text1=texts[0], text2=texts[1], text3=texts[2],
|
||||||
txt=choice([1, 2, 3, 4]),
|
|
||||||
text1=texts[0],
|
|
||||||
text2=texts[1],
|
|
||||||
text3=texts[2],
|
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
return await ctx.send(
|
return await ctx.send("\N{CROSS MARK} please provide three words seperated by ';' or one word")
|
||||||
"\N{CROSS MARK} please provide three words seperated by ';' or one word"
|
|
||||||
)
|
|
||||||
|
|
||||||
async with ctx.channel.typing():
|
async with ctx.channel.typing():
|
||||||
async with self.session.post(
|
async with self.session.post("https://photofunia.com/effects/retro-wave", data=data) as response:
|
||||||
"https://photofunia.com/effects/retro-wave", data=data
|
|
||||||
) as response:
|
|
||||||
if response.status == 200:
|
if response.status == 200:
|
||||||
soup = bs(await response.text(), "html.parser")
|
soup = bs(await response.text(), "html.parser")
|
||||||
download_url = soup.find("div", class_="downloads-container").ul.li.a["href"]
|
download_url = soup.find("div", class_="downloads-container").ul.li.a["href"]
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
from .rndstatus import RndStatus
|
from .rndstatus import RndStatus
|
||||||
|
|
||||||
|
__red_end_user_data_statement__ = "This cog does not persistently store data or metadata about users."
|
||||||
|
|
||||||
|
|
||||||
def setup(bot):
|
def setup(bot):
|
||||||
bot.add_cog(RndStatus(bot))
|
bot.add_cog(RndStatus(bot))
|
||||||
|
|||||||
@@ -9,5 +9,6 @@
|
|||||||
"tags": [
|
"tags": [
|
||||||
"status"
|
"status"
|
||||||
],
|
],
|
||||||
"type": "COG"
|
"type": "COG",
|
||||||
|
"end_user_data_statement": "This cog does not persistently store data or metadata about users."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,8 +3,7 @@ import discord
|
|||||||
from redbot.core import Config, commands, checks
|
from redbot.core import Config, commands, checks
|
||||||
from redbot.core.utils import AsyncIter
|
from redbot.core.utils import AsyncIter
|
||||||
from random import choice as rndchoice
|
from random import choice as rndchoice
|
||||||
from collections import defaultdict, Counter, Sequence
|
from collections import defaultdict
|
||||||
import time
|
|
||||||
import contextlib
|
import contextlib
|
||||||
import asyncio
|
import asyncio
|
||||||
import logging
|
import logging
|
||||||
@@ -18,6 +17,10 @@ class RndStatus(commands.Cog):
|
|||||||
If a custom status is already set, it won't change it until
|
If a custom status is already set, it won't change it until
|
||||||
it's back to none. [p]set game"""
|
it's back to none. [p]set game"""
|
||||||
|
|
||||||
|
async def red_delete_data_for_user(self, **kwargs):
|
||||||
|
""" Nothing to delete """
|
||||||
|
return
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
self.last_change = None
|
self.last_change = None
|
||||||
@@ -80,9 +83,7 @@ class RndStatus(commands.Cog):
|
|||||||
if statuses == () or "" in statuses:
|
if statuses == () or "" in statuses:
|
||||||
return await ctx.send("Current statuses: " + " | ".join(saved_status))
|
return await ctx.send("Current statuses: " + " | ".join(saved_status))
|
||||||
await self.config.statuses.set(list(statuses))
|
await self.config.statuses.set(list(statuses))
|
||||||
await ctx.send(
|
await ctx.send("Done. Redo this command with no parameters to see the current list of statuses.")
|
||||||
"Done. Redo this command with no parameters to see the current list of statuses."
|
|
||||||
)
|
|
||||||
|
|
||||||
@rndstatus.command(name="streamer")
|
@rndstatus.command(name="streamer")
|
||||||
async def _streamer(self, ctx: commands.Context, *, streamer=None):
|
async def _streamer(self, ctx: commands.Context, *, streamer=None):
|
||||||
@@ -91,11 +92,9 @@ class RndStatus(commands.Cog):
|
|||||||
|
|
||||||
saved_streamer = await self.config.streamer()
|
saved_streamer = await self.config.streamer()
|
||||||
if streamer is None:
|
if streamer is None:
|
||||||
return await ctx.send(f"Current Streamer: {saved_streamer}" )
|
return await ctx.send(f"Current Streamer: {saved_streamer}")
|
||||||
await self.config.streamer.set(streamer)
|
await self.config.streamer.set(streamer)
|
||||||
await ctx.send(
|
await ctx.send("Done. Redo this command with no parameters to see the current streamer.")
|
||||||
"Done. Redo this command with no parameters to see the current streamer."
|
|
||||||
)
|
|
||||||
|
|
||||||
@rndstatus.command()
|
@rndstatus.command()
|
||||||
async def botstats(self, ctx, *statuses: str):
|
async def botstats(self, ctx, *statuses: str):
|
||||||
@@ -160,22 +159,16 @@ class RndStatus(commands.Cog):
|
|||||||
botstatus = f"{clean_prefix}help | {total_users} users | {servers} servers"
|
botstatus = f"{clean_prefix}help | {total_users} users | {servers} servers"
|
||||||
if (current_game != str(botstatus)) or current_game is None:
|
if (current_game != str(botstatus)) or current_game is None:
|
||||||
if _type == 1:
|
if _type == 1:
|
||||||
await self.bot.change_presence(
|
await self.bot.change_presence(activity=discord.Streaming(name=botstatus, url=url))
|
||||||
activity=discord.Streaming(name=botstatus, url=url)
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
await self.bot.change_presence(
|
await self.bot.change_presence(activity=discord.Activity(name=botstatus, type=_type))
|
||||||
activity=discord.Activity(name=botstatus, type=_type)
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
if len(statuses) > 0:
|
if len(statuses) > 0:
|
||||||
new_status = self.random_status(guild, statuses)
|
new_status = self.random_status(guild, statuses)
|
||||||
if current_game != new_status:
|
if current_game != new_status:
|
||||||
if (current_game != new_status) or current_game is None:
|
if (current_game != new_status) or current_game is None:
|
||||||
if _type == 1:
|
if _type == 1:
|
||||||
await self.bot.change_presence(
|
await self.bot.change_presence(activity=discord.Streaming(name=new_status, url=url))
|
||||||
activity=discord.Streaming(name=new_status, url=url)
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
await self.bot.change_presence(
|
await self.bot.change_presence(
|
||||||
activity=discord.Activity(name=new_status, type=_type)
|
activity=discord.Activity(name=new_status, type=_type)
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
from .seen import Seen
|
from .seen import Seen
|
||||||
|
|
||||||
|
__red_end_user_data_statement__ = (
|
||||||
|
"This cog does not persistently store end user data. "
|
||||||
|
"This cog does store discord IDs and last seen timestamp as needed for operation. "
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
async def setup(bot):
|
async def setup(bot):
|
||||||
cog = Seen(bot)
|
cog = Seen(bot)
|
||||||
|
|||||||
@@ -8,5 +8,6 @@
|
|||||||
"seen",
|
"seen",
|
||||||
"activity"
|
"activity"
|
||||||
],
|
],
|
||||||
"type": "COG"
|
"type": "COG",
|
||||||
|
"end_user_data_statement": "This cog does not persistently store end user data. This cog does store discord IDs and last seen timestamp as needed for operation. "
|
||||||
}
|
}
|
||||||
32
seen/seen.py
32
seen/seen.py
@@ -1,7 +1,7 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
import contextlib
|
import contextlib
|
||||||
import datetime
|
import datetime
|
||||||
from typing import Union
|
from typing import Union, Literal
|
||||||
|
|
||||||
import discord
|
import discord
|
||||||
import time
|
import time
|
||||||
@@ -14,6 +14,15 @@ _SCHEMA_VERSION = 2
|
|||||||
class Seen(commands.Cog):
|
class Seen(commands.Cog):
|
||||||
"""Shows last time a user was seen in chat."""
|
"""Shows last time a user was seen in chat."""
|
||||||
|
|
||||||
|
async def red_delete_data_for_user(
|
||||||
|
self, *, requester: Literal["discord", "owner", "user", "user_strict"], user_id: int,
|
||||||
|
):
|
||||||
|
if requester in ["discord", "owner"]:
|
||||||
|
data = await self.config.all_members()
|
||||||
|
for guild_id, members in data.items():
|
||||||
|
if user_id in members:
|
||||||
|
await self.config.member_from_ids(guild_id, user_id).clear()
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
self.config = Config.get_conf(self, 2784481001, force_registration=True)
|
self.config = Config.get_conf(self, 2784481001, force_registration=True)
|
||||||
@@ -29,9 +38,7 @@ class Seen(commands.Cog):
|
|||||||
|
|
||||||
async def initialize(self):
|
async def initialize(self):
|
||||||
asyncio.ensure_future(
|
asyncio.ensure_future(
|
||||||
self._migrate_config(
|
self._migrate_config(from_version=await self.config.schema_version(), to_version=_SCHEMA_VERSION)
|
||||||
from_version=await self.config.schema_version(), to_version=_SCHEMA_VERSION
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
async def _migrate_config(self, from_version: int, to_version: int):
|
async def _migrate_config(self, from_version: int, to_version: int):
|
||||||
@@ -75,9 +82,7 @@ class Seen(commands.Cog):
|
|||||||
member_seen_cache = self._cache.get(author.guild.id, {}).get(author.id, None)
|
member_seen_cache = self._cache.get(author.guild.id, {}).get(author.id, None)
|
||||||
|
|
||||||
if not member_seen_cache and not member_seen_config:
|
if not member_seen_cache and not member_seen_config:
|
||||||
embed = discord.Embed(
|
embed = discord.Embed(colour=discord.Color.red(), title="I haven't seen that user yet.")
|
||||||
colour=discord.Color.red(), title="I haven't seen that user yet."
|
|
||||||
)
|
|
||||||
return await ctx.send(embed=embed)
|
return await ctx.send(embed=embed)
|
||||||
|
|
||||||
if not member_seen_cache:
|
if not member_seen_cache:
|
||||||
@@ -132,10 +137,7 @@ class Seen(commands.Cog):
|
|||||||
|
|
||||||
@commands.Cog.listener()
|
@commands.Cog.listener()
|
||||||
async def on_typing(
|
async def on_typing(
|
||||||
self,
|
self, channel: discord.abc.Messageable, user: Union[discord.User, discord.Member], when: datetime.datetime,
|
||||||
channel: discord.abc.Messageable,
|
|
||||||
user: Union[discord.User, discord.Member],
|
|
||||||
when: datetime.datetime,
|
|
||||||
):
|
):
|
||||||
if getattr(user, "guild", None):
|
if getattr(user, "guild", None):
|
||||||
if user.guild.id not in self._cache:
|
if user.guild.id not in self._cache:
|
||||||
@@ -150,18 +152,14 @@ class Seen(commands.Cog):
|
|||||||
self._cache[after.guild.id][after.author.id] = int(time.time())
|
self._cache[after.guild.id][after.author.id] = int(time.time())
|
||||||
|
|
||||||
@commands.Cog.listener()
|
@commands.Cog.listener()
|
||||||
async def on_reaction_remove(
|
async def on_reaction_remove(self, reaction: discord.Reaction, user: Union[discord.Member, discord.User]):
|
||||||
self, reaction: discord.Reaction, user: Union[discord.Member, discord.User]
|
|
||||||
):
|
|
||||||
if getattr(user, "guild", None):
|
if getattr(user, "guild", None):
|
||||||
if user.guild.id not in self._cache:
|
if user.guild.id not in self._cache:
|
||||||
self._cache[user.guild.id] = {}
|
self._cache[user.guild.id] = {}
|
||||||
self._cache[user.guild.id][user.id] = int(time.time())
|
self._cache[user.guild.id][user.id] = int(time.time())
|
||||||
|
|
||||||
@commands.Cog.listener()
|
@commands.Cog.listener()
|
||||||
async def on_reaction_add(
|
async def on_reaction_add(self, reaction: discord.Reaction, user: Union[discord.Member, discord.User]):
|
||||||
self, reaction: discord.Reaction, user: Union[discord.Member, discord.User]
|
|
||||||
):
|
|
||||||
if getattr(user, "guild", None):
|
if getattr(user, "guild", None):
|
||||||
if user.guild.id not in self._cache:
|
if user.guild.id not in self._cache:
|
||||||
self._cache[user.guild.id] = {}
|
self._cache[user.guild.id] = {}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
from .snacktime import Snacktime
|
from .snacktime import Snacktime
|
||||||
|
|
||||||
|
__red_end_user_data_statement__ = "This cog does not persistently store data or metadata about users."
|
||||||
|
|
||||||
|
|
||||||
async def setup(bot):
|
async def setup(bot):
|
||||||
bot.add_cog(Snacktime(bot))
|
bot.add_cog(Snacktime(bot))
|
||||||
|
|||||||
@@ -5,5 +5,6 @@
|
|||||||
"description" : "snackburr will come around every-so-often if you've asked him to.\nI hear snackburr likes to come around more often when people are partyin.",
|
"description" : "snackburr will come around every-so-often if you've asked him to.\nI hear snackburr likes to come around more often when people are partyin.",
|
||||||
"install_msg" : "A snack delivery bear has arrived ʕ•ᴥ• ʔ",
|
"install_msg" : "A snack delivery bear has arrived ʕ•ᴥ• ʔ",
|
||||||
"tags" : ["snack", "snacktime", "snackburr", "party", "party time"],
|
"tags" : ["snack", "snacktime", "snackburr", "party", "party time"],
|
||||||
"disabled" : false
|
"disabled" : false,
|
||||||
|
"end_user_data_statement": "This cog does not persistently store data or metadata about users."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -124,8 +124,6 @@ SNACKBURR_PHRASES = {
|
|||||||
"partakes of",
|
"partakes of",
|
||||||
"ingests",
|
"ingests",
|
||||||
],
|
],
|
||||||
"ENABLE": [
|
"ENABLE": ["Oh you guys want snacks?! Aight, I'll come around every so often to hand some out!"],
|
||||||
"Oh you guys want snacks?! Aight, I'll come around every so often to hand some out!"
|
|
||||||
],
|
|
||||||
"DISABLE": ["You guys don't want snacks anymore? Alright, I'll stop comin around."],
|
"DISABLE": ["You guys don't want snacks anymore? Alright, I'll stop comin around."],
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,10 @@ log = logging.getLogger("red.aikaterna.snacktime")
|
|||||||
class Snacktime(commands.Cog):
|
class Snacktime(commands.Cog):
|
||||||
"""Snackburr's passing out pb jars!"""
|
"""Snackburr's passing out pb jars!"""
|
||||||
|
|
||||||
|
async def red_delete_data_for_user(self, **kwargs):
|
||||||
|
""" Nothing to delete """
|
||||||
|
return
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
self.config = Config.get_conf(self, 2712291001, force_registration=True)
|
self.config = Config.get_conf(self, 2712291001, force_registration=True)
|
||||||
@@ -93,9 +97,7 @@ class Snacktime(commands.Cog):
|
|||||||
|
|
||||||
first_phrase = randchoice(SNACKBURR_PHRASES["EAT_BEFORE"])
|
first_phrase = randchoice(SNACKBURR_PHRASES["EAT_BEFORE"])
|
||||||
second_phrase = randchoice(SNACKBURR_PHRASES["EAT_AFTER"])
|
second_phrase = randchoice(SNACKBURR_PHRASES["EAT_AFTER"])
|
||||||
await ctx.send(
|
await ctx.send(f"`{persona} {ctx.author.display_name} {first_phrase} {second_phrase} {amount} whole pb jars!`")
|
||||||
f"`{persona} {ctx.author.display_name} {first_phrase} {second_phrase} {amount} whole pb jars!`"
|
|
||||||
)
|
|
||||||
|
|
||||||
@commands.guild_only()
|
@commands.guild_only()
|
||||||
@commands.group()
|
@commands.group()
|
||||||
@@ -121,9 +123,7 @@ class Snacktime(commands.Cog):
|
|||||||
|
|
||||||
msg = f"[Delivering in]: {humanize_list(channel_names)}\n"
|
msg = f"[Delivering in]: {humanize_list(channel_names)}\n"
|
||||||
msg += f"[Event start delay]: {guild_data['EVENT_START_DELAY']} seconds\n"
|
msg += f"[Event start delay]: {guild_data['EVENT_START_DELAY']} seconds\n"
|
||||||
msg += (
|
msg += f"[Event start variance]: {guild_data['EVENT_START_DELAY_VARIANCE']} seconds\n"
|
||||||
f"[Event start variance]: {guild_data['EVENT_START_DELAY_VARIANCE']} seconds\n"
|
|
||||||
)
|
|
||||||
msg += f"[Friends status]: {invite_friends}\n"
|
msg += f"[Friends status]: {invite_friends}\n"
|
||||||
msg += f"[Messages before event]: {guild_data['MSGS_BEFORE_EVENT']}\n"
|
msg += f"[Messages before event]: {guild_data['MSGS_BEFORE_EVENT']}\n"
|
||||||
msg += f"[Snack amount limit]: {guild_data['SNACK_AMOUNT']} pb\n"
|
msg += f"[Snack amount limit]: {guild_data['SNACK_AMOUNT']} pb\n"
|
||||||
@@ -136,18 +136,14 @@ class Snacktime(commands.Cog):
|
|||||||
@snackset.command()
|
@snackset.command()
|
||||||
async def errandtime(self, ctx, seconds: int):
|
async def errandtime(self, ctx, seconds: int):
|
||||||
"""How long snackburr needs to be out doin errands.. more or less."""
|
"""How long snackburr needs to be out doin errands.. more or less."""
|
||||||
event_start_delay_variance = await self.config.guild(
|
event_start_delay_variance = await self.config.guild(ctx.guild).EVENT_START_DELAY_VARIANCE()
|
||||||
ctx.guild
|
|
||||||
).EVENT_START_DELAY_VARIANCE()
|
|
||||||
if seconds <= event_start_delay_variance:
|
if seconds <= event_start_delay_variance:
|
||||||
await ctx.send("errandtime must be greater than errandvariance!")
|
await ctx.send("errandtime must be greater than errandvariance!")
|
||||||
elif seconds <= 0:
|
elif seconds <= 0:
|
||||||
await ctx.send("errandtime must be greater than 0")
|
await ctx.send("errandtime must be greater than 0")
|
||||||
else:
|
else:
|
||||||
await self.config.guild(ctx.guild).EVENT_START_DELAY.set(seconds)
|
await self.config.guild(ctx.guild).EVENT_START_DELAY.set(seconds)
|
||||||
await ctx.send(
|
await ctx.send(f"snackburr's errands will now take around {round(seconds/60, 2)} minutes!")
|
||||||
f"snackburr's errands will now take around {round(seconds/60, 2)} minutes!"
|
|
||||||
)
|
|
||||||
|
|
||||||
@snackset.command()
|
@snackset.command()
|
||||||
async def errandvariance(self, ctx, seconds: int):
|
async def errandvariance(self, ctx, seconds: int):
|
||||||
@@ -159,9 +155,7 @@ class Snacktime(commands.Cog):
|
|||||||
await ctx.send("errandvariance must be 0 or greater!")
|
await ctx.send("errandvariance must be 0 or greater!")
|
||||||
else:
|
else:
|
||||||
await self.config.guild(ctx.guild).EVENT_START_DELAY_VARIANCE.set(seconds)
|
await self.config.guild(ctx.guild).EVENT_START_DELAY_VARIANCE.set(seconds)
|
||||||
await ctx.send(
|
await ctx.send(f"snackburr now might be {round(seconds/60, 2)} minutes early or late to snacktime")
|
||||||
f"snackburr now might be {round(seconds/60, 2)} minutes early or late to snacktime"
|
|
||||||
)
|
|
||||||
|
|
||||||
@snackset.command(name="snacktime")
|
@snackset.command(name="snacktime")
|
||||||
async def snacktimetime(self, ctx, seconds: int):
|
async def snacktimetime(self, ctx, seconds: int):
|
||||||
@@ -185,9 +179,7 @@ class Snacktime(commands.Cog):
|
|||||||
await ctx.send("snackvariance must be 0 or greater!")
|
await ctx.send("snackvariance must be 0 or greater!")
|
||||||
else:
|
else:
|
||||||
await self.config.guild(ctx.guild).SNACK_DURATION_VARIANCE.set(seconds)
|
await self.config.guild(ctx.guild).SNACK_DURATION_VARIANCE.set(seconds)
|
||||||
await ctx.send(
|
await ctx.send(f"snackburr now may have to leave snacktime {round(seconds/60, 2)} minutes early or late")
|
||||||
f"snackburr now may have to leave snacktime {round(seconds/60, 2)} minutes early or late"
|
|
||||||
)
|
|
||||||
|
|
||||||
@snackset.command()
|
@snackset.command()
|
||||||
async def msgsneeded(self, ctx, amt: int):
|
async def msgsneeded(self, ctx, amt: int):
|
||||||
@@ -196,9 +188,7 @@ class Snacktime(commands.Cog):
|
|||||||
await ctx.send("msgsneeded must be greater than 0")
|
await ctx.send("msgsneeded must be greater than 0")
|
||||||
else:
|
else:
|
||||||
await self.config.guild(ctx.guild).MSGS_BEFORE_EVENT.set(amt)
|
await self.config.guild(ctx.guild).MSGS_BEFORE_EVENT.set(amt)
|
||||||
await ctx.send(
|
await ctx.send(f"snackburr will now wait until {amt} messages pass until he comes with snacks")
|
||||||
f"snackburr will now wait until {amt} messages pass until he comes with snacks"
|
|
||||||
)
|
|
||||||
|
|
||||||
@snackset.command()
|
@snackset.command()
|
||||||
async def amount(self, ctx, amt: int):
|
async def amount(self, ctx, amt: int):
|
||||||
@@ -272,13 +262,9 @@ class Snacktime(commands.Cog):
|
|||||||
return
|
return
|
||||||
self.snacktimeCheckLock[scid] = True
|
self.snacktimeCheckLock[scid] = True
|
||||||
if seconds < 0:
|
if seconds < 0:
|
||||||
await ctx.send(
|
await ctx.send(f"I'm not sure where snackburr is.. He's already {round(abs(seconds/60), 2)} minutes late!")
|
||||||
f"I'm not sure where snackburr is.. He's already {round(abs(seconds/60), 2)} minutes late!"
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
await ctx.send(
|
await ctx.send(f"snackburr's out on errands! I think he'll be back in {round(seconds/60, 2)} minutes")
|
||||||
f"snackburr's out on errands! I think he'll be back in {round(seconds/60, 2)} minutes"
|
|
||||||
)
|
|
||||||
await asyncio.sleep(40)
|
await asyncio.sleep(40)
|
||||||
self.snacktimeCheckLock[scid] = False
|
self.snacktimeCheckLock[scid] = False
|
||||||
|
|
||||||
@@ -306,20 +292,14 @@ class Snacktime(commands.Cog):
|
|||||||
await self.config.channel(message.channel).repeatMissedSnacktimes.set(0)
|
await self.config.channel(message.channel).repeatMissedSnacktimes.set(0)
|
||||||
else:
|
else:
|
||||||
await message.channel.send(await self.get_response(message, "NO_TAKERS"))
|
await message.channel.send(await self.get_response(message, "NO_TAKERS"))
|
||||||
repeat_missed_snacktimes = await self.config.channel(
|
repeat_missed_snacktimes = await self.config.channel(message.channel).repeatMissedSnacktimes()
|
||||||
message.channel
|
await self.config.channel(message.channel).repeatMissedSnacktimes.set(repeat_missed_snacktimes + 1)
|
||||||
).repeatMissedSnacktimes()
|
|
||||||
await self.config.channel(message.channel).repeatMissedSnacktimes.set(
|
|
||||||
repeat_missed_snacktimes + 1
|
|
||||||
)
|
|
||||||
await asyncio.sleep(2)
|
await asyncio.sleep(2)
|
||||||
if (repeat_missed_snacktimes + 1) > 9: # move to a setting
|
if (repeat_missed_snacktimes + 1) > 9: # move to a setting
|
||||||
await message.channel.send(await self.get_response(message, "LONELY"))
|
await message.channel.send(await self.get_response(message, "LONELY"))
|
||||||
deliver_channels = await self.config.guild(message.guild).DELIVER_CHANNELS()
|
deliver_channels = await self.config.guild(message.guild).DELIVER_CHANNELS()
|
||||||
new_deliver_channels = deliver_channels.remove(message.channel.id)
|
new_deliver_channels = deliver_channels.remove(message.channel.id)
|
||||||
await self.config.guild(message.guild).DELIVER_CHANNELS.set(
|
await self.config.guild(message.guild).DELIVER_CHANNELS.set(new_deliver_channels)
|
||||||
new_deliver_channels
|
|
||||||
)
|
|
||||||
await self.config.channel(message.channel).repeatMissedSnacktimes.set(0)
|
await self.config.channel(message.channel).repeatMissedSnacktimes.set(0)
|
||||||
except:
|
except:
|
||||||
log.error("Snacktime: Failed to send message in startSnack")
|
log.error("Snacktime: Failed to send message in startSnack")
|
||||||
@@ -365,9 +345,7 @@ class Snacktime(commands.Cog):
|
|||||||
# start snacktime
|
# start snacktime
|
||||||
await self.startSnack(message)
|
await self.startSnack(message)
|
||||||
# if no snack coming, schedule one
|
# if no snack coming, schedule one
|
||||||
elif self.snackInProgress.get(scid, False) == False and not self.startLock.get(
|
elif self.snackInProgress.get(scid, False) == False and not self.startLock.get(scid, False):
|
||||||
scid, False
|
|
||||||
):
|
|
||||||
self.msgsPassed[scid] = self.msgsPassed.get(scid, 0) + 1
|
self.msgsPassed[scid] = self.msgsPassed.get(scid, 0) + 1
|
||||||
# check for collisions
|
# check for collisions
|
||||||
msgs_before_event = await self.config.guild(message.guild).MSGS_BEFORE_EVENT()
|
msgs_before_event = await self.config.guild(message.guild).MSGS_BEFORE_EVENT()
|
||||||
@@ -385,9 +363,7 @@ class Snacktime(commands.Cog):
|
|||||||
log.debug(f"Snacktime: {message.author.name} - I got the Lock")
|
log.debug(f"Snacktime: {message.author.name} - I got the Lock")
|
||||||
self.lockRequests[scid] = []
|
self.lockRequests[scid] = []
|
||||||
# someone got through already
|
# someone got through already
|
||||||
if self.msgsPassed[
|
if self.msgsPassed[scid] < msgs_before_event or self.snackInProgress.get(scid, False):
|
||||||
scid
|
|
||||||
] < msgs_before_event or self.snackInProgress.get(scid, False):
|
|
||||||
log.debug("Snacktime: Lock: someone got through already.")
|
log.debug("Snacktime: Lock: someone got through already.")
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
@@ -404,8 +380,7 @@ class Snacktime(commands.Cog):
|
|||||||
log.debug(f"Snacktime: activity: {message.content}")
|
log.debug(f"Snacktime: activity: {message.content}")
|
||||||
guild_data = await self.config.guild(message.guild).all()
|
guild_data = await self.config.guild(message.guild).all()
|
||||||
timeTillSnack = guild_data["EVENT_START_DELAY"] + randint(
|
timeTillSnack = guild_data["EVENT_START_DELAY"] + randint(
|
||||||
-guild_data["EVENT_START_DELAY_VARIANCE"],
|
-guild_data["EVENT_START_DELAY_VARIANCE"], guild_data["EVENT_START_DELAY_VARIANCE"],
|
||||||
guild_data["EVENT_START_DELAY_VARIANCE"],
|
|
||||||
)
|
)
|
||||||
log.debug(f"Snacktime: {str(timeTillSnack)} seconds till snacktime")
|
log.debug(f"Snacktime: {str(timeTillSnack)} seconds till snacktime")
|
||||||
self.snacktimePrediction[scid] = msgTime + guild_data["EVENT_START_DELAY"]
|
self.snacktimePrediction[scid] = msgTime + guild_data["EVENT_START_DELAY"]
|
||||||
@@ -450,10 +425,7 @@ class Snacktime(commands.Cog):
|
|||||||
userWants = False
|
userWants = False
|
||||||
for agreePhrase in agree_phrases:
|
for agreePhrase in agree_phrases:
|
||||||
# no one word answers
|
# no one word answers
|
||||||
if (
|
if agreePhrase in message.content.lower() and len(message.content.split()) > 1:
|
||||||
agreePhrase in message.content.lower()
|
|
||||||
and len(message.content.split()) > 1
|
|
||||||
):
|
|
||||||
userWants = True
|
userWants = True
|
||||||
break
|
break
|
||||||
if userWants:
|
if userWants:
|
||||||
@@ -478,8 +450,7 @@ class Snacktime(commands.Cog):
|
|||||||
await bank.set_balance(message.author, b.max_balance)
|
await bank.set_balance(message.author, b.max_balance)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
log.info(
|
log.info(
|
||||||
f"Failed to send pb message. {message.author.name} didn't get pb\n",
|
f"Failed to send pb message. {message.author.name} didn't get pb\n", exc_info=True,
|
||||||
exc_info=True,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -1,5 +1,16 @@
|
|||||||
from .timezone import Timezone
|
from .timezone import Timezone
|
||||||
|
|
||||||
|
__red_end_user_data_statement__ = (
|
||||||
|
"This cog stores data provided by users "
|
||||||
|
"for the express purpose of redisplaying. "
|
||||||
|
"It does not store user data which was not "
|
||||||
|
"provided through a command. "
|
||||||
|
"Users may remove their own content "
|
||||||
|
"without making a data removal request. "
|
||||||
|
"This cog does not support data requests, "
|
||||||
|
"but will respect deletion requests."
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def setup(bot):
|
def setup(bot):
|
||||||
bot.add_cog(Timezone(bot))
|
bot.add_cog(Timezone(bot))
|
||||||
|
|||||||
@@ -12,5 +12,6 @@
|
|||||||
"requirements": [
|
"requirements": [
|
||||||
"pytz"
|
"pytz"
|
||||||
],
|
],
|
||||||
"type": "COG"
|
"type": "COG",
|
||||||
|
"end_user_data_statement": "This cog stores data provided by users for the express purpose of redisplaying. It does not store user data which was not provided through a command. Users may remove their own content without making a data removal request. This cog does not support data requests, but will respect deletion requests."
|
||||||
}
|
}
|
||||||
@@ -3,13 +3,18 @@ import pytz
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from pytz import common_timezones
|
from pytz import common_timezones
|
||||||
from pytz import country_timezones
|
from pytz import country_timezones
|
||||||
from typing import Optional
|
from typing import Optional, Literal
|
||||||
from redbot.core import Config, commands, checks
|
from redbot.core import Config, commands, checks
|
||||||
|
|
||||||
|
|
||||||
class Timezone(commands.Cog):
|
class Timezone(commands.Cog):
|
||||||
"""Gets times across the world..."""
|
"""Gets times across the world..."""
|
||||||
|
|
||||||
|
async def red_delete_data_for_user(
|
||||||
|
self, *, requester: Literal["discord", "owner", "user", "user_strict"], user_id: int,
|
||||||
|
):
|
||||||
|
await self.config.user_from_id(user_id).clear()
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
self.config = Config.get_conf(self, 278049241001, force_registration=True)
|
self.config = Config.get_conf(self, 278049241001, force_registration=True)
|
||||||
@@ -45,7 +50,7 @@ class Timezone(commands.Cog):
|
|||||||
"<https://en.wikipedia.org/wiki/List_of_tz_database_time_zones>"
|
"<https://en.wikipedia.org/wiki/List_of_tz_database_time_zones>"
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
tz = tz.title() if '/' in tz else tz.upper()
|
tz = tz.title() if "/" in tz else tz.upper()
|
||||||
if tz not in common_timezones:
|
if tz not in common_timezones:
|
||||||
raise Exception(tz)
|
raise Exception(tz)
|
||||||
fmt = "**%H:%M** %d-%B-%Y **%Z (UTC %z)**"
|
fmt = "**%H:%M** %d-%B-%Y **%Z (UTC %z)**"
|
||||||
@@ -139,8 +144,7 @@ class Timezone(commands.Cog):
|
|||||||
fmt = "**%H:%M** %d-%B-%Y **%Z (UTC %z)**"
|
fmt = "**%H:%M** %d-%B-%Y **%Z (UTC %z)**"
|
||||||
time = time.strftime(fmt)
|
time = time.strftime(fmt)
|
||||||
await ctx.send(
|
await ctx.send(
|
||||||
f"{user.name}'s current timezone is: **{usertime}**\n"
|
f"{user.name}'s current timezone is: **{usertime}**\n" f"The current time is: {str(time)}"
|
||||||
f"The current time is: {str(time)}"
|
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
await ctx.send("That user hasn't set their timezone.")
|
await ctx.send("That user hasn't set their timezone.")
|
||||||
@@ -174,6 +178,4 @@ class Timezone(commands.Cog):
|
|||||||
position = "ahead of" if user_diff < other_diff else "behind"
|
position = "ahead of" if user_diff < other_diff else "behind"
|
||||||
position_text = "" if time_diff == 0 else f" {position} you"
|
position_text = "" if time_diff == 0 else f" {position} you"
|
||||||
|
|
||||||
await ctx.send(
|
await ctx.send(f"{user.display_name}'s time is {other_time} which is {time_amt}{position_text}.")
|
||||||
f"{user.display_name}'s time is {other_time} which is {time_amt}{position_text}."
|
|
||||||
)
|
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
from .tools import Tools
|
from .tools import Tools
|
||||||
|
|
||||||
|
__red_end_user_data_statement__ = "This cog does not persistently store data or metadata about users."
|
||||||
|
|
||||||
|
|
||||||
def setup(bot):
|
def setup(bot):
|
||||||
bot.add_cog(Tools(bot))
|
bot.add_cog(Tools(bot))
|
||||||
|
|||||||
@@ -51,9 +51,7 @@ class GuildChannelConverter(converter.IDConverter, converter.Converter):
|
|||||||
else:
|
else:
|
||||||
result = converter._get_from_guilds(bot, "get_channel", channel_id)
|
result = converter._get_from_guilds(bot, "get_channel", channel_id)
|
||||||
|
|
||||||
if not isinstance(
|
if not isinstance(result, (discord.TextChannel, discord.VoiceChannel, discord.CategoryChannel)):
|
||||||
result, (discord.TextChannel, discord.VoiceChannel, discord.CategoryChannel)
|
|
||||||
):
|
|
||||||
raise BadArgument('Channel "{}" not found.'.format(argument))
|
raise BadArgument('Channel "{}" not found.'.format(argument))
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|||||||
@@ -17,5 +17,6 @@
|
|||||||
"tags": [
|
"tags": [
|
||||||
"tools"
|
"tools"
|
||||||
],
|
],
|
||||||
"type": "COG"
|
"type": "COG",
|
||||||
|
"end_user_data_statement": "This cog does not persistently store data or metadata about users."
|
||||||
}
|
}
|
||||||
162
tools/tools.py
162
tools/tools.py
@@ -3,11 +3,8 @@ import datetime
|
|||||||
import discord
|
import discord
|
||||||
import inspect
|
import inspect
|
||||||
import logging
|
import logging
|
||||||
import random
|
|
||||||
import re
|
import re
|
||||||
import os
|
from redbot.core import checks, commands
|
||||||
import time
|
|
||||||
from redbot.core import Config, checks, commands
|
|
||||||
from redbot.core.utils import chat_formatting as cf
|
from redbot.core.utils import chat_formatting as cf
|
||||||
from redbot.core.utils.common_filters import filter_invites
|
from redbot.core.utils.common_filters import filter_invites
|
||||||
from redbot.core.utils.menus import menu, DEFAULT_CONTROLS, close_menu
|
from redbot.core.utils.menus import menu, DEFAULT_CONTROLS, close_menu
|
||||||
@@ -21,6 +18,10 @@ log = logging.getLogger("red.aikaterna.tools")
|
|||||||
class Tools(commands.Cog):
|
class Tools(commands.Cog):
|
||||||
"""Mod and Admin tools."""
|
"""Mod and Admin tools."""
|
||||||
|
|
||||||
|
async def red_delete_data_for_user(self, **kwargs):
|
||||||
|
""" Nothing to delete """
|
||||||
|
return
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
|
||||||
@@ -53,13 +54,9 @@ class Tools(commands.Cog):
|
|||||||
tcs = guild.text_channels
|
tcs = guild.text_channels
|
||||||
vcs = guild.voice_channels
|
vcs = guild.voice_channels
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
return await ctx.send(
|
return await ctx.send("User is not in that guild or I do not have access to that guild.")
|
||||||
"User is not in that guild or I do not have access to that guild."
|
|
||||||
)
|
|
||||||
|
|
||||||
author_text_channels = [
|
author_text_channels = [c for c in tcs if c.permissions_for(ctx.author).read_messages is True]
|
||||||
c for c in tcs if c.permissions_for(ctx.author).read_messages is True
|
|
||||||
]
|
|
||||||
author_voice_channels = [c for c in vcs if c.permissions_for(ctx.author).connect is True]
|
author_voice_channels = [c for c in vcs if c.permissions_for(ctx.author).connect is True]
|
||||||
|
|
||||||
user_text_channels = [c for c in tcs if c.permissions_for(user).read_messages is True]
|
user_text_channels = [c for c in tcs if c.permissions_for(user).read_messages is True]
|
||||||
@@ -72,9 +69,7 @@ class Tools(commands.Cog):
|
|||||||
user_voice_channels
|
user_voice_channels
|
||||||
) # voice channels only the author has access to
|
) # voice channels only the author has access to
|
||||||
|
|
||||||
user_only_t = set(user_text_channels) - set(
|
user_only_t = set(user_text_channels) - set(author_text_channels) # text channels only the user has access to
|
||||||
author_text_channels
|
|
||||||
) # text channels only the user has access to
|
|
||||||
user_only_v = set(user_voice_channels) - set(
|
user_only_v = set(user_voice_channels) - set(
|
||||||
author_voice_channels
|
author_voice_channels
|
||||||
) # voice channels only the user has access to
|
) # voice channels only the user has access to
|
||||||
@@ -87,18 +82,14 @@ class Tools(commands.Cog):
|
|||||||
) # voice channels that author and user have in common
|
) # voice channels that author and user have in common
|
||||||
|
|
||||||
msg = "```ini\n"
|
msg = "```ini\n"
|
||||||
msg += "{} [TEXT CHANNELS IN COMMON]:\n\n{}\n\n".format(
|
msg += "{} [TEXT CHANNELS IN COMMON]:\n\n{}\n\n".format(len(common_t), ", ".join([c.name for c in common_t]))
|
||||||
len(common_t), ", ".join([c.name for c in common_t])
|
|
||||||
)
|
|
||||||
msg += "{} [TEXT CHANNELS {} HAS EXCLUSIVE ACCESS TO]:\n\n{}\n\n".format(
|
msg += "{} [TEXT CHANNELS {} HAS EXCLUSIVE ACCESS TO]:\n\n{}\n\n".format(
|
||||||
len(user_only_t), user.name.upper(), ", ".join([c.name for c in user_only_t])
|
len(user_only_t), user.name.upper(), ", ".join([c.name for c in user_only_t])
|
||||||
)
|
)
|
||||||
msg += "{} [TEXT CHANNELS YOU HAVE EXCLUSIVE ACCESS TO]:\n\n{}\n\n\n".format(
|
msg += "{} [TEXT CHANNELS YOU HAVE EXCLUSIVE ACCESS TO]:\n\n{}\n\n\n".format(
|
||||||
len(author_only_t), ", ".join([c.name for c in author_only_t])
|
len(author_only_t), ", ".join([c.name for c in author_only_t])
|
||||||
)
|
)
|
||||||
msg += "{} [VOICE CHANNELS IN COMMON]:\n\n{}\n\n".format(
|
msg += "{} [VOICE CHANNELS IN COMMON]:\n\n{}\n\n".format(len(common_v), ", ".join([c.name for c in common_v]))
|
||||||
len(common_v), ", ".join([c.name for c in common_v])
|
|
||||||
)
|
|
||||||
msg += "{} [VOICE CHANNELS {} HAS EXCLUSIVE ACCESS TO]:\n\n{}\n\n".format(
|
msg += "{} [VOICE CHANNELS {} HAS EXCLUSIVE ACCESS TO]:\n\n{}\n\n".format(
|
||||||
len(user_only_v), user.name.upper(), ", ".join([c.name for c in user_only_v])
|
len(user_only_v), user.name.upper(), ", ".join([c.name for c in user_only_v])
|
||||||
)
|
)
|
||||||
@@ -119,16 +110,10 @@ class Tools(commands.Cog):
|
|||||||
guild = self.bot.get_guild(guild)
|
guild = self.bot.get_guild(guild)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
can_access = [
|
can_access = [c.name for c in guild.text_channels if c.permissions_for(user).read_messages == True]
|
||||||
c.name
|
|
||||||
for c in guild.text_channels
|
|
||||||
if c.permissions_for(user).read_messages == True
|
|
||||||
]
|
|
||||||
text_channels = [c.name for c in guild.text_channels]
|
text_channels = [c.name for c in guild.text_channels]
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
return await ctx.send(
|
return await ctx.send("User is not in that guild or I do not have access to that guild.")
|
||||||
"User is not in that guild or I do not have access to that guild."
|
|
||||||
)
|
|
||||||
|
|
||||||
prefix = "You have" if user.id == ctx.author.id else user.name + " has"
|
prefix = "You have" if user.id == ctx.author.id else user.name + " has"
|
||||||
msg = "```ini\n[{} access to {} out of {} text channels]\n\n".format(
|
msg = "```ini\n[{} access to {} out of {} text channels]\n\n".format(
|
||||||
@@ -136,9 +121,7 @@ class Tools(commands.Cog):
|
|||||||
)
|
)
|
||||||
|
|
||||||
msg += "[ACCESS]:\n{}\n\n".format(", ".join(can_access))
|
msg += "[ACCESS]:\n{}\n\n".format(", ".join(can_access))
|
||||||
msg += "[NO ACCESS]:\n{}\n```".format(
|
msg += "[NO ACCESS]:\n{}\n```".format(", ".join(list(set(text_channels) - set(can_access))))
|
||||||
", ".join(list(set(text_channels) - set(can_access)))
|
|
||||||
)
|
|
||||||
await ctx.send(msg)
|
await ctx.send(msg)
|
||||||
|
|
||||||
@access.command()
|
@access.command()
|
||||||
@@ -152,14 +135,10 @@ class Tools(commands.Cog):
|
|||||||
guild = self.bot.get_guild(guild)
|
guild = self.bot.get_guild(guild)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
can_access = [
|
can_access = [c.name for c in guild.voice_channels if c.permissions_for(user).connect is True]
|
||||||
c.name for c in guild.voice_channels if c.permissions_for(user).connect is True
|
|
||||||
]
|
|
||||||
voice_channels = [c.name for c in guild.voice_channels]
|
voice_channels = [c.name for c in guild.voice_channels]
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
return await ctx.send(
|
return await ctx.send("User is not in that guild or I do not have access to that guild.")
|
||||||
"User is not in that guild or I do not have access to that guild."
|
|
||||||
)
|
|
||||||
|
|
||||||
prefix = "You have" if user.id == ctx.author.id else user.name + " has"
|
prefix = "You have" if user.id == ctx.author.id else user.name + " has"
|
||||||
msg = "```ini\n[{} access to {} out of {} voice channels]\n\n".format(
|
msg = "```ini\n[{} access to {} out of {} voice channels]\n\n".format(
|
||||||
@@ -167,9 +146,7 @@ class Tools(commands.Cog):
|
|||||||
)
|
)
|
||||||
|
|
||||||
msg += "[ACCESS]:\n{}\n\n".format(", ".join(can_access))
|
msg += "[ACCESS]:\n{}\n\n".format(", ".join(can_access))
|
||||||
msg += "[NO ACCESS]:\n{}\n```".format(
|
msg += "[NO ACCESS]:\n{}\n```".format(", ".join(list(set(voice_channels) - set(can_access))))
|
||||||
", ".join(list(set(voice_channels) - set(can_access)))
|
|
||||||
)
|
|
||||||
await ctx.send(msg)
|
await ctx.send(msg)
|
||||||
|
|
||||||
@commands.guild_only()
|
@commands.guild_only()
|
||||||
@@ -196,8 +173,7 @@ class Tools(commands.Cog):
|
|||||||
embed_list = []
|
embed_list = []
|
||||||
for page in cf.pagify(msg, shorten_by=1400):
|
for page in cf.pagify(msg, shorten_by=1400):
|
||||||
embed = discord.Embed(
|
embed = discord.Embed(
|
||||||
description="**Total bans:** {}\n\n{}".format(bancount, page),
|
description="**Total bans:** {}\n\n{}".format(bancount, page), colour=await ctx.embed_colour(),
|
||||||
colour=await ctx.embed_colour(),
|
|
||||||
)
|
)
|
||||||
embed_list.append(embed)
|
embed_list.append(embed)
|
||||||
await menu(ctx, embed_list, DEFAULT_CONTROLS)
|
await menu(ctx, embed_list, DEFAULT_CONTROLS)
|
||||||
@@ -332,17 +308,13 @@ class Tools(commands.Cog):
|
|||||||
role = roles[response - 1]
|
role = roles[response - 1]
|
||||||
|
|
||||||
awaiter = await ctx.send(
|
awaiter = await ctx.send(
|
||||||
embed=discord.Embed(
|
embed=discord.Embed(description="Getting member names...", colour=await ctx.embed_colour())
|
||||||
description="Getting member names...", colour=await ctx.embed_colour()
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
await asyncio.sleep(1.5) # taking time to retrieve the names
|
await asyncio.sleep(1.5) # taking time to retrieve the names
|
||||||
users_in_role = "\n".join(
|
users_in_role = "\n".join(sorted(m.display_name for m in guild.members if role in m.roles))
|
||||||
sorted(m.display_name for m in guild.members if role in m.roles)
|
|
||||||
)
|
|
||||||
if len(users_in_role) == 0:
|
if len(users_in_role) == 0:
|
||||||
embed = discord.Embed(
|
embed = discord.Embed(
|
||||||
description=cf.bold(f"0 users found in the {role.name} role."), colour=await ctx.embed_colour()
|
description=cf.bold(f"0 users found in the {role.name} role."), colour=await ctx.embed_colour(),
|
||||||
)
|
)
|
||||||
await awaiter.edit(embed=embed)
|
await awaiter.edit(embed=embed)
|
||||||
return
|
return
|
||||||
@@ -385,8 +357,7 @@ class Tools(commands.Cog):
|
|||||||
|
|
||||||
if ctx.channel.permissions_for(ctx.guild.me).embed_links:
|
if ctx.channel.permissions_for(ctx.guild.me).embed_links:
|
||||||
embed = discord.Embed(
|
embed = discord.Embed(
|
||||||
description=f"{user.mention} joined this guild on {joined_on}.",
|
description=f"{user.mention} joined this guild on {joined_on}.", color=await ctx.embed_colour(),
|
||||||
color=await ctx.embed_colour(),
|
|
||||||
)
|
)
|
||||||
await ctx.send(embed=embed)
|
await ctx.send(embed=embed)
|
||||||
else:
|
else:
|
||||||
@@ -406,9 +377,9 @@ class Tools(commands.Cog):
|
|||||||
form = "{gid} :: {mems:0{zpadding}} :: {name}"
|
form = "{gid} :: {mems:0{zpadding}} :: {name}"
|
||||||
all_forms = [
|
all_forms = [
|
||||||
form.format(
|
form.format(
|
||||||
gid=g.id,
|
gid=g.id,
|
||||||
mems=g.member_count,
|
mems=g.member_count,
|
||||||
name=filter_invites(cf.escape(g.name)),
|
name=filter_invites(cf.escape(g.name)),
|
||||||
zpadding=max_zpadding
|
zpadding=max_zpadding
|
||||||
)
|
)
|
||||||
for g in guilds
|
for g in guilds
|
||||||
@@ -438,9 +409,7 @@ class Tools(commands.Cog):
|
|||||||
topChannels_formed = "\n".join(self.channels_format(top_channels))
|
topChannels_formed = "\n".join(self.channels_format(top_channels))
|
||||||
categories_formed = "\n\n".join([self.category_format(tup) for tup in category_channels])
|
categories_formed = "\n\n".join([self.category_format(tup) for tup in category_channels])
|
||||||
|
|
||||||
await ctx.send(
|
await ctx.send(f"{ctx.guild.name} has {len(channels)} channel{'s' if len(channels) > 1 else ''}.")
|
||||||
f"{ctx.guild.name} has {len(channels)} channel{'s' if len(channels) > 1 else ''}."
|
|
||||||
)
|
|
||||||
|
|
||||||
for page in cf.pagify(topChannels_formed, delims=["\n"], shorten_by=16):
|
for page in cf.pagify(topChannels_formed, delims=["\n"], shorten_by=16):
|
||||||
await ctx.send(asciidoc(page))
|
await ctx.send(asciidoc(page))
|
||||||
@@ -461,9 +430,7 @@ class Tools(commands.Cog):
|
|||||||
header = "{:>33}\n{}\n\n".format(head1, "-" * 57)
|
header = "{:>33}\n{}\n\n".format(head1, "-" * 57)
|
||||||
|
|
||||||
user_body = (
|
user_body = (
|
||||||
" {mem} ({memid})\n"
|
" {mem} ({memid})\n" " {spcs}Joined Guild: {sp1}{join}\n" " {spcs}Account Created: {sp2}{created}\n\n"
|
||||||
" {spcs}Joined Guild: {sp1}{join}\n"
|
|
||||||
" {spcs}Account Created: {sp2}{created}\n\n"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
disp = header
|
disp = header
|
||||||
@@ -526,11 +493,7 @@ class Tools(commands.Cog):
|
|||||||
else:
|
else:
|
||||||
role = self._role_from_string(ctx.guild, rolename)
|
role = self._role_from_string(ctx.guild, rolename)
|
||||||
if role is None:
|
if role is None:
|
||||||
await ctx.send(
|
await ctx.send(embed=discord.Embed(description="Cannot find role.", colour=await ctx.embed_colour()))
|
||||||
embed=discord.Embed(
|
|
||||||
description="Cannot find role.", colour=await ctx.embed_colour()
|
|
||||||
)
|
|
||||||
)
|
|
||||||
return
|
return
|
||||||
await ctx.send(f"**{rolename} ID:** {role.id}")
|
await ctx.send(f"**{rolename} ID:** {role.id}")
|
||||||
|
|
||||||
@@ -576,9 +539,7 @@ class Tools(commands.Cog):
|
|||||||
em.add_field(name="Server", value=role.guild.name)
|
em.add_field(name="Server", value=role.guild.name)
|
||||||
em.add_field(name="Role Name", value=role.name)
|
em.add_field(name="Role Name", value=role.name)
|
||||||
em.add_field(name="Created", value=self._dynamic_time(role.created_at))
|
em.add_field(name="Created", value=self._dynamic_time(role.created_at))
|
||||||
em.add_field(
|
em.add_field(name="Users in Role", value=len([m for m in guild.members if role in m.roles]))
|
||||||
name="Users in Role", value=len([m for m in guild.members if role in m.roles])
|
|
||||||
)
|
|
||||||
em.add_field(name="ID", value=role.id)
|
em.add_field(name="ID", value=role.id)
|
||||||
em.add_field(name="Color", value=role.color)
|
em.add_field(name="Color", value=role.color)
|
||||||
em.add_field(name="Position", value=role.position)
|
em.add_field(name="Position", value=role.position)
|
||||||
@@ -624,9 +585,7 @@ class Tools(commands.Cog):
|
|||||||
form = "`{rpos:0{zpadding}}` - `{rid}` - `{rcolor}` - {rment} "
|
form = "`{rpos:0{zpadding}}` - `{rid}` - `{rcolor}` - {rment} "
|
||||||
max_zpadding = max([len(str(r.position)) for r in ctx.guild.roles])
|
max_zpadding = max([len(str(r.position)) for r in ctx.guild.roles])
|
||||||
rolelist = [
|
rolelist = [
|
||||||
form.format(
|
form.format(rpos=r.position, zpadding=max_zpadding, rid=r.id, rment=r.mention, rcolor=r.color)
|
||||||
rpos=r.position, zpadding=max_zpadding, rid=r.id, rment=r.mention, rcolor=r.color
|
|
||||||
)
|
|
||||||
for r in ctx.guild.roles
|
for r in ctx.guild.roles
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -635,8 +594,7 @@ class Tools(commands.Cog):
|
|||||||
embed_list = []
|
embed_list = []
|
||||||
for page in cf.pagify(rolelist, shorten_by=1400):
|
for page in cf.pagify(rolelist, shorten_by=1400):
|
||||||
embed = discord.Embed(
|
embed = discord.Embed(
|
||||||
description=f"**Total roles:** {len(ctx.guild.roles)}\n\n{page}",
|
description=f"**Total roles:** {len(ctx.guild.roles)}\n\n{page}", colour=await ctx.embed_colour(),
|
||||||
colour=await ctx.embed_colour(),
|
|
||||||
)
|
)
|
||||||
embed_list.append(embed)
|
embed_list.append(embed)
|
||||||
await menu(ctx, embed_list, DEFAULT_CONTROLS)
|
await menu(ctx, embed_list, DEFAULT_CONTROLS)
|
||||||
@@ -648,24 +606,8 @@ class Tools(commands.Cog):
|
|||||||
guild = ctx.guild
|
guild = ctx.guild
|
||||||
if not user:
|
if not user:
|
||||||
user = author
|
user = author
|
||||||
seen = len(
|
seen = len(set([member.guild.name for member in self.bot.get_all_members() if member.id == user.id]))
|
||||||
set(
|
sharedservers = str(set([member.guild.name for member in self.bot.get_all_members() if member.id == user.id]))
|
||||||
[
|
|
||||||
member.guild.name
|
|
||||||
for member in self.bot.get_all_members()
|
|
||||||
if member.id == user.id
|
|
||||||
]
|
|
||||||
)
|
|
||||||
)
|
|
||||||
sharedservers = str(
|
|
||||||
set(
|
|
||||||
[
|
|
||||||
member.guild.name
|
|
||||||
for member in self.bot.get_all_members()
|
|
||||||
if member.id == user.id
|
|
||||||
]
|
|
||||||
)
|
|
||||||
)
|
|
||||||
for shared in sharedservers:
|
for shared in sharedservers:
|
||||||
shared = "".strip("'").join(sharedservers).strip("'")
|
shared = "".strip("'").join(sharedservers).strip("'")
|
||||||
shared = shared.strip("{").strip("}")
|
shared = shared.strip("{").strip("}")
|
||||||
@@ -693,15 +635,7 @@ class Tools(commands.Cog):
|
|||||||
guild = self.bot.get_guild(int(guild))
|
guild = self.bot.get_guild(int(guild))
|
||||||
except TypeError:
|
except TypeError:
|
||||||
return await ctx.send("Not a valid guild id.")
|
return await ctx.send("Not a valid guild id.")
|
||||||
online = str(
|
online = str(len([m.status for m in guild.members if str(m.status) == "online" or str(m.status) == "idle"]))
|
||||||
len(
|
|
||||||
[
|
|
||||||
m.status
|
|
||||||
for m in guild.members
|
|
||||||
if str(m.status) == "online" or str(m.status) == "idle"
|
|
||||||
]
|
|
||||||
)
|
|
||||||
)
|
|
||||||
total_users = str(len(guild.members))
|
total_users = str(len(guild.members))
|
||||||
text_channels = [x for x in guild.channels if isinstance(x, discord.TextChannel)]
|
text_channels = [x for x in guild.channels if isinstance(x, discord.TextChannel)]
|
||||||
voice_channels = [x for x in guild.channels if isinstance(x, discord.VoiceChannel)]
|
voice_channels = [x for x in guild.channels if isinstance(x, discord.VoiceChannel)]
|
||||||
@@ -739,17 +673,7 @@ class Tools(commands.Cog):
|
|||||||
roles = [x.name for x in user.roles if x.name != "@everyone"]
|
roles = [x.name for x in user.roles if x.name != "@everyone"]
|
||||||
if not roles:
|
if not roles:
|
||||||
roles = ["None"]
|
roles = ["None"]
|
||||||
seen = str(
|
seen = str(len(set([member.guild.name for member in self.bot.get_all_members() if member.id == user.id])))
|
||||||
len(
|
|
||||||
set(
|
|
||||||
[
|
|
||||||
member.guild.name
|
|
||||||
for member in self.bot.get_all_members()
|
|
||||||
if member.id == user.id
|
|
||||||
]
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
load = "```\nLoading user info...```"
|
load = "```\nLoading user info...```"
|
||||||
waiting = await ctx.send(load)
|
waiting = await ctx.send(load)
|
||||||
@@ -772,9 +696,7 @@ class Tools(commands.Cog):
|
|||||||
if actwatch := discord.utils.get(user.activities, type=discord.ActivityType.watching):
|
if actwatch := discord.utils.get(user.activities, type=discord.ActivityType.watching):
|
||||||
data += "[Watching]: {}\n".format(cf.escape(str(actwatch.name)))
|
data += "[Watching]: {}\n".format(cf.escape(str(actwatch.name)))
|
||||||
if actstream := discord.utils.get(user.activities, type=discord.ActivityType.streaming):
|
if actstream := discord.utils.get(user.activities, type=discord.ActivityType.streaming):
|
||||||
data += "[Streaming]: [{}]({})\n".format(
|
data += "[Streaming]: [{}]({})\n".format(cf.escape(str(actstream.name)), cf.escape(actstream.url))
|
||||||
cf.escape(str(actstream.name)), cf.escape(actstream.url)
|
|
||||||
)
|
|
||||||
if actcustom := discord.utils.get(user.activities, type=discord.ActivityType.custom):
|
if actcustom := discord.utils.get(user.activities, type=discord.ActivityType.custom):
|
||||||
if actcustom.name is not None:
|
if actcustom.name is not None:
|
||||||
data += "[Custom status]: {}\n".format(cf.escape(str(actcustom.name)))
|
data += "[Custom status]: {}\n".format(cf.escape(str(actcustom.name)))
|
||||||
@@ -784,12 +706,8 @@ class Tools(commands.Cog):
|
|||||||
if caller != "invoke":
|
if caller != "invoke":
|
||||||
data += "[Joined]: {}\n".format(self._dynamic_time(joined_at))
|
data += "[Joined]: {}\n".format(self._dynamic_time(joined_at))
|
||||||
data += "[Roles]: {}\n".format(", ".join(roles))
|
data += "[Roles]: {}\n".format(", ".join(roles))
|
||||||
data += "[In Voice]: {}\n".format(
|
data += "[In Voice]: {}\n".format(user.voice.channel if user.voice is not None else None)
|
||||||
user.voice.channel if user.voice is not None else None
|
data += "[AFK]: {}\n".format(user.voice.afk if user.voice is not None else False)
|
||||||
)
|
|
||||||
data += "[AFK]: {}\n".format(
|
|
||||||
user.voice.afk if user.voice is not None else False
|
|
||||||
)
|
|
||||||
data += "```"
|
data += "```"
|
||||||
await asyncio.sleep(1)
|
await asyncio.sleep(1)
|
||||||
await waiting.edit(content=data)
|
await waiting.edit(content=data)
|
||||||
@@ -902,11 +820,7 @@ class Tools(commands.Cog):
|
|||||||
type_justify = max([len(type_name(c)) for c in channels])
|
type_justify = max([len(type_name(c)) for c in channels])
|
||||||
|
|
||||||
return [
|
return [
|
||||||
channel_form.format(
|
channel_form.format(name=c.name[:24].ljust(name_justify), ctype=type_name(c).ljust(type_justify), cid=c.id,)
|
||||||
name=c.name[:24].ljust(name_justify),
|
|
||||||
ctype=type_name(c).ljust(type_justify),
|
|
||||||
cid=c.id,
|
|
||||||
)
|
|
||||||
for c in channels
|
for c in channels
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,14 @@
|
|||||||
from .trickortreat import TrickOrTreat
|
from .trickortreat import TrickOrTreat
|
||||||
|
|
||||||
|
__red_end_user_data_statement__ = (
|
||||||
|
"This cog does not persistently store end user data. "
|
||||||
|
"This cog does store discord IDs as needed for operation. "
|
||||||
|
"This cog does store user stats for the cog such as their score. "
|
||||||
|
"Users may remove their own content without making a data removal request."
|
||||||
|
"This cog does not support data requests, "
|
||||||
|
"but will respect deletion requests."
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def setup(bot):
|
def setup(bot):
|
||||||
bot.add_cog(TrickOrTreat(bot))
|
bot.add_cog(TrickOrTreat(bot))
|
||||||
|
|||||||
@@ -11,5 +11,6 @@
|
|||||||
"candy",
|
"candy",
|
||||||
"pick"
|
"pick"
|
||||||
],
|
],
|
||||||
"type": "COG"
|
"type": "COG",
|
||||||
|
"end_user_data_statement": "This cog does not persistently store end user data. This cog does store discord IDs as needed for operation. This cog does store user stats for the cog such as their score. Users may remove their own content without making a data removal request. This cog does not support data requests, but will respect deletion requests."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
import datetime
|
import datetime
|
||||||
|
from imaplib import Literal
|
||||||
|
|
||||||
import discord
|
import discord
|
||||||
import random
|
import random
|
||||||
import math
|
import math
|
||||||
@@ -7,10 +9,15 @@ from redbot.core import commands, checks, Config, bank
|
|||||||
from redbot.core.utils.chat_formatting import box, pagify, humanize_number
|
from redbot.core.utils.chat_formatting import box, pagify, humanize_number
|
||||||
from redbot.core.utils.menus import menu, DEFAULT_CONTROLS
|
from redbot.core.utils.menus import menu, DEFAULT_CONTROLS
|
||||||
|
|
||||||
__version__ = "0.0.7"
|
__version__ = "0.0.8"
|
||||||
|
|
||||||
|
|
||||||
class TrickOrTreat(commands.Cog):
|
class TrickOrTreat(commands.Cog):
|
||||||
|
async def red_delete_data_for_user(
|
||||||
|
self, *, requester: Literal["discord", "owner", "user", "user_strict"], user_id: int,
|
||||||
|
):
|
||||||
|
await self.config.user_from_id(user_id).clear()
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
self.config = Config.get_conf(self, 2710311393, force_registration=True)
|
self.config = Config.get_conf(self, 2710311393, force_registration=True)
|
||||||
@@ -51,9 +58,7 @@ class TrickOrTreat(commands.Cog):
|
|||||||
candy_type = "stars"
|
candy_type = "stars"
|
||||||
candy_list = ["candies", "lollipops", "stars"]
|
candy_list = ["candies", "lollipops", "stars"]
|
||||||
if candy_type not in candy_list:
|
if candy_type not in candy_list:
|
||||||
return await ctx.send(
|
return await ctx.send("That's not a candy type! Use the inventory command to see what you have.")
|
||||||
"That's not a candy type! Use the inventory command to see what you have."
|
|
||||||
)
|
|
||||||
if userdata[candy_type] < number:
|
if userdata[candy_type] < number:
|
||||||
return await ctx.send(f"You don't have that many {candy_type}.")
|
return await ctx.send(f"You don't have that many {candy_type}.")
|
||||||
if userdata[candy_type] == 0:
|
if userdata[candy_type] == 0:
|
||||||
@@ -76,9 +81,7 @@ class TrickOrTreat(commands.Cog):
|
|||||||
if yuck == 10:
|
if yuck == 10:
|
||||||
await self.config.user(ctx.author).sickness.set(userdata["sickness"] + 25)
|
await self.config.user(ctx.author).sickness.set(userdata["sickness"] + 25)
|
||||||
if yuck in range(1, 9):
|
if yuck in range(1, 9):
|
||||||
await self.config.user(ctx.author).sickness.set(
|
await self.config.user(ctx.author).sickness.set(userdata["sickness"] + (yuck * 2))
|
||||||
userdata["sickness"] + (yuck * 2)
|
|
||||||
)
|
|
||||||
|
|
||||||
if userdata["candies"] > 3 + number:
|
if userdata["candies"] > 3 + number:
|
||||||
lost_candy = userdata["candies"] - random.randint(1, 3) - number
|
lost_candy = userdata["candies"] - random.randint(1, 3) - number
|
||||||
@@ -90,14 +93,10 @@ class TrickOrTreat(commands.Cog):
|
|||||||
await self.config.user(ctx.author).candies.set(0)
|
await self.config.user(ctx.author).candies.set(0)
|
||||||
await self.config.guild(ctx.guild).pick.set(pick_now + lost_candy)
|
await self.config.guild(ctx.guild).pick.set(pick_now + lost_candy)
|
||||||
else:
|
else:
|
||||||
await self.config.user(ctx.author).candies.set(
|
await self.config.user(ctx.author).candies.set(userdata["candies"] - lost_candy)
|
||||||
userdata["candies"] - lost_candy
|
|
||||||
)
|
|
||||||
await self.config.guild(ctx.guild).pick.set(pick_now + lost_candy)
|
await self.config.guild(ctx.guild).pick.set(pick_now + lost_candy)
|
||||||
|
|
||||||
await self.config.user(ctx.author).eaten.set(
|
await self.config.user(ctx.author).eaten.set(userdata["eaten"] + (userdata["candies"] - lost_candy))
|
||||||
userdata["eaten"] + (userdata["candies"] - lost_candy)
|
|
||||||
)
|
|
||||||
|
|
||||||
return await ctx.send(
|
return await ctx.send(
|
||||||
f"You begin to think you don't need all this candy, maybe...\n*{lost_candy} candies are left behind*"
|
f"You begin to think you don't need all this candy, maybe...\n*{lost_candy} candies are left behind*"
|
||||||
@@ -117,9 +116,7 @@ class TrickOrTreat(commands.Cog):
|
|||||||
)
|
)
|
||||||
await self.config.guild(ctx.guild).pick.set(pick + lost_candy)
|
await self.config.guild(ctx.guild).pick.set(pick + lost_candy)
|
||||||
await self.config.user(ctx.author).candies.set(0)
|
await self.config.user(ctx.author).candies.set(0)
|
||||||
await self.config.user(ctx.author).eaten.set(
|
await self.config.user(ctx.author).eaten.set(userdata["eaten"] + (userdata["candies"] - lost_candy))
|
||||||
userdata["eaten"] + (userdata["candies"] - lost_candy)
|
|
||||||
)
|
|
||||||
message = await ctx.send("...")
|
message = await ctx.send("...")
|
||||||
await asyncio.sleep(2)
|
await asyncio.sleep(2)
|
||||||
await message.edit(content="..........")
|
await message.edit(content="..........")
|
||||||
@@ -235,12 +232,9 @@ class TrickOrTreat(commands.Cog):
|
|||||||
for page in pagify(temp_msg, delims=["\n"], page_length=1000):
|
for page in pagify(temp_msg, delims=["\n"], page_length=1000):
|
||||||
embed = discord.Embed(
|
embed = discord.Embed(
|
||||||
colour=0xF4731C,
|
colour=0xF4731C,
|
||||||
description=box(f"\N{CANDY} Global leaderboard \N{CANDY}", lang="prolog")
|
description=box(f"\N{CANDY} Global leaderboard \N{CANDY}", lang="prolog") + (box(page, lang="md")),
|
||||||
+ (box(page, lang="md")),
|
|
||||||
)
|
|
||||||
embed.set_footer(
|
|
||||||
text=f"Page {humanize_number(pages)}/{humanize_number(math.ceil(len(temp_msg) / 1500))}"
|
|
||||||
)
|
)
|
||||||
|
embed.set_footer(text=f"Page {humanize_number(pages)}/{humanize_number(math.ceil(len(temp_msg) / 1500))}")
|
||||||
pages += 1
|
pages += 1
|
||||||
page_list.append(embed)
|
page_list.append(embed)
|
||||||
return await menu(ctx, page_list, DEFAULT_CONTROLS)
|
return await menu(ctx, page_list, DEFAULT_CONTROLS)
|
||||||
@@ -264,15 +258,11 @@ class TrickOrTreat(commands.Cog):
|
|||||||
elif sickness in range(56, 71):
|
elif sickness in range(56, 71):
|
||||||
em.description += f"\n\n**Sickness is over 55/100**\n*You don't feel so good...*"
|
em.description += f"\n\n**Sickness is over 55/100**\n*You don't feel so good...*"
|
||||||
elif sickness in range(71, 86):
|
elif sickness in range(71, 86):
|
||||||
em.description += (
|
em.description += f"\n\n**Sickness is over 70/100**\n*You really don't feel so good...*"
|
||||||
f"\n\n**Sickness is over 70/100**\n*You really don't feel so good...*"
|
|
||||||
)
|
|
||||||
elif sickness in range(86, 101):
|
elif sickness in range(86, 101):
|
||||||
em.description += f"\n\n**Sickness is over 85/100**\n*The thought of more sugar makes you feel awful...*"
|
em.description += f"\n\n**Sickness is over 85/100**\n*The thought of more sugar makes you feel awful...*"
|
||||||
elif sickness > 100:
|
elif sickness > 100:
|
||||||
em.description += (
|
em.description += f"\n\n**Sickness is over 100/100**\n*Better wait a while for more candy...*"
|
||||||
f"\n\n**Sickness is over 100/100**\n*Better wait a while for more candy...*"
|
|
||||||
)
|
|
||||||
await ctx.send(msg, embed=em)
|
await ctx.send(msg, embed=em)
|
||||||
|
|
||||||
@commands.guild_only()
|
@commands.guild_only()
|
||||||
@@ -351,9 +341,7 @@ class TrickOrTreat(commands.Cog):
|
|||||||
else:
|
else:
|
||||||
message = await ctx.send("You start looking around for a target...")
|
message = await ctx.send("You start looking around for a target...")
|
||||||
await asyncio.sleep(random.randint(3, 6))
|
await asyncio.sleep(random.randint(3, 6))
|
||||||
return await message.edit(
|
return await message.edit(content="You snuck around for a while but didn't find anything.")
|
||||||
content="You snuck around for a while but didn't find anything."
|
|
||||||
)
|
|
||||||
user_candy_now = await self.config.user(ctx.author).candies()
|
user_candy_now = await self.config.user(ctx.author).candies()
|
||||||
multip = random.randint(1, 100) / 100
|
multip = random.randint(1, 100) / 100
|
||||||
if multip > 0.7:
|
if multip > 0.7:
|
||||||
@@ -362,9 +350,7 @@ class TrickOrTreat(commands.Cog):
|
|||||||
if pieces <= 0:
|
if pieces <= 0:
|
||||||
message = await ctx.send("You stealthily move over to an unsuspecting person...")
|
message = await ctx.send("You stealthily move over to an unsuspecting person...")
|
||||||
await asyncio.sleep(4)
|
await asyncio.sleep(4)
|
||||||
return await message.edit(
|
return await message.edit(content="You found someone to pickpocket, but they had nothing but pocket lint.")
|
||||||
content="You found someone to pickpocket, but they had nothing but pocket lint."
|
|
||||||
)
|
|
||||||
chance = random.randint(1, 25)
|
chance = random.randint(1, 25)
|
||||||
sneak_phrases = [
|
sneak_phrases = [
|
||||||
"You look around furtively...",
|
"You look around furtively...",
|
||||||
@@ -374,9 +360,7 @@ class TrickOrTreat(commands.Cog):
|
|||||||
if chance <= 10:
|
if chance <= 10:
|
||||||
message = await ctx.send("You creep closer to the target...")
|
message = await ctx.send("You creep closer to the target...")
|
||||||
await asyncio.sleep(random.randint(3, 5))
|
await asyncio.sleep(random.randint(3, 5))
|
||||||
return await message.edit(
|
return await message.edit(content="You snuck around for a while but didn't find anything.")
|
||||||
content="You snuck around for a while but didn't find anything."
|
|
||||||
)
|
|
||||||
if chance > 18:
|
if chance > 18:
|
||||||
await self.config.user(picked_user).candies.set(picked_candy_now - pieces)
|
await self.config.user(picked_user).candies.set(picked_candy_now - pieces)
|
||||||
await self.config.user(ctx.author).candies.set(user_candy_now + pieces)
|
await self.config.user(ctx.author).candies.set(user_candy_now + pieces)
|
||||||
@@ -412,9 +396,7 @@ class TrickOrTreat(commands.Cog):
|
|||||||
@commands.group()
|
@commands.group()
|
||||||
async def totchannel(self, ctx):
|
async def totchannel(self, ctx):
|
||||||
"""Channel management for Trick or Treat."""
|
"""Channel management for Trick or Treat."""
|
||||||
if ctx.invoked_subcommand is not None or isinstance(
|
if ctx.invoked_subcommand is not None or isinstance(ctx.invoked_subcommand, commands.Group):
|
||||||
ctx.invoked_subcommand, commands.Group
|
|
||||||
):
|
|
||||||
return
|
return
|
||||||
channel_list = await self.config.guild(ctx.guild).channel()
|
channel_list = await self.config.guild(ctx.guild).channel()
|
||||||
channel_msg = "Trick or Treat Channels:\n"
|
channel_msg = "Trick or Treat Channels:\n"
|
||||||
@@ -501,10 +483,7 @@ class TrickOrTreat(commands.Cog):
|
|||||||
last_time = datetime.datetime.strptime(str(userdata["last_tot"]), "%Y-%m-%d %H:%M:%S.%f")
|
last_time = datetime.datetime.strptime(str(userdata["last_tot"]), "%Y-%m-%d %H:%M:%S.%f")
|
||||||
now = datetime.datetime.now(datetime.timezone.utc)
|
now = datetime.datetime.now(datetime.timezone.utc)
|
||||||
now = now.replace(tzinfo=None)
|
now = now.replace(tzinfo=None)
|
||||||
if (
|
if int((now - last_time).total_seconds()) < await self.config.guild(message.guild).cooldown():
|
||||||
int((now - last_time).total_seconds())
|
|
||||||
< await self.config.guild(message.guild).cooldown()
|
|
||||||
):
|
|
||||||
messages = [
|
messages = [
|
||||||
"The thought of candy right now doesn't really sound like a good idea.",
|
"The thought of candy right now doesn't really sound like a good idea.",
|
||||||
"All the lights on this street are dark...",
|
"All the lights on this street are dark...",
|
||||||
|
|||||||
@@ -1,5 +1,16 @@
|
|||||||
from .warcraftlogs import WarcraftLogs
|
from .warcraftlogs import WarcraftLogs
|
||||||
|
|
||||||
|
__red_end_user_data_statement__ = (
|
||||||
|
"This cog stores data provided by users "
|
||||||
|
"for the express purpose of redisplaying. "
|
||||||
|
"It does not store user data which was not "
|
||||||
|
"provided through a command. "
|
||||||
|
"Users may remove their own content "
|
||||||
|
"without making a data removal request. "
|
||||||
|
"This cog does not support data requests, "
|
||||||
|
"but will respect deletion requests."
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def setup(bot):
|
def setup(bot):
|
||||||
bot.add_cog(WarcraftLogs(bot))
|
bot.add_cog(WarcraftLogs(bot))
|
||||||
|
|||||||
@@ -4,5 +4,7 @@
|
|||||||
"install_msg": "Check out [p]help WarcraftLogs and set your WCL API key, available by signing into a WarcraftLogs account on their site and visiting the bottom of your settings page. ",
|
"install_msg": "Check out [p]help WarcraftLogs and set your WCL API key, available by signing into a WarcraftLogs account on their site and visiting the bottom of your settings page. ",
|
||||||
"short": "WarcraftLogs data for World of Warcraft Classic players.",
|
"short": "WarcraftLogs data for World of Warcraft Classic players.",
|
||||||
"tags": ["warcraft"],
|
"tags": ["warcraft"],
|
||||||
"type": "COG"
|
"type": "COG",
|
||||||
|
"end_user_data_statement": "This cog stores data provided by users for the express purpose of redisplaying. It does not store user data which was not provided through a command. Users may remove their own content without making a data removal request. This cog does not support data requests, but will respect deletion requests."
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,18 +1,24 @@
|
|||||||
|
from imaplib import Literal
|
||||||
|
|
||||||
import aiohttp
|
import aiohttp
|
||||||
import asyncio
|
|
||||||
import datetime
|
import datetime
|
||||||
import discord
|
import discord
|
||||||
import itertools
|
import itertools
|
||||||
import json
|
import json
|
||||||
from operator import itemgetter
|
from operator import itemgetter
|
||||||
from redbot.core import Config, commands, checks
|
from redbot.core import Config, commands, checks
|
||||||
from redbot.core.utils.chat_formatting import box, humanize_list, pagify
|
from redbot.core.utils.chat_formatting import box
|
||||||
from redbot.core.utils.menus import menu, DEFAULT_CONTROLS
|
from redbot.core.utils.menus import menu, DEFAULT_CONTROLS
|
||||||
|
|
||||||
|
|
||||||
class WarcraftLogs(commands.Cog):
|
class WarcraftLogs(commands.Cog):
|
||||||
"""Access Warcraftlogs stats."""
|
"""Access Warcraftlogs stats."""
|
||||||
|
|
||||||
|
async def red_delete_data_for_user(
|
||||||
|
self, *, requester: Literal["discord", "owner", "user", "user_strict"], user_id: int,
|
||||||
|
):
|
||||||
|
await self.config.user_from_id(user_id).clear()
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
self.config = Config.get_conf(self, 2713931001, force_registration=True)
|
self.config = Config.get_conf(self, 2713931001, force_registration=True)
|
||||||
@@ -89,9 +95,7 @@ class WarcraftLogs(commands.Cog):
|
|||||||
userdata = await self.config.user(ctx.author).all()
|
userdata = await self.config.user(ctx.author).all()
|
||||||
apikey = await self.config.apikey()
|
apikey = await self.config.apikey()
|
||||||
if not apikey:
|
if not apikey:
|
||||||
return await ctx.send(
|
return await ctx.send("The bot owner needs to set a WarcraftLogs API key before this can be used.")
|
||||||
"The bot owner needs to set a WarcraftLogs API key before this can be used."
|
|
||||||
)
|
|
||||||
if not username:
|
if not username:
|
||||||
username = userdata["charname"]
|
username = userdata["charname"]
|
||||||
if not username:
|
if not username:
|
||||||
@@ -135,9 +139,7 @@ class WarcraftLogs(commands.Cog):
|
|||||||
log_data.append(log_info)
|
log_data.append(log_info)
|
||||||
|
|
||||||
# Logged Kill sorting
|
# Logged Kill sorting
|
||||||
embed1 = discord.Embed(
|
embed1 = discord.Embed(title=f"{username.title()} - {realmname.title()} ({region.upper()})\nLogged Kills")
|
||||||
title=f"{username.title()} - {realmname.title()} ({region.upper()})\nLogged Kills"
|
|
||||||
)
|
|
||||||
for item in kill_data:
|
for item in kill_data:
|
||||||
zone_kills = ""
|
zone_kills = ""
|
||||||
for boss_info in list(item.values()):
|
for boss_info in list(item.values()):
|
||||||
@@ -155,10 +157,7 @@ class WarcraftLogs(commands.Cog):
|
|||||||
for item in log_data:
|
for item in log_data:
|
||||||
log_page = ""
|
log_page = ""
|
||||||
for id_data in list(item.values()):
|
for id_data in list(item.values()):
|
||||||
sorted_item = {
|
sorted_item = {k: v for k, v in sorted(id_data.items(), key=lambda item: item[1], reverse=True)}
|
||||||
k: v
|
|
||||||
for k, v in sorted(id_data.items(), key=lambda item: item[1], reverse=True)
|
|
||||||
}
|
|
||||||
short_list = dict(itertools.islice(sorted_item.items(), 5))
|
short_list = dict(itertools.islice(sorted_item.items(), 5))
|
||||||
zone_name, phase_num = self.clean_name(list(item))
|
zone_name, phase_num = self.clean_name(list(item))
|
||||||
for log_id, info_list in short_list.items():
|
for log_id, info_list in short_list.items():
|
||||||
@@ -188,9 +187,7 @@ class WarcraftLogs(commands.Cog):
|
|||||||
userdata = await self.config.user(ctx.author).all()
|
userdata = await self.config.user(ctx.author).all()
|
||||||
apikey = await self.config.apikey()
|
apikey = await self.config.apikey()
|
||||||
if not apikey:
|
if not apikey:
|
||||||
return await ctx.send(
|
return await ctx.send("The bot owner needs to set a WarcraftLogs API key before this can be used.")
|
||||||
"The bot owner needs to set a WarcraftLogs API key before this can be used."
|
|
||||||
)
|
|
||||||
if not username:
|
if not username:
|
||||||
username = userdata["charname"]
|
username = userdata["charname"]
|
||||||
if not username:
|
if not username:
|
||||||
@@ -328,7 +325,7 @@ class WarcraftLogs(commands.Cog):
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_recent_gear(data):
|
def get_recent_gear(data):
|
||||||
date_sorted_data = sorted(data, key=itemgetter('startTime'), reverse=True)
|
date_sorted_data = sorted(data, key=itemgetter("startTime"), reverse=True)
|
||||||
for encounter in date_sorted_data:
|
for encounter in date_sorted_data:
|
||||||
try:
|
try:
|
||||||
item_name = encounter["gear"][0]["name"]
|
item_name = encounter["gear"][0]["name"]
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
from .wolfram import Wolfram
|
from .wolfram import Wolfram
|
||||||
|
|
||||||
|
__red_end_user_data_statement__ = "This cog does not persistently store data or metadata about users."
|
||||||
|
|
||||||
|
|
||||||
def setup(bot):
|
def setup(bot):
|
||||||
bot.add_cog(Wolfram(bot))
|
bot.add_cog(Wolfram(bot))
|
||||||
|
|||||||
@@ -11,5 +11,6 @@
|
|||||||
"requirements": [
|
"requirements": [
|
||||||
"pillow"
|
"pillow"
|
||||||
],
|
],
|
||||||
"type": "COG"
|
"type": "COG",
|
||||||
|
"end_user_data_statement": "This cog does not persistently store data or metadata about users."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
import aiohttp
|
import aiohttp
|
||||||
import asyncio
|
|
||||||
import discord
|
import discord
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
from PIL import Image
|
|
||||||
import xml.etree.ElementTree as ET
|
import xml.etree.ElementTree as ET
|
||||||
import urllib.parse
|
import urllib.parse
|
||||||
|
|
||||||
@@ -13,6 +11,10 @@ from redbot.core.utils.chat_formatting import box, pagify
|
|||||||
class Wolfram(commands.Cog):
|
class Wolfram(commands.Cog):
|
||||||
"""Ask Wolfram Alpha any question."""
|
"""Ask Wolfram Alpha any question."""
|
||||||
|
|
||||||
|
async def red_delete_data_for_user(self, **kwargs):
|
||||||
|
""" Nothing to delete """
|
||||||
|
return
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
self.session = aiohttp.ClientSession()
|
self.session = aiohttp.ClientSession()
|
||||||
@@ -27,9 +29,7 @@ class Wolfram(commands.Cog):
|
|||||||
"""Ask Wolfram Alpha any question."""
|
"""Ask Wolfram Alpha any question."""
|
||||||
api_key = await self.config.WOLFRAM_API_KEY()
|
api_key = await self.config.WOLFRAM_API_KEY()
|
||||||
if not api_key:
|
if not api_key:
|
||||||
return await ctx.send(
|
return await ctx.send("No API key set for Wolfram Alpha. Get one at http://products.wolframalpha.com/api/")
|
||||||
"No API key set for Wolfram Alpha. Get one at http://products.wolframalpha.com/api/"
|
|
||||||
)
|
|
||||||
|
|
||||||
url = "http://api.wolframalpha.com/v2/query?"
|
url = "http://api.wolframalpha.com/v2/query?"
|
||||||
query = " ".join(question)
|
query = " ".join(question)
|
||||||
@@ -59,9 +59,7 @@ class Wolfram(commands.Cog):
|
|||||||
return await ctx.send_help()
|
return await ctx.send_help()
|
||||||
api_key = await self.config.WOLFRAM_API_KEY()
|
api_key = await self.config.WOLFRAM_API_KEY()
|
||||||
if not api_key:
|
if not api_key:
|
||||||
return await ctx.send(
|
return await ctx.send("No API key set for Wolfram Alpha. Get one at http://products.wolframalpha.com/api/")
|
||||||
"No API key set for Wolfram Alpha. Get one at http://products.wolframalpha.com/api/"
|
|
||||||
)
|
|
||||||
|
|
||||||
width = 800
|
width = 800
|
||||||
font_size = 30
|
font_size = 30
|
||||||
@@ -78,14 +76,10 @@ class Wolfram(commands.Cog):
|
|||||||
img = await r.content.read()
|
img = await r.content.read()
|
||||||
if len(img) == 43:
|
if len(img) == 43:
|
||||||
# img = b'Wolfram|Alpha did not understand your input'
|
# img = b'Wolfram|Alpha did not understand your input'
|
||||||
return await ctx.send(
|
return await ctx.send("There is as yet insufficient data for a meaningful answer.")
|
||||||
"There is as yet insufficient data for a meaningful answer."
|
|
||||||
)
|
|
||||||
wolfram_img = BytesIO(img)
|
wolfram_img = BytesIO(img)
|
||||||
try:
|
try:
|
||||||
await ctx.channel.send(
|
await ctx.channel.send(file=discord.File(wolfram_img, f"wolfram{ctx.author.id}.png"))
|
||||||
file=discord.File(wolfram_img, f"wolfram{ctx.author.id}.png")
|
|
||||||
)
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
await ctx.send(f"Oops, there was a problem: {e}")
|
await ctx.send(f"Oops, there was a problem: {e}")
|
||||||
|
|
||||||
@@ -94,9 +88,7 @@ class Wolfram(commands.Cog):
|
|||||||
"""Ask Wolfram Alpha any math question. Returns step by step answers."""
|
"""Ask Wolfram Alpha any math question. Returns step by step answers."""
|
||||||
api_key = await self.config.WOLFRAM_API_KEY()
|
api_key = await self.config.WOLFRAM_API_KEY()
|
||||||
if not api_key:
|
if not api_key:
|
||||||
return await ctx.send(
|
return await ctx.send("No API key set for Wolfram Alpha. Get one at http://products.wolframalpha.com/api/")
|
||||||
"No API key set for Wolfram Alpha. Get one at http://products.wolframalpha.com/api/"
|
|
||||||
)
|
|
||||||
|
|
||||||
url = f"http://api.wolframalpha.com/v2/query"
|
url = f"http://api.wolframalpha.com/v2/query"
|
||||||
params = {
|
params = {
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
from .youtube import YouTube
|
from .youtube import YouTube
|
||||||
|
|
||||||
|
__red_end_user_data_statement__ = "This cog does not persistently store data or metadata about users."
|
||||||
|
|
||||||
|
|
||||||
def setup(bot):
|
def setup(bot):
|
||||||
bot.add_cog(YouTube(bot))
|
bot.add_cog(YouTube(bot))
|
||||||
|
|||||||
@@ -8,5 +8,6 @@
|
|||||||
"tags": [
|
"tags": [
|
||||||
"youtube"
|
"youtube"
|
||||||
],
|
],
|
||||||
"type": "COG"
|
"type": "COG",
|
||||||
|
"end_user_data_statement": "This cog does not persistently store data or metadata about users."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,10 @@ from redbot.core.utils.menus import menu, DEFAULT_CONTROLS
|
|||||||
class YouTube(commands.Cog):
|
class YouTube(commands.Cog):
|
||||||
"""Search YouTube for videos."""
|
"""Search YouTube for videos."""
|
||||||
|
|
||||||
|
async def red_delete_data_for_user(self, **kwargs):
|
||||||
|
""" Nothing to delete """
|
||||||
|
return
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
self.session = aiohttp.ClientSession()
|
self.session = aiohttp.ClientSession()
|
||||||
@@ -14,7 +18,9 @@ class YouTube(commands.Cog):
|
|||||||
async def _youtube_results(self, query: str):
|
async def _youtube_results(self, query: str):
|
||||||
try:
|
try:
|
||||||
headers = {"user-agent": "Red-cog/3.0"}
|
headers = {"user-agent": "Red-cog/3.0"}
|
||||||
async with self.session.get("https://www.youtube.com/results", params={"search_query": query}, headers=headers) as r:
|
async with self.session.get(
|
||||||
|
"https://www.youtube.com/results", params={"search_query": query}, headers=headers
|
||||||
|
) as r:
|
||||||
result = await r.text()
|
result = await r.text()
|
||||||
yt_find = re.findall(r"{\"videoId\":\"(.{11})", result)
|
yt_find = re.findall(r"{\"videoId\":\"(.{11})", result)
|
||||||
url_list = []
|
url_list = []
|
||||||
|
|||||||
Reference in New Issue
Block a user