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> | | 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> | | 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> | | 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> | | 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> | | 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> | | 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 re
import discord import discord
from redbot.core import Config, checks from redbot.core import Config, checks
from redbot.core import commands from redbot.core import commands
from redbot.core.utils.chat_formatting import pagify, box from redbot.core.utils.chat_formatting import pagify, box
@ -106,7 +105,7 @@ class CCRole:
return return
# Selfrole # 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: try:
answer = await self.bot.wait_for('message', timeout=120, check=check) answer = await self.bot.wait_for('message', timeout=120, check=check)
@ -191,7 +190,7 @@ class CCRole:
"""Shows custom commands list""" """Shows custom commands list"""
guild = ctx.guild guild = ctx.guild
cmd_list = await self.config.guild(guild).cmdlist() 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: if not cmd_list:
await ctx.send( await ctx.send(
"There are no custom commands in this server. Use `{}ccrole add` to start adding some.".format( "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 from datetime import datetime, timedelta
import discord import discord
from redbot.core import Config from redbot.core import Config
from redbot.core import commands from redbot.core import commands
@ -10,7 +9,6 @@ from chatter.chatterbot import ChatBot
from chatter.chatterbot.trainers import ListTrainer from chatter.chatterbot.trainers import ListTrainer
class Chatter: class Chatter:
""" """
This cog trains a chatbot that will talk like members of your Guild 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 Backup your training data to a json for later use
""" """
await ctx.send("Backing up data, this may take a while") 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: if future:
await ctx.send("Backup successful!") await ctx.send("Backup successful!")
@ -142,7 +141,6 @@ class Chatter:
author = message.author author = message.author
channel = message.channel channel = message.channel
if message.author.id != self.bot.user.id: if message.author.id != self.bot.user.id:
to_strip = "@" + author.guild.me.display_name + " " to_strip = "@" + author.guild.me.display_name + " "
text = message.clean_content text = message.clean_content

@ -158,7 +158,9 @@ class StorageAdapter(object):
class EmptyDatabaseException(Exception): class EmptyDatabaseException(Exception):
def __init__(self, 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 self.value = value
def __str__(self): def __str__(self):

@ -1,11 +1,8 @@
import discord import discord
from redbot.core import Config, checks
from redbot.core.bot import Red
from pylint import epylint as lint from pylint import epylint as lint
from redbot.core import Config
from redbot.core import commands from redbot.core import commands
from redbot.core.bot import Red
from redbot.core.data_manager import cog_data_path 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 from random import randint
import discord import discord
from redbot.core import Config, checks from redbot.core import Config, checks
from redbot.core import commands 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: class Hangman:
@ -26,7 +25,7 @@ class Hangman:
lambda: {"running": False, "hangman": 0, "guesses": [], "trackmessage": False, "answer": ''}) lambda: {"running": False, "hangman": 0, "guesses": [], "trackmessage": False, "answer": ''})
self.path = str(cog_data_path(self)).replace('\\', '/') 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) self.winbool = defaultdict(lambda: False)
@ -331,4 +330,3 @@ class Hangman:
await self._reactmessage_menu(message) await self._reactmessage_menu(message)
await self._checkdone(channel) await self._checkdone(channel)

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

@ -1,12 +1,9 @@
import asyncio
from typing import List, Union from typing import List, Union
import discord import discord
from redbot.core import Config from redbot.core import Config
from redbot.core.bot import Red
from redbot.core import commands from redbot.core import commands
from redbot.core.bot import Red
class ReactRestrictCombo: class ReactRestrictCombo:
@ -95,10 +92,10 @@ class ReactRestrict:
async def remove_react(self, message_id: int, role: discord.Role): async def remove_react(self, message_id: int, role: discord.Role):
""" """
Removes a given reaction. Removes a given reaction
:param int message_id: :param message_id:
:param str or int emoji: :param role:
:return: :return:
""" """
current_combos = await self.combo_list() current_combos = await self.combo_list()
@ -109,14 +106,13 @@ class ReactRestrict:
if to_keep != current_combos: if to_keep != current_combos:
await self.set_combo_list(to_keep) 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]): -> (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. and emoji ID.
:param int message_id: :param message_id:
:param str or int emoji:
:return: :return:
""" """
if not await self.is_registered(message_id): if not await self.is_registered(message_id):
@ -170,7 +166,7 @@ class ReactRestrict:
return role 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]: -> Union[discord.Message, None]:
""" """
Tries to find a message by ID in the current guild context. Tries to find a message by ID in the current guild context.
@ -185,7 +181,7 @@ class ReactRestrict:
return None 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]: -> Union[discord.Message, None]:
""" """
Tries to find a message by ID in the current guild context. Tries to find a message by ID in the current guild context.
@ -204,8 +200,6 @@ class ReactRestrict:
except discord.Forbidden: # No access to channel, skip except discord.Forbidden: # No access to channel, skip
pass pass
return None return None
@commands.group() @commands.group()
@ -232,14 +226,14 @@ class ReactRestrict:
# except asyncio.TimeoutError: # except asyncio.TimeoutError:
# await ctx.send("You didn't respond in time, please redo this command.") # await ctx.send("You didn't respond in time, please redo this command.")
# return # return
#
# try: # try:
# await message.add_reaction(actual_emoji) # await message.add_reaction(actual_emoji)
# except discord.HTTPException: # except discord.HTTPException:
# await ctx.send("I can't add that emoji because I'm not in the guild that" # await ctx.send("I can't add that emoji because I'm not in the guild that"
# " owns it.") # " owns it.")
# return # return
#
# noinspection PyTypeChecker # noinspection PyTypeChecker
await self.add_reactrestrict(message_id, role) await self.add_reactrestrict(message_id, role)
@ -306,12 +300,12 @@ class ReactRestrict:
# await member.add_roles(*roles) # await member.add_roles(*roles)
# except discord.Forbidden: # except discord.Forbidden:
# pass # pass
#
# async def on_raw_reaction_remove(self, emoji: discord.PartialReactionEmoji, # async def on_raw_reaction_remove(self, emoji: discord.PartialReactionEmoji,
# message_id: int, channel_id: int, user_id: int): # message_id: int, channel_id: int, user_id: int):
# """ # """
# Event handler for long term reaction watching. # Event handler for long term reaction watching.
#
# :param discord.PartialReactionEmoji emoji: # :param discord.PartialReactionEmoji emoji:
# :param int message_id: # :param int message_id:
# :param int channel_id: # :param int channel_id:
@ -322,25 +316,25 @@ class ReactRestrict:
# emoji_id = emoji.id # emoji_id = emoji.id
# else: # else:
# emoji_id = emoji.name # emoji_id = emoji.name
#
# has_reactrestrict, combos = await self.has_reactrestrict_combo(message_id, emoji_id) # has_reactrestrict, combos = await self.has_reactrestrict_combo(message_id, emoji_id)
#
# if not has_reactrestrict: # if not has_reactrestrict:
# return # return
#
# try: # try:
# member = self._get_member(channel_id, user_id) # member = self._get_member(channel_id, user_id)
# except LookupError: # except LookupError:
# return # return
#
# if member.bot: # if member.bot:
# return # return
#
# try: # try:
# roles = [self._get_role(member.guild, c.role_id) for c in combos] # roles = [self._get_role(member.guild, c.role_id) for c in combos]
# except LookupError: # except LookupError:
# return # return
#
# try: # try:
# await member.remove_roles(*roles) # await member.remove_roles(*roles)
# except discord.Forbidden: # except discord.Forbidden:

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

@ -58,7 +58,7 @@ class StealEmoji:
async def se_bank(self, ctx): async def se_bank(self, ctx):
"""Add current server as emoji bank""" """Add current server as emoji bank"""
await ctx.send("This will upload custom emojis to this server\n" 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): def check(m):
return m.content.upper() in ["Y", "YES", "N", "NO"] and m.channel == ctx.channel and m.author == ctx.author 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 digits += 1
continue continue
try: try:
idx = int(built) idx = int(built)
except ValueError: except ValueError:
@ -146,7 +144,6 @@ async def parse_code(code, game):
built = "" built = ""
return decode return decode

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

Loading…
Cancel
Save