commit
080d0f97f2
@ -1,2 +1,5 @@
|
||||
.idea/
|
||||
*.pyc
|
||||
venv/
|
||||
v-data/
|
||||
database.sqlite3
|
||||
|
@ -0,0 +1,9 @@
|
||||
from redbot.core.bot import Red
|
||||
|
||||
from .announcedaily import AnnounceDaily
|
||||
|
||||
|
||||
def setup(bot: Red):
|
||||
daily = AnnounceDaily(bot)
|
||||
bot.add_cog(daily)
|
||||
bot.loop.create_task(daily.check_day())
|
@ -0,0 +1,250 @@
|
||||
import asyncio
|
||||
import random
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
import discord
|
||||
from redbot.core import Config, checks, commands
|
||||
from redbot.core.bot import Red
|
||||
from redbot.core.data_manager import cog_data_path
|
||||
from redbot.core.utils.chat_formatting import pagify, box
|
||||
|
||||
DEFAULT_MESSAGES = [
|
||||
# "Example message. Uncomment and overwrite to use",
|
||||
# "Example message 2. Each message is in quotes and separated by a comma"
|
||||
]
|
||||
|
||||
|
||||
class AnnounceDaily:
|
||||
"""
|
||||
Send daily announcements
|
||||
"""
|
||||
|
||||
def __init__(self, bot: Red):
|
||||
self.bot = bot
|
||||
self.path = str(cog_data_path(self)).replace('\\', '/')
|
||||
|
||||
self.image_path = self.path + "/"
|
||||
|
||||
self.config = Config.get_conf(self, identifier=9811198108111121, force_registration=True)
|
||||
default_global = {
|
||||
'messages': [],
|
||||
'images': [],
|
||||
'time': {'hour': 0, 'minute': 0, 'second': 0}
|
||||
}
|
||||
default_guild = {
|
||||
"channelid": None
|
||||
}
|
||||
|
||||
self.config.register_global(**default_global)
|
||||
self.config.register_guild(**default_guild)
|
||||
|
||||
async def _get_msgs(self):
|
||||
return DEFAULT_MESSAGES + await self.config.messages()
|
||||
|
||||
@commands.group(name="announcedaily", aliases=['annd'])
|
||||
@checks.mod_or_permissions(administrator=True)
|
||||
@commands.guild_only()
|
||||
async def _ad(self, ctx: commands.Context):
|
||||
"""
|
||||
Base command for managing AnnounceDaily settings
|
||||
|
||||
Do `[p]help annd <subcommand>` for more details
|
||||
"""
|
||||
if ctx.invoked_subcommand is None:
|
||||
pass
|
||||
|
||||
@commands.command()
|
||||
@checks.guildowner()
|
||||
@commands.guild_only()
|
||||
async def runannounce(self, ctx: commands.Context):
|
||||
"""Manually run the daily announcement"""
|
||||
|
||||
await self.send_announcements()
|
||||
await ctx.send("Success")
|
||||
|
||||
@_ad.command()
|
||||
async def setchannel(self, ctx: commands.Context, channel: discord.TextChannel = None):
|
||||
"""
|
||||
Set the announcement channel for this server
|
||||
|
||||
Don't pass a channel to clear this server of receiving announcements
|
||||
"""
|
||||
if channel is not None:
|
||||
await self.config.guild(ctx.guild).channelid.set(channel.id)
|
||||
await ctx.send("Announcement channel has been set to {}".format(channel.mention))
|
||||
else:
|
||||
await self.config.guild(ctx.guild).channelid.set(None)
|
||||
await ctx.send("Announcement channel has been cleared")
|
||||
|
||||
@_ad.command()
|
||||
async def addmsg(self, ctx: commands.Context, *, msg):
|
||||
"""
|
||||
Add a message to the pool of announcement messages
|
||||
"""
|
||||
async with self.config.messages() as msgs:
|
||||
msgs.append(msg)
|
||||
|
||||
await ctx.send("Message successfully added!")
|
||||
|
||||
@_ad.command()
|
||||
async def addimg(self, ctx: commands.Context, filename=None):
|
||||
"""
|
||||
Add an image to the pool of announcement images
|
||||
|
||||
You must attach an image while executing this command
|
||||
"""
|
||||
if ctx.message.attachments:
|
||||
att_ = ctx.message.attachments[0]
|
||||
try:
|
||||
h = att_.height
|
||||
except AttributeError:
|
||||
await ctx.send("You must attach an image, no other file will be accepted")
|
||||
return
|
||||
|
||||
if filename is None:
|
||||
filename = att_.filename
|
||||
|
||||
try:
|
||||
# with open(self.image_path + filename, 'w') as f:
|
||||
# await att_.save(f)
|
||||
await att_.save(self.image_path + filename)
|
||||
except discord.NotFound:
|
||||
await ctx.send("Did you delete the message? Cause I couldn't download the attachment")
|
||||
except discord.HTTPException:
|
||||
await ctx.send("Failed to download the attachment, please try again")
|
||||
else:
|
||||
async with self.config.images() as images:
|
||||
if filename in images:
|
||||
await ctx.send("Image {} has been overwritten!".format(filename))
|
||||
else:
|
||||
images.append(filename)
|
||||
await ctx.send("Image {} has been added!".format(filename))
|
||||
else:
|
||||
await ctx.send("You must attach an image when sending this command")
|
||||
|
||||
@_ad.command()
|
||||
async def listmsg(self, ctx: commands.Context):
|
||||
"""
|
||||
List all registered announcement messages
|
||||
"""
|
||||
messages = await self.config.messages()
|
||||
for page in pagify("\n".join("{} - {}".format(key, image) for key, image in enumerate(messages))):
|
||||
await ctx.send(box(page))
|
||||
await ctx.send("Done!")
|
||||
|
||||
@_ad.command()
|
||||
async def listimg(self, ctx: commands.Context):
|
||||
"""
|
||||
List all registered announcement immages
|
||||
"""
|
||||
images = await self.config.images()
|
||||
for page in pagify("\n".join(images)):
|
||||
await ctx.send(box(page))
|
||||
await ctx.send("Done!")
|
||||
|
||||
@_ad.command()
|
||||
async def delmsg(self, ctx: commands.Context, index: int):
|
||||
"""
|
||||
Remove a message from the announcement pool
|
||||
|
||||
Must provide the index of the message, which can be found by using `[p]annd listmsg`
|
||||
"""
|
||||
async with self.config.messages() as messages:
|
||||
try:
|
||||
out = messages.pop(index)
|
||||
except IndexError:
|
||||
await ctx.send("Invalid index, check valid indexes with `listmsg` command")
|
||||
return
|
||||
|
||||
await ctx.send("The following message was removed:\n```{}```".format(out))
|
||||
|
||||
@_ad.command()
|
||||
async def delimg(self, ctx: commands.Context, filename: str):
|
||||
"""
|
||||
Remove an image from the announcement pool
|
||||
|
||||
Does not delete the file from the disk, so you may have to clean it up occasionally
|
||||
"""
|
||||
async with self.config.images() as images:
|
||||
if filename not in images:
|
||||
await ctx.send("This file doesn't exist")
|
||||
else:
|
||||
images.remove(filename)
|
||||
await ctx.send("Successfully removed {}".format(filename))
|
||||
|
||||
@_ad.command()
|
||||
async def settime(self, ctx: commands.Context, minutes_from_now: int):
|
||||
"""
|
||||
Set the daily announcement time
|
||||
|
||||
It will first announce at the time you provided, then it will repeat every 24 hours
|
||||
"""
|
||||
ann_time = datetime.now() + timedelta(minutes=minutes_from_now)
|
||||
|
||||
h = ann_time.hour
|
||||
m = ann_time.minute
|
||||
s = ann_time.second
|
||||
await self.config.time.set({'hour': h, 'minute': m, 'second': s})
|
||||
|
||||
await ctx.send("Announcements time has been set to {}::{}::{} every day\n"
|
||||
"**Changes will apply after next scheduled announcement or reload**".format(h, m, s))
|
||||
|
||||
async def send_announcements(self):
|
||||
messages = await self._get_msgs()
|
||||
images = await self.config.images()
|
||||
|
||||
total = len(messages) + len(images)
|
||||
if total < 1:
|
||||
return
|
||||
|
||||
x = random.randint(0, total - 1)
|
||||
|
||||
if x >= len(messages):
|
||||
x -= len(messages)
|
||||
choice = images[x]
|
||||
choice = open(self.image_path + choice, 'rb')
|
||||
is_image = True
|
||||
else:
|
||||
choice = messages[x]
|
||||
is_image = False
|
||||
|
||||
for guild in self.bot.guilds:
|
||||
channel = await self.config.guild(guild).channelid()
|
||||
if channel is None:
|
||||
continue
|
||||
channel = guild.get_channel(channel)
|
||||
if channel is None:
|
||||
continue
|
||||
|
||||
if is_image:
|
||||
await channel.send(file=discord.File(choice))
|
||||
else:
|
||||
await channel.send(choice)
|
||||
|
||||
async def check_day(self):
|
||||
while self is self.bot.get_cog("AnnounceDaily"):
|
||||
tomorrow = datetime.now() + timedelta(days=1)
|
||||
time = await self.config.time()
|
||||
h, m, s = time['hour'], time['minute'], time['second']
|
||||
midnight = datetime(year=tomorrow.year, month=tomorrow.month,
|
||||
day=tomorrow.day, hour=h, minute=m, second=s)
|
||||
|
||||
print("Sleeping for {} seconds".format((midnight - datetime.now()).seconds))
|
||||
await asyncio.sleep((midnight - datetime.now()).seconds)
|
||||
|
||||
if self is not self.bot.get_cog("AnnounceDaily"):
|
||||
print("Announce canceled, cog has been lost")
|
||||
return
|
||||
|
||||
await self.send_announcements()
|
||||
|
||||
await asyncio.sleep(3)
|
||||
|
||||
# [p]setchannel #channelname - Set the announcement channel per server
|
||||
# [p]addmsg <message goes here> - Adds a msg to the pool
|
||||
# [p]addimg http://imgurl.com/image.jpg - Adds an image to the pool
|
||||
# [p]listmsg - Lists all messages in the pool
|
||||
# [p]listimg - Unsure about this one, but would probably just post all the images
|
||||
# [p]delmsg - Remove msg from pool
|
||||
# [p]delimg - Remove image from pool
|
||||
# [p]settime <x> - S
|
@ -0,0 +1,18 @@
|
||||
{
|
||||
"author": [
|
||||
"Bobloy"
|
||||
],
|
||||
"bot_version": [
|
||||
3,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"description": "Send daily announcements to all servers at a specified times",
|
||||
"hidden": true,
|
||||
"install_msg": "Thank you for installing AnnounceDaily! Get started with `[p]help AnnounceDaily`",
|
||||
"requirements": [],
|
||||
"short": "Send daily announcements",
|
||||
"tags": [
|
||||
"bobloy"
|
||||
]
|
||||
}
|
@ -1,10 +1,22 @@
|
||||
{
|
||||
"author" : ["Bobloy"],
|
||||
"bot_version" : [3,0,0],
|
||||
"description" : "[Incomplete] Creates custom commands to adjust roles and send custom messages",
|
||||
"hidden" : false,
|
||||
"install_msg" : "Thank you for installing Custom Commands w/ Roles.",
|
||||
"requirements" : [],
|
||||
"short" : "[Incomplete] Creates commands that adjust roles",
|
||||
"tags" : ["fox", "bobloy", "utility", "tools", "roles"]
|
||||
"author": [
|
||||
"Bobloy"
|
||||
],
|
||||
"bot_version": [
|
||||
3,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"description": "[Incomplete] Creates custom commands to adjust roles and send custom messages",
|
||||
"hidden": false,
|
||||
"install_msg": "Thank you for installing Custom Commands w/ Roles.",
|
||||
"requirements": [],
|
||||
"short": "[Incomplete] Creates commands that adjust roles",
|
||||
"tags": [
|
||||
"fox",
|
||||
"bobloy",
|
||||
"utility",
|
||||
"tools",
|
||||
"roles"
|
||||
]
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
from .flag import Flag
|
||||
|
||||
|
||||
def setup(bot):
|
||||
bot.add_cog(Flag(bot))
|
@ -0,0 +1,184 @@
|
||||
from datetime import date, timedelta
|
||||
|
||||
import discord
|
||||
from redbot.core import Config, checks, commands
|
||||
from redbot.core.bot import Red
|
||||
from redbot.core.utils.chat_formatting import pagify
|
||||
|
||||
|
||||
class Flag:
|
||||
"""
|
||||
Set expiring flags on members
|
||||
"""
|
||||
|
||||
def __init__(self, bot: Red):
|
||||
self.bot = bot
|
||||
self.config = Config.get_conf(self, identifier=9811198108111121, force_registration=True)
|
||||
default_global = {}
|
||||
default_guild = {
|
||||
"days": 31,
|
||||
"dm": True,
|
||||
"flags": {}
|
||||
}
|
||||
|
||||
self.config.register_global(**default_global)
|
||||
self.config.register_guild(**default_guild)
|
||||
|
||||
@checks.is_owner()
|
||||
@commands.command()
|
||||
async def clearallflag(self, ctx: commands.Context):
|
||||
"""Clears all flags for all members in this server"""
|
||||
|
||||
await self.config.guild(ctx.guild).flags.clear()
|
||||
await ctx.send("Done")
|
||||
|
||||
@checks.mod_or_permissions(manage_roles=True)
|
||||
@commands.guild_only()
|
||||
@commands.group()
|
||||
async def flagset(self, ctx: commands.Context):
|
||||
"""
|
||||
My custom cog
|
||||
|
||||
Extra information goes here
|
||||
"""
|
||||
if ctx.invoked_subcommand is None:
|
||||
pass
|
||||
|
||||
@flagset.command(name="expire")
|
||||
async def flagset_expire(self, ctx: commands.Context, days: int):
|
||||
"""
|
||||
Set the number of days for flags to expire after for server
|
||||
"""
|
||||
await self.config.guild(ctx.guild).days.set(days)
|
||||
await ctx.send("Number of days for new flags to expire is now {} days".format(days))
|
||||
|
||||
@flagset.command(name="dm")
|
||||
async def flagset_dm(self, ctx: commands.Context):
|
||||
"""Toggles DM-ing the flags"""
|
||||
|
||||
dm = await self.config.guild(ctx.guild).dm()
|
||||
await self.config.guild(ctx.guild).dm.set(not dm)
|
||||
|
||||
await ctx.send("DM-ing members when they get a flag is now set to **{}**".format(not dm))
|
||||
|
||||
@staticmethod
|
||||
def _flag_template():
|
||||
return {
|
||||
'reason': "",
|
||||
'expireyear': 0,
|
||||
'expiremonth': 0,
|
||||
'expireday': 0
|
||||
}
|
||||
|
||||
# ************************Flag command group start************************
|
||||
@checks.mod_or_permissions(manage_roles=True)
|
||||
@commands.command()
|
||||
async def flag(self, ctx: commands.Context, member: discord.Member, *, reason):
|
||||
"""Flag a member"""
|
||||
guild = ctx.guild
|
||||
await self._check_flags(guild)
|
||||
# clashroyale = self.bot.get_cog('clashroyale')
|
||||
# if clashroyale is None:
|
||||
# await ctx.send("Requires clashroyale cog installed")
|
||||
# return
|
||||
|
||||
flag = self._flag_template()
|
||||
expiredate = date.today()
|
||||
expiredate += timedelta(days=await self.config.guild(guild).days())
|
||||
|
||||
flag['reason'] = reason
|
||||
flag['expireyear'] = expiredate.year
|
||||
flag['expiremonth'] = expiredate.month
|
||||
flag['expireday'] = expiredate.day
|
||||
|
||||
# flags = await self.config.guild(guild).flags.get_raw(str(member.id), default=[])
|
||||
# flags.append(flag)
|
||||
# await self.config.guild(guild).flags.set_raw(str(member.id), value=flags)
|
||||
|
||||
async with self.config.guild(guild).flags() as flags:
|
||||
flags[str(member.id)].append(flag)
|
||||
|
||||
outembed = await self._list_flags(member)
|
||||
|
||||
if outembed:
|
||||
await ctx.send(embed=outembed)
|
||||
if await self.config.guild(guild).dm():
|
||||
await member.send(embed=outembed)
|
||||
else:
|
||||
await ctx.send("This member has no flags.. somehow..")
|
||||
|
||||
@checks.mod_or_permissions(manage_roles=True)
|
||||
@commands.command(pass_context=True, no_pm=True, aliases=['flagclear'])
|
||||
async def clearflag(self, ctx: commands.Context, member: discord.Member):
|
||||
"""Clears flags for a member"""
|
||||
guild = ctx.guild
|
||||
await self._check_flags(guild)
|
||||
|
||||
await self.config.guild(guild).flags.set_raw(str(member.id), value=[])
|
||||
|
||||
await ctx.send("Success!")
|
||||
|
||||
@commands.command(pass_context=True, no_pm=True, aliases=['flaglist'])
|
||||
async def listflag(self, ctx: commands.Context, member: discord.Member):
|
||||
"""Lists flags for a member"""
|
||||
server = ctx.guild
|
||||
await self._check_flags(server)
|
||||
|
||||
outembed = await self._list_flags(member)
|
||||
|
||||
if outembed:
|
||||
await ctx.send(embed=outembed)
|
||||
else:
|
||||
await ctx.send("This member has no flags!")
|
||||
|
||||
@commands.command(pass_context=True, no_pm=True, aliases=['flagall'])
|
||||
async def allflag(self, ctx: commands.Context):
|
||||
"""Lists all flags for the server"""
|
||||
guild = ctx.guild
|
||||
await self._check_flags(guild)
|
||||
out = "All flags for {}\n".format(ctx.guild.name)
|
||||
|
||||
flags = await self.config.guild(guild).flags()
|
||||
flag_d = {}
|
||||
for memberid, flag_data in flags.items():
|
||||
if len(flag_data) > 0:
|
||||
member = guild.get_member(int(memberid))
|
||||
flag_d[member.display_name + member.discriminator] = len(flag_data)
|
||||
|
||||
for display_name, flag_count in sorted(flag_d.items()):
|
||||
out += "{} - **{}** flags".format(display_name, flag_count)
|
||||
|
||||
for page in pagify(out):
|
||||
await ctx.send(page)
|
||||
|
||||
async def _list_flags(self, member: discord.Member):
|
||||
"""Returns a pretty embed of flags on a member"""
|
||||
flags = await self.config.guild(member.guild).flags.get_raw(str(member.id), default=[])
|
||||
|
||||
embed = discord.Embed(title="Flags for " + member.display_name,
|
||||
description="User has {} active flags".format(len(flags)), color=0x804040)
|
||||
for flag in flags:
|
||||
embed.add_field(name="Reason: " + flag['reason'],
|
||||
value="Expires on " + str(date(flag['expireyear'], flag['expiremonth'], flag['expireday'])),
|
||||
inline=True)
|
||||
|
||||
embed.set_thumbnail(url=member.avatar_url)
|
||||
|
||||
return embed
|
||||
|
||||
async def _check_flags(self, guild: discord.Guild):
|
||||
"""Updates and removes expired flags"""
|
||||
flag_data = await self.config.guild(guild).flags()
|
||||
flag_d = {}
|
||||
for memberid, flags in flag_data.items():
|
||||
# for member in guild.members:
|
||||
# flags = await self.config.guild(guild).flags.get_raw(str(member.id), default=[])
|
||||
x = 0
|
||||
while x < len(flags):
|
||||
flag = flags[x]
|
||||
if date.today() >= date(flag['expireyear'], flag['expiremonth'], flag['expireday']):
|
||||
del flags[x]
|
||||
else:
|
||||
x += 1
|
||||
|
||||
await self.config.guild(guild).flags.set_raw(memberid, value=flags)
|
@ -0,0 +1,23 @@
|
||||
{
|
||||
"author": [
|
||||
"Bobloy"
|
||||
],
|
||||
"bot_version": [
|
||||
3,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"description": "Add expiring flags on members to track warnings or incidents",
|
||||
"hidden": true,
|
||||
"install_msg": "Thank you for installing Flag! Get started with `[p]help Flag`",
|
||||
"requirements": [],
|
||||
"short": "Add expiring flags to members",
|
||||
"tags": [
|
||||
"bobloy",
|
||||
"warning",
|
||||
"warn",
|
||||
"temp",
|
||||
"tools",
|
||||
"warning"
|
||||
]
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
from .leaver import Leaver
|
||||
|
||||
|
||||
def setup(bot):
|
||||
bot.add_cog(Leaver(bot))
|
@ -1,9 +1,20 @@
|
||||
{
|
||||
"AUTHOR": "Bobloy",
|
||||
"INSTALL_MSG": "Thank you for installing leaver",
|
||||
"NAME": "Leaver",
|
||||
"SHORT": "Sends message on leave",
|
||||
"DESCRIPTION": "Keeps track of when people leave the server, and posts a message notifying",
|
||||
"TAGS": ["fox", "bobloy", "utilities", "tools", "tool"],
|
||||
"HIDDEN": false
|
||||
"author": [
|
||||
"Bobloy"
|
||||
],
|
||||
"bot_version": [
|
||||
3,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"description": "Keeps track of when people leave the server, and posts a message notifying",
|
||||
"hidden": false,
|
||||
"install_msg": "Thank you for installing Leaver. Get started with `[p]help Leaver`",
|
||||
"requirements": [],
|
||||
"short": "Send message on leave",
|
||||
"tags": [
|
||||
"bobloy",
|
||||
"utils",
|
||||
"tools"
|
||||
]
|
||||
}
|
@ -1,78 +1,42 @@
|
||||
import discord
|
||||
import os
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
from .utils.dataIO import dataIO
|
||||
from .utils import checks
|
||||
from redbot.core import Config, checks, commands
|
||||
from redbot.core.commands import Context
|
||||
|
||||
|
||||
class Leaver:
|
||||
"""Creates a goodbye message when people leave"""
|
||||
"""
|
||||
Creates a goodbye message when people leave
|
||||
"""
|
||||
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
self.path = "data/Fox-Cogs/leaver"
|
||||
self.file_path = "data/Fox-Cogs/leaver/leaver.json"
|
||||
self.the_data = dataIO.load_json(self.file_path)
|
||||
self.config = Config.get_conf(self, identifier=9811198108111121, force_registration=True)
|
||||
default_guild = {
|
||||
"channel": ''
|
||||
}
|
||||
|
||||
def save_data(self):
|
||||
"""Saves the json"""
|
||||
dataIO.save_json(self.file_path, self.the_data)
|
||||
self.config.register_guild(**default_guild)
|
||||
|
||||
@commands.group(aliases=['setleaver'], pass_context=True, no_pm=True)
|
||||
@commands.group(aliases=['setleaver'])
|
||||
@checks.mod_or_permissions(administrator=True)
|
||||
async def leaverset(self, ctx):
|
||||
"""Adjust leaver settings"""
|
||||
|
||||
server = ctx.message.server
|
||||
if server.id not in self.the_data:
|
||||
self.the_data[server.id] = {}
|
||||
self.save_data()
|
||||
|
||||
|
||||
if ctx.invoked_subcommand is None:
|
||||
await self.bot.send_cmd_help(ctx)
|
||||
pass
|
||||
|
||||
@leaverset.command(pass_context=True, no_pm=True)
|
||||
async def channel(self, ctx):
|
||||
server = ctx.message.server
|
||||
if 'CHANNEL' not in self.the_data[server.id]:
|
||||
self.the_data[server.id]['CHANNEL'] = ''
|
||||
@leaverset.command()
|
||||
async def channel(self, ctx: Context):
|
||||
guild = ctx.guild
|
||||
await self.config.guild(guild).channel.set(ctx.channel.id)
|
||||
await ctx.send("Channel set to " + ctx.channel.name)
|
||||
|
||||
async def on_member_remove(self, member: discord.Member):
|
||||
guild = member.guild
|
||||
channel = await self.config.guild(guild).channel()
|
||||
|
||||
self.the_data[server.id]['CHANNEL'] = ctx.message.channel.id
|
||||
self.save_data()
|
||||
await self.bot.say("Channel set to "+ctx.message.channel.name)
|
||||
|
||||
async def when_leave(self, member):
|
||||
server = member.server
|
||||
if server.id in self.the_data:
|
||||
await self.bot.send_message(server.get_channel(self.the_data[server.id]['CHANNEL']),
|
||||
str(member) + "(*" + str(member.nick) +"*) has left the server!")
|
||||
if channel != '':
|
||||
channel = guild.get_channel(channel)
|
||||
await channel.send(str(member) + "(*" + str(member.nick) + "*) has left the server!")
|
||||
else:
|
||||
await self.bot.send_message(server.default_channel.id, str(member) + " (*" + str(member.nick) +"*) has left the server!")
|
||||
|
||||
|
||||
def check_folders():
|
||||
if not os.path.exists("data/Fox-Cogs"):
|
||||
print("Creating data/Fox-Cogs folder...")
|
||||
os.makedirs("data/Fox-Cogs")
|
||||
|
||||
if not os.path.exists("data/Fox-Cogs/leaver"):
|
||||
print("Creating data/Fox-Cogs/leaver folder...")
|
||||
os.makedirs("data/Fox-Cogs/leaver")
|
||||
|
||||
|
||||
def check_files():
|
||||
if not dataIO.is_valid_json("data/Fox-Cogs/leaver/leaver.json"):
|
||||
dataIO.save_json("data/Fox-Cogs/leaver/leaver.json", {})
|
||||
|
||||
|
||||
def setup(bot):
|
||||
check_folders()
|
||||
check_files()
|
||||
q = Leaver(bot)
|
||||
bot.add_listener(q.when_leave, "on_member_remove")
|
||||
bot.add_cog(q)
|
||||
|
||||
pass
|
||||
|
@ -0,0 +1,5 @@
|
||||
from .nudity import Nudity
|
||||
|
||||
|
||||
def setup(bot):
|
||||
bot.add_cog(Nudity(bot))
|
@ -0,0 +1,20 @@
|
||||
{
|
||||
"author": [
|
||||
"Bobloy"
|
||||
],
|
||||
"bot_version": [
|
||||
3,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"description": "Keep track of when users were last seen online",
|
||||
"hidden": true,
|
||||
"install_msg": "Thank you for installing LastSeen. Get started with `[p]help LastSeen`",
|
||||
"requirements": ["nudepy"],
|
||||
"short": "Last seen tracker",
|
||||
"tags": [
|
||||
"bobloy",
|
||||
"utils",
|
||||
"tools"
|
||||
]
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
from datetime import datetime
|
||||
|
||||
import discord
|
||||
import nude
|
||||
from nude import Nude
|
||||
from redbot.core import Config
|
||||
from redbot.core import commands
|
||||
from redbot.core.bot import Red
|
||||
|
||||
|
||||
class Nudity:
|
||||
"""
|
||||
V3 Cog Template
|
||||
"""
|
||||
|
||||
online_status = discord.Status.online
|
||||
|
||||
offline_status = discord.Status.offline
|
||||
|
||||
def __init__(self, bot: Red):
|
||||
self.bot = bot
|
||||
self.config = Config.get_conf(self, identifier=9811198108111121, force_registration=True)
|
||||
|
||||
default_guild = {
|
||||
"enabled": False
|
||||
}
|
||||
|
||||
self.config.register_guild(**default_guild)
|
||||
|
||||
@commands.command(aliases=['togglenudity'], name='nudity')
|
||||
async def nudity(self, ctx: commands.Context):
|
||||
"""Toggle nude-checking on or off"""
|
||||
is_on = await self.config.guild(ctx.guild).enabled()
|
||||
await self.config.guild(ctx.guild).enabled.set(not is_on)
|
||||
await ctx.send("Nude checking is now set to {}".format(not is_on))
|
||||
|
||||
async def on_message(self, message: discord.Message):
|
||||
is_on = await self.config.guild(message.guild).enabled()
|
||||
if not is_on:
|
||||
return
|
||||
|
||||
if not message.attachments:
|
||||
return
|
||||
|
||||
|
@ -0,0 +1,5 @@
|
||||
from .qrinvite import QRInvite
|
||||
|
||||
|
||||
def setup(bot):
|
||||
bot.add_cog(QRInvite(bot))
|
@ -0,0 +1,23 @@
|
||||
{
|
||||
"author": [
|
||||
"Bobloy"
|
||||
],
|
||||
"bot_version": [
|
||||
3,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"description": "Create a QR code invite for the server",
|
||||
"hidden": true,
|
||||
"install_msg": "Thank you for installing QRInvite! Get started with `[p]help QRInvite`",
|
||||
"requirements": [
|
||||
"MyQR"
|
||||
],
|
||||
"short": "Create a QR code invite",
|
||||
"tags": [
|
||||
"bobloy",
|
||||
"tools",
|
||||
"qr",
|
||||
"code"
|
||||
]
|
||||
}
|
@ -0,0 +1,81 @@
|
||||
import pathlib
|
||||
|
||||
import aiohttp
|
||||
import discord
|
||||
from PIL import Image
|
||||
|
||||
from redbot.core import Config, checks, commands
|
||||
|
||||
from redbot.core.bot import Red
|
||||
|
||||
from MyQR import myqr
|
||||
from redbot.core.data_manager import cog_data_path
|
||||
|
||||
|
||||
class QRInvite:
|
||||
"""
|
||||
V3 Cog Template
|
||||
"""
|
||||
|
||||
def __init__(self, bot: Red):
|
||||
self.bot = bot
|
||||
self.config = Config.get_conf(self, identifier=9811198108111121, force_registration=True)
|
||||
default_global = {}
|
||||
default_guild = {}
|
||||
|
||||
self.config.register_global(**default_global)
|
||||
self.config.register_guild(**default_guild)
|
||||
|
||||
@commands.command()
|
||||
async def qrinvite(self, ctx: commands.Context, invite: str=None, colorized: bool=False, image_url: str=None):
|
||||
"""
|
||||
Create a custom QR code invite for this server
|
||||
"""
|
||||
if invite is None:
|
||||
try:
|
||||
invite = await ctx.channel.create_invite()
|
||||
except discord.Forbidden:
|
||||
try:
|
||||
invite = await ctx.channel.invites()
|
||||
invite = invite[0]
|
||||
except discord.Forbidden:
|
||||
await ctx.send("No permission to get an invite, please provide one")
|
||||
return
|
||||
invite = invite.code
|
||||
|
||||
if image_url is None:
|
||||
image_url = ctx.guild.icon_url
|
||||
|
||||
extension = pathlib.Path(image_url).parts[-1].replace('.','?').split('?')[1]
|
||||
|
||||
path: pathlib.Path = cog_data_path(self)
|
||||
image_path = path / (ctx.guild.icon+"."+extension)
|
||||
async with aiohttp.ClientSession() as session:
|
||||
async with session.get(image_url) as response:
|
||||
image = await response.read()
|
||||
|
||||
with image_path.open("wb") as file:
|
||||
file.write(image)
|
||||
|
||||
if extension == "webp":
|
||||
new_path = convert_png(str(image_path))
|
||||
else:
|
||||
new_path = str(image_path)
|
||||
|
||||
myqr.run(invite,picture=new_path,save_name=ctx.guild.icon+"_qrcode.png",
|
||||
save_dir=str(cog_data_path(self)),colorized=colorized,)
|
||||
|
||||
png_path: pathlib.Path = path / (ctx.guild.icon+"_qrcode.png")
|
||||
with png_path.open("rb") as png_fp:
|
||||
await ctx.send(file=discord.File(png_fp.read(), "qrcode.png"))
|
||||
|
||||
def convert_png(path):
|
||||
im = Image.open(path)
|
||||
im.load()
|
||||
alpha = im.split()[-1]
|
||||
im = im.convert('RGB').convert('P', palette=Image.ADAPTIVE, colors=255)
|
||||
mask = Image.eval(alpha, lambda a: 255 if a <=128 else 0)
|
||||
im.paste(255, mask)
|
||||
newPath = path.replace(".webp",".png")
|
||||
im.save(newPath, transparency=255)
|
||||
return newPath
|
@ -0,0 +1,5 @@
|
||||
from .tts import TTS
|
||||
|
||||
|
||||
def setup(bot):
|
||||
bot.add_cog(TTS(bot))
|
@ -0,0 +1,22 @@
|
||||
{
|
||||
"author": [
|
||||
"Bobloy"
|
||||
],
|
||||
"bot_version": [
|
||||
3,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"description": "Send Text2Speech messages as an uploaded mp3",
|
||||
"hidden": true,
|
||||
"install_msg": "Thank you for installing TTS. Get started with `[p]tts`",
|
||||
"requirements": [
|
||||
"gTTS"
|
||||
],
|
||||
"short": "Send TTS messages as uploaded mp3",
|
||||
"tags": [
|
||||
"bobloy",
|
||||
"utils",
|
||||
"audio"
|
||||
]
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
import io
|
||||
|
||||
import discord
|
||||
from gtts import gTTS
|
||||
from redbot.core import Config, commands
|
||||
from redbot.core.bot import Red
|
||||
|
||||
|
||||
class TTS:
|
||||
"""
|
||||
V3 Cog Template
|
||||
"""
|
||||
|
||||
def __init__(self, bot: Red):
|
||||
self.bot = bot
|
||||
|
||||
self.config = Config.get_conf(self, identifier=9811198108111121, force_registration=True)
|
||||
default_global = {}
|
||||
default_guild = {}
|
||||
|
||||
self.config.register_global(**default_global)
|
||||
self.config.register_guild(**default_guild)
|
||||
|
||||
@commands.command(aliases=["t2s", "text2"])
|
||||
async def tts(self, ctx: commands.Context, *, text: str):
|
||||
"""
|
||||
My custom cog
|
||||
|
||||
Extra information goes here
|
||||
"""
|
||||
mp3_fp = io.BytesIO()
|
||||
tts = gTTS(text, 'en')
|
||||
tts.write_to_fp(mp3_fp)
|
||||
await ctx.send(file=discord.File(mp3_fp.getvalue(), "text.mp3"))
|
Loading…
Reference in new issue