Merge branch 'master' into announcedaily-develop

pull/19/head
Bobloy 7 years ago
commit 70e2e86efd

@ -9,7 +9,7 @@ Cog Function
| chatter | **Alpha** | <details><summary>Chat-bot trained to talk like your guild</summary>Missing some key features, but currently functional</details> |
| coglint | **Alpha** | <details><summary>Error check code in python syntax posted to discord</summary>Works, but probably needs more turning to work for cogs</details> |
| fight | **Incomplete** | <details><summary>Organize bracket tournaments within discord</summary>Still in-progress, a massive project</details> |
| flag | **Incomplete** | <details><summary>Create temporary marks on users that expire after specified time</summary>Not yet ported to v3</details> |
| flag | **Alpha** | <details><summary>Create temporary marks on users that expire after specified time</summary>Ported, will not import old data. Please report bugs</details> |
| forcemention | **Alpha** | <details><summary>Mentions unmentionable roles</summary>Very simple cog, mention doesn't persist</details> |
| hangman | **Alpha** | <details><summary>Play a game of hangman</summary>Some visual glitches and needs more customization</details> |
| howdoi | **Incomplete** | <details><summary>Create temporary marks on users that expire after specified time</summary>Not yet ported to v3</details> |

@ -2,7 +2,6 @@ import asyncio
import re
import discord
from redbot.core import Config, checks
from redbot.core import commands
from redbot.core.utils.chat_formatting import pagify, box
@ -106,7 +105,7 @@ class CCRole:
return
# Selfrole
await ctx.send('Is this a targeted command?(yes/no)\nNo will make this a selfrole command')
await ctx.send('Is this a targeted command?(yes//no)\nNo will make this a selfrole command')
try:
answer = await self.bot.wait_for('message', timeout=120, check=check)
@ -191,7 +190,7 @@ class CCRole:
"""Shows custom commands list"""
guild = ctx.guild
cmd_list = await self.config.guild(guild).cmdlist()
cmd_list = {k: v for k,v in cmd_list.items() if v}
cmd_list = {k: v for k, v in cmd_list.items() if v}
if not cmd_list:
await ctx.send(
"There are no custom commands in this server. Use `{}ccrole add` to start adding some.".format(

@ -2,7 +2,6 @@ import asyncio
from datetime import datetime, timedelta
import discord
from redbot.core import Config
from redbot.core import commands
@ -10,7 +9,6 @@ from chatter.chatterbot import ChatBot
from chatter.chatterbot.trainers import ListTrainer
class Chatter:
"""
This cog trains a chatbot that will talk like members of your Guild
@ -99,7 +97,8 @@ class Chatter:
Backup your training data to a json for later use
"""
await ctx.send("Backing up data, this may take a while")
future = await self.loop.run_in_executor(None, self.chatbot.trainer.export_for_training, './{}.json'.format(backupname))
future = await self.loop.run_in_executor(None, self.chatbot.trainer.export_for_training,
'./{}.json'.format(backupname))
if future:
await ctx.send("Backup successful!")
@ -142,7 +141,6 @@ class Chatter:
author = message.author
channel = message.channel
if message.author.id != self.bot.user.id:
to_strip = "@" + author.guild.me.display_name + " "
text = message.clean_content

@ -158,7 +158,9 @@ class StorageAdapter(object):
class EmptyDatabaseException(Exception):
def __init__(self,
value='The database currently contains no entries. At least one entry is expected. You may need to train your chat bot to populate your database.'):
value='The database currently contains no entries. '
'At least one entry is expected. '
'You may need to train your chat bot to populate your database.'):
self.value = value
def __str__(self):

@ -1,11 +1,8 @@
import discord
from redbot.core import Config, checks
from redbot.core.bot import Red
from pylint import epylint as lint
from redbot.core import Config
from redbot.core import commands
from redbot.core.bot import Red
from redbot.core.data_manager import cog_data_path

@ -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:
await ctx.send_help()
@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"
]
}

@ -2,10 +2,9 @@ from collections import defaultdict
from random import randint
import discord
from redbot.core import Config, checks
from redbot.core import commands
from redbot.core.data_manager import cog_data_path, load_basic_configuration
from redbot.core.data_manager import cog_data_path
class Hangman:
@ -26,7 +25,7 @@ class Hangman:
lambda: {"running": False, "hangman": 0, "guesses": [], "trackmessage": False, "answer": ''})
self.path = str(cog_data_path(self)).replace('\\', '/')
self.answer_path = self.path+"/bundled_data/hanganswers.txt"
self.answer_path = self.path + "/bundled_data/hanganswers.txt"
self.winbool = defaultdict(lambda: False)
@ -331,4 +330,3 @@ class Hangman:
await self._reactmessage_menu(message)
await self._checkdone(channel)

@ -58,8 +58,6 @@ class LastSeen:
async def lseen(self, ctx: commands.Context, member: discord.Member):
"""
Just says the time the user was last seen
:param member:
"""
if member.status != self.offline_status:

@ -1,12 +1,9 @@
import asyncio
from typing import List, Union
import discord
from redbot.core import Config
from redbot.core.bot import Red
from redbot.core import commands
from redbot.core.bot import Red
class ReactRestrictCombo:
@ -16,8 +13,8 @@ class ReactRestrictCombo:
def __eq__(self, other: "ReactRestrictCombo"):
return (
self.message_id == other.message_id and
self.role_id == other.role_id
self.message_id == other.message_id and
self.role_id == other.role_id
)
def to_json(self):
@ -83,7 +80,7 @@ class ReactRestrict:
"""
# is_custom = True
# if isinstance(emoji, str):
# is_custom = False
# is_custom = False
combo = ReactRestrictCombo(message_id, role.id)
@ -95,10 +92,10 @@ class ReactRestrict:
async def remove_react(self, message_id: int, role: discord.Role):
"""
Removes a given reaction.
Removes a given reaction
:param int message_id:
:param str or int emoji:
:param message_id:
:param role:
:return:
"""
current_combos = await self.combo_list()
@ -109,14 +106,13 @@ class ReactRestrict:
if to_keep != current_combos:
await self.set_combo_list(to_keep)
async def has_reactrestrict_combo(self, message_id: int)\
async def has_reactrestrict_combo(self, message_id: int) \
-> (bool, List[ReactRestrictCombo]):
"""
Determines if there is an existing role combo for a given message
Determines if there is an existing role combo for a given message
and emoji ID.
:param int message_id:
:param str or int emoji:
:param message_id:
:return:
"""
if not await self.is_registered(message_id):
@ -170,7 +166,7 @@ class ReactRestrict:
return role
async def _get_message_from_channel(self, channel_id: int, message_id: int)\
async def _get_message_from_channel(self, channel_id: int, message_id: int) \
-> Union[discord.Message, None]:
"""
Tries to find a message by ID in the current guild context.
@ -180,12 +176,12 @@ class ReactRestrict:
return await channel.get_message(message_id)
except discord.NotFound:
pass
except AttributeError: # VoiceChannel object has no attribute 'get_message'
except AttributeError: # VoiceChannel object has no attribute 'get_message'
pass
return None
async def _get_message(self, ctx: commands.Context, message_id: int)\
async def _get_message(self, ctx: commands.Context, message_id: int) \
-> Union[discord.Message, None]:
"""
Tries to find a message by ID in the current guild context.
@ -199,13 +195,11 @@ class ReactRestrict:
return await channel.get_message(message_id)
except discord.NotFound:
pass
except AttributeError: # VoiceChannel object has no attribute 'get_message'
except AttributeError: # VoiceChannel object has no attribute 'get_message'
pass
except discord.Forbidden: # No access to channel, skip
pass
return None
@commands.group()
@ -228,18 +222,18 @@ class ReactRestrict:
return
# try:
# emoji, actual_emoji = await self._wait_for_emoji(ctx)
# emoji, actual_emoji = await self._wait_for_emoji(ctx)
# except asyncio.TimeoutError:
# await ctx.send("You didn't respond in time, please redo this command.")
# return
# await ctx.send("You didn't respond in time, please redo this command.")
# return
#
# try:
# await message.add_reaction(actual_emoji)
# await message.add_reaction(actual_emoji)
# except discord.HTTPException:
# await ctx.send("I can't add that emoji because I'm not in the guild that"
# " owns it.")
# return
# await ctx.send("I can't add that emoji because I'm not in the guild that"
# " owns it.")
# return
#
# noinspection PyTypeChecker
await self.add_reactrestrict(message_id, role)
@ -251,10 +245,10 @@ class ReactRestrict:
Removes role associated with a given reaction.
"""
# try:
# emoji, actual_emoji = await self._wait_for_emoji(ctx)
# emoji, actual_emoji = await self._wait_for_emoji(ctx)
# except asyncio.TimeoutError:
# await ctx.send("You didn't respond in time, please redo this command.")
# return
# await ctx.send("You didn't respond in time, please redo this command.")
# return
# noinspection PyTypeChecker
await self.remove_react(message_id, role)
@ -302,46 +296,46 @@ class ReactRestrict:
message = await self._get_message_from_channel(channel_id, message_id)
await message.remove_reaction(emoji, member)
# try:
# await member.add_roles(*roles)
# except discord.Forbidden:
# pass
# try:
# await member.add_roles(*roles)
# except discord.Forbidden:
# pass
#
# async def on_raw_reaction_remove(self, emoji: discord.PartialReactionEmoji,
# message_id: int, channel_id: int, user_id: int):
# """
# Event handler for long term reaction watching.
# :param discord.PartialReactionEmoji emoji:
# :param int message_id:
# :param int channel_id:
# :param int user_id:
# :return:
# """
# if emoji.is_custom_emoji():
# emoji_id = emoji.id
# else:
# emoji_id = emoji.name
# has_reactrestrict, combos = await self.has_reactrestrict_combo(message_id, emoji_id)
# if not has_reactrestrict:
# return
# try:
# member = self._get_member(channel_id, user_id)
# except LookupError:
# return
# if member.bot:
# return
# try:
# roles = [self._get_role(member.guild, c.role_id) for c in combos]
# except LookupError:
# return
# try:
# await member.remove_roles(*roles)
# except discord.Forbidden:
# pass
# message_id: int, channel_id: int, user_id: int):
# """
# Event handler for long term reaction watching.
#
# :param discord.PartialReactionEmoji emoji:
# :param int message_id:
# :param int channel_id:
# :param int user_id:
# :return:
# """
# if emoji.is_custom_emoji():
# emoji_id = emoji.id
# else:
# emoji_id = emoji.name
#
# has_reactrestrict, combos = await self.has_reactrestrict_combo(message_id, emoji_id)
#
# if not has_reactrestrict:
# return
#
# try:
# member = self._get_member(channel_id, user_id)
# except LookupError:
# return
#
# if member.bot:
# return
#
# try:
# roles = [self._get_role(member.guild, c.role_id) for c in combos]
# except LookupError:
# return
#
# try:
# await member.remove_roles(*roles)
# except discord.Forbidden:
# pass

@ -32,8 +32,7 @@ class SayUrl:
"""
Converts a URL to something readable
:param url:
:return:
Works better on smaller websites
"""
h = html2text.HTML2Text()

@ -58,7 +58,7 @@ class StealEmoji:
async def se_bank(self, ctx):
"""Add current server as emoji bank"""
await ctx.send("This will upload custom emojis to this server\n"
"Are you sure you want to make the current server an emoji bank? (y/n)")
"Are you sure you want to make the current server an emoji bank? (y//n)")
def check(m):
return m.content.upper() in ["Y", "YES", "N", "NO"] and m.channel == ctx.channel and m.author == ctx.author

@ -120,8 +120,6 @@ async def parse_code(code, game):
digits += 1
continue
try:
idx = int(built)
except ValueError:
@ -146,7 +144,6 @@ async def parse_code(code, game):
built = ""
return decode

@ -16,7 +16,6 @@ class Seer(Role):
description = "A mystic in search of answers in a chaotic town.\n" \
"Calls upon the cosmos to discern those of Lycan blood"
def __init__(self, game):
super().__init__(game)
# self.game = game

Loading…
Cancel
Save