diff --git a/README.md b/README.md
index 8f61811..ca27574 100644
--- a/README.md
+++ b/README.md
@@ -9,7 +9,7 @@ Cog Function
| chatter | **Alpha** | Chat-bot trained to talk like your guild
Missing some key features, but currently functional |
| coglint | **Alpha** | Error check code in python syntax posted to discord
Works, but probably needs more turning to work for cogs |
| fight | **Incomplete** | Organize bracket tournaments within discord
Still in-progress, a massive project |
-| flag | **Incomplete** | Create temporary marks on users that expire after specified time
Not yet ported to v3 |
+| flag | **Alpha** | Create temporary marks on users that expire after specified time
Ported, will not import old data. Please report bugs |
| forcemention | **Alpha** | Mentions unmentionable roles
Very simple cog, mention doesn't persist |
| hangman | **Alpha** | Play a game of hangman
Some visual glitches and needs more customization |
| howdoi | **Incomplete** | Create temporary marks on users that expire after specified time
Not yet ported to v3 |
diff --git a/ccrole/ccrole.py b/ccrole/ccrole.py
index d8c17f6..a858992 100644
--- a/ccrole/ccrole.py
+++ b/ccrole/ccrole.py
@@ -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(
diff --git a/chatter/chat.py b/chatter/chat.py
index dce136f..eca1056 100644
--- a/chatter/chat.py
+++ b/chatter/chat.py
@@ -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
diff --git a/chatter/chatterbot/storage/storage_adapter.py b/chatter/chatterbot/storage/storage_adapter.py
index 046ae63..cf1f45b 100644
--- a/chatter/chatterbot/storage/storage_adapter.py
+++ b/chatter/chatterbot/storage/storage_adapter.py
@@ -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):
diff --git a/coglint/coglint.py b/coglint/coglint.py
index 10861c7..0c3d045 100644
--- a/coglint/coglint.py
+++ b/coglint/coglint.py
@@ -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
diff --git a/flag/__init__.py b/flag/__init__.py
new file mode 100644
index 0000000..0184952
--- /dev/null
+++ b/flag/__init__.py
@@ -0,0 +1,5 @@
+from .flag import Flag
+
+
+def setup(bot):
+ bot.add_cog(Flag(bot))
diff --git a/flag/flag.py b/flag/flag.py
new file mode 100644
index 0000000..7fe1b30
--- /dev/null
+++ b/flag/flag.py
@@ -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)
diff --git a/flag/info..json b/flag/info..json
new file mode 100644
index 0000000..b5908b9
--- /dev/null
+++ b/flag/info..json
@@ -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"
+ ]
+}
\ No newline at end of file
diff --git a/hangman/hangman.py b/hangman/hangman.py
index 4958eac..2a95f54 100644
--- a/hangman/hangman.py
+++ b/hangman/hangman.py
@@ -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)
-
diff --git a/lseen/lseen.py b/lseen/lseen.py
index 43c56ea..6cdf666 100644
--- a/lseen/lseen.py
+++ b/lseen/lseen.py
@@ -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:
diff --git a/reactrestrict/reactrestrict.py b/reactrestrict/reactrestrict.py
index 87b50a3..50aa61e 100644
--- a/reactrestrict/reactrestrict.py
+++ b/reactrestrict/reactrestrict.py
@@ -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):
@@ -169,8 +165,8 @@ class ReactRestrict:
raise LookupError("No role found.")
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,12 +195,10 @@ 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
@@ -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)
@@ -298,50 +292,50 @@ class ReactRestrict:
for apprrole in roles:
if apprrole in member.roles:
return
-
+
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
diff --git a/sayurl/sayurl.py b/sayurl/sayurl.py
index b9837aa..04499cd 100644
--- a/sayurl/sayurl.py
+++ b/sayurl/sayurl.py
@@ -32,8 +32,7 @@ class SayUrl:
"""
Converts a URL to something readable
- :param url:
- :return:
+ Works better on smaller websites
"""
h = html2text.HTML2Text()
diff --git a/stealemoji/stealemoji.py b/stealemoji/stealemoji.py
index a55d2c9..143c38a 100644
--- a/stealemoji/stealemoji.py
+++ b/stealemoji/stealemoji.py
@@ -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
diff --git a/werewolf/builder.py b/werewolf/builder.py
index 28b22ea..48e7e71 100644
--- a/werewolf/builder.py
+++ b/werewolf/builder.py
@@ -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
diff --git a/werewolf/player.py b/werewolf/player.py
index d1f9359..c84d87f 100644
--- a/werewolf/player.py
+++ b/werewolf/player.py
@@ -30,4 +30,4 @@ class Player:
try:
await self.member.send(message) # Lets do embeds later
except discord.Forbidden:
- await self.role.game.village_channel.send("Couldn't DM {}, uh oh".format(self.mention))
\ No newline at end of file
+ await self.role.game.village_channel.send("Couldn't DM {}, uh oh".format(self.mention))
diff --git a/werewolf/roles/seer.py b/werewolf/roles/seer.py
index b005b9a..5c58250 100644
--- a/werewolf/roles/seer.py
+++ b/werewolf/roles/seer.py
@@ -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