internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: python-discord/bot

Issue:
Banned members not showing up as leaving the server in #user-log
Currently, the `#user-log` channel only shows that a user left if they voluntarily leave the server. It should also include members leaving the server due to any moderator action taken.

**Implementation Details**
- Log member leaving due to any reason, voluntary or involuntary, to `#user-log`
- Show that the member left due to moderator action, eg. `User banned`/`User temporarily banned` as the title


Discussion:

Resolving patch:
diff --git a/bot/cogs/moderation/infractions.py b/bot/cogs/moderation/infractions.py
--- a/bot/cogs/moderation/infractions.py
+++ b/bot/cogs/moderation/infractions.py
@@ -261,7 +261,6 @@ async def apply_ban(self, ctx: Context, user: MemberObject, reason: str, **kwarg
         if infraction is None:
             return
 
-        self.mod_log.ignore(Event.member_ban, user.id)
         self.mod_log.ignore(Event.member_remove, user.id)
 
         action = ctx.guild.ban(user, reason=reason, delete_message_days=0)
diff --git a/bot/cogs/moderation/modlog.py b/bot/cogs/moderation/modlog.py
--- a/bot/cogs/moderation/modlog.py
+++ b/bot/cogs/moderation/modlog.py
@@ -353,7 +353,7 @@ async def on_guild_update(self, before: discord.Guild, after: discord.Guild) ->
 
     @Cog.listener()
     async def on_member_ban(self, guild: discord.Guild, member: UserTypes) -> None:
-        """Log ban event to mod log."""
+        """Log ban event to user log."""
         if guild.id != GuildConstant.id:
             return
 
@@ -365,7 +365,7 @@ async def on_member_ban(self, guild: discord.Guild, member: UserTypes) -> None:
             Icons.user_ban, Colours.soft_red,
             "User banned", f"{member.name}#{member.discriminator} (`{member.id}`)",
             thumbnail=member.avatar_url_as(static_format="png"),
-            channel_id=Channels.modlog
+            channel_id=Channels.userlog
         )
 
     @Cog.listener()


Test patch:
Repository: python-discord/bot

Issue:
Prepend emojis indicative of success for !eval
Comments on [org-issue-141](https://github.com/python-discord/organisation/issues/141) suggests something quite useful. 

Add emojis indicative of success when you use !eval. 

- ✅ - if no error.
- ❌ - if exception.
- ❗ - for other cases, as it runs but there's no output


![bild](https://user-images.githubusercontent.com/1515135/66685485-90e52600-ec31-11e9-9f42-d9c0da31a5c3.png)
![bild](https://user-images.githubusercontent.com/1515135/66685492-95114380-ec31-11e9-9154-77da46f11cde.png)
![bild](https://imgur.com/l10DMcQ.png)



Discussion:
I think ⚠️ is better for the third one since it's yellow rather than red. More distinct from the :x: that way.
I'd like to work on this, since I personally use this more often than not. Unless you are working on it with other plans like bringing 3.8 to `snekbox` @MarkKoz 
You can go for it. My plans are only concerned with CI.
I had this assigned and was working on this, you can have it though.
Ah no no, it has been quite a while and so I thought no one has taken it, @kosayoda 
If you are already on it please dont mind me
Sorry I was on mobile at the time of commenting and wasn't aware it was already assigned.

Resolving patch:
diff --git a/bot/cogs/snekbox.py b/bot/cogs/snekbox.py
--- a/bot/cogs/snekbox.py
+++ b/bot/cogs/snekbox.py
@@ -115,6 +115,16 @@ def get_results_message(results: dict) -> Tuple[str, str]:
 
         return msg, error
 
+    @staticmethod
+    def get_status_emoji(results: dict) -> str:
+        """Return an emoji corresponding to the status code or lack of output in result."""
+        if not results["stdout"].strip():  # No output
+            return ":warning:"
+        elif results["returncode"] == 0:  # No error
+            return ":white_check_mark:"
+        else:  # Exception
+            return ":x:"
+
     async def format_output(self, output: str) -> Tuple[str, Optional[str]]:
         """
         Format the output and return a tuple of the formatted output and a URL to the full output.
@@ -201,7 +211,8 @@ async def eval_command(self, ctx: Context, *, code: str = None) -> None:
                 else:
                     output, paste_link = await self.format_output(results["stdout"])
 
-                msg = f"{ctx.author.mention} {msg}.\n\n```py\n{output}\n```"
+                icon = self.get_status_emoji(results)
+                msg = f"{ctx.author.mention} {icon} {msg}.\n\n```py\n{output}\n```"
                 if paste_link:
                     msg = f"{msg}\nFull output: {paste_link}"
 


Test patch:
Repository: python-discord/bot

Issue:
Make bold links in Reddit embeds mobile compatible
The links in the Reddit relay embeds are not displayed properly on Mobile. This is caused by the same issue we've seen with tags: If the markdown for `bold text` is applied inside of the link markdown (`[**bold inside**](link)`), Discord will render it incorrectly on Android clients. If the bold markdown is applied around the link markdown (`**[bold outside](link)**`), it will be displayed as expected.


Discussion:

Resolving patch:
diff --git a/bot/cogs/reddit.py b/bot/cogs/reddit.py
--- a/bot/cogs/reddit.py
+++ b/bot/cogs/reddit.py
@@ -9,7 +9,7 @@
 from discord.ext.commands import Bot, Cog, Context, group
 from discord.ext.tasks import loop
 
-from bot.constants import Channels, ERROR_REPLIES, Reddit as RedditConfig, STAFF_ROLES, Webhooks
+from bot.constants import Channels, ERROR_REPLIES, Emojis, Reddit as RedditConfig, STAFF_ROLES, Webhooks
 from bot.converters import Subreddit
 from bot.decorators import with_role
 from bot.pagination import LinePaginator
@@ -117,9 +117,9 @@ async def get_top_posts(self, subreddit: Subreddit, time: str = "all", amount: i
             link = self.URL + data["permalink"]
 
             embed.description += (
-                f"[**{title}**]({link})\n"
+                f"**[{title}]({link})**\n"
                 f"{text}"
-                f"| {ups} upvotes | {comments} comments | u/{author} | {subreddit} |\n\n"
+                f"{Emojis.upvotes} {ups} {Emojis.comments} {comments} {Emojis.user} {author}\n\n"
             )
 
         embed.colour = Colour.blurple()
diff --git a/bot/constants.py b/bot/constants.py
--- a/bot/constants.py
+++ b/bot/constants.py
@@ -259,6 +259,10 @@ class Emojis(metaclass=YAMLGetter):
     pencil: str
     cross_mark: str
 
+    upvotes: str
+    comments: str
+    user: str
+
 
 class Icons(metaclass=YAMLGetter):
     section = "style"


Test patch:
Repository: python-discord/bot

Issue:
New custom user statuses should appear in !user
Related to #620, we must moderate the new custom statuses, but they don't appear when we issue a !user command. These should be included to form part of the channel record for moderation purposes.


Discussion:
appy aperture is working on this
> appy aperture is working on this

can confirm
There's currently a PR that changes quite a bit in regards to the `!user` command, so we may want to determine a merge order to avoid conflicts. See #637.
See also python-discord/organisation#157 - consensus was "we moderate these when we see them"

Resolving patch:
diff --git a/bot/cogs/information.py b/bot/cogs/information.py
--- a/bot/cogs/information.py
+++ b/bot/cogs/information.py
@@ -9,6 +9,7 @@
 from discord import CategoryChannel, Colour, Embed, Member, Role, TextChannel, VoiceChannel, utils
 from discord.ext import commands
 from discord.ext.commands import Bot, BucketType, Cog, Context, command, group
+from discord.utils import escape_markdown
 
 from bot.constants import Channels, Emojis, MODERATION_ROLES, STAFF_ROLES
 from bot.decorators import InChannelCheckFailure, in_channel, with_role
@@ -180,6 +181,13 @@ async def user_info(self, ctx: Context, user: Member = None, hidden: bool = Fals
         # User information
         created = time_since(user.created_at, max_units=3)
 
+        # Custom status
+        custom_status = ''
+        for activity in user.activities:
+            if activity.name == 'Custom Status':
+                state = escape_markdown(activity.state)
+                custom_status = f'Status: {state}\n'
+
         name = str(user)
         if user.nick:
             name = f"{user.nick} ({name})"
@@ -217,7 +225,7 @@ async def user_info(self, ctx: Context, user: Member = None, hidden: bool = Fals
                 Created: {created}
                 Profile: {user.mention}
                 ID: {user.id}
-
+                {custom_status}
                 **Member Information**
                 Joined: {joined}
                 Roles: {roles or None}


Test patch:
Repository: python-discord/bot

Issue:
Don't ping actor when an infraction DM fails to send
Would anyone miss this functionality?


Discussion:
Kill it with fire
We're still discussing whether or not we should actually remove this internally. 
We have discussed this with the moderation team and no one seems to be opposed to removing the "actor ping".

To still get *explicit* feedback about DMs failing to be delivered to the user, we would like to add an emoji to the infraction confirmation message in a similar style to the "swooshing" envelope we use to signal that a DM was successfully sent:

![infraction_confirmation_message](https://user-images.githubusercontent.com/33516116/66835835-817f1900-ef60-11e9-819c-a0b28c4cab0a.png)

An initial design for the "fail" emoji is:

![failmail2](https://user-images.githubusercontent.com/33516116/66836216-3f0a0c00-ef61-11e9-87ae-7db4847660ac.png)


The emoji has been added as `:failmail:` (ID of `633660039931887616`) to the emoji server.

Resolving patch:
diff --git a/bot/cogs/moderation/scheduler.py b/bot/cogs/moderation/scheduler.py
--- a/bot/cogs/moderation/scheduler.py
+++ b/bot/cogs/moderation/scheduler.py
@@ -114,8 +114,8 @@ async def apply_infraction(
                 dm_result = ":incoming_envelope: "
                 dm_log_text = "\nDM: Sent"
             else:
+                dm_result = f"{constants.Emojis.failmail} "
                 dm_log_text = "\nDM: **Failed**"
-                log_content = ctx.author.mention
 
         if infraction["actor"] == self.bot.user.id:
             log.trace(
@@ -255,8 +255,7 @@ async def pardon_infraction(self, ctx: Context, infr_type: str, user: MemberObje
         if log_text.get("DM") == "Sent":
             dm_emoji = ":incoming_envelope: "
         elif "DM" in log_text:
-            # Mention the actor because the DM failed to send.
-            log_content = ctx.author.mention
+            dm_emoji = f"{constants.Emojis.failmail} "
 
         # Accordingly display whether the pardon failed.
         if "Failure" in log_text:
diff --git a/bot/constants.py b/bot/constants.py
--- a/bot/constants.py
+++ b/bot/constants.py
@@ -256,6 +256,8 @@ class Emojis(metaclass=YAMLGetter):
     status_idle: str
     status_dnd: str
 
+    failmail: str
+
     bullet: str
     new: str
     pencil: str


Test patch:
Repository: python-discord/bot

Issue:
Make nominate show the target users name if they are already being watched
As the `!nominate` command mostly gets used by passing in the target user's id, the identity of the user is not immediately obvious. This can be annoying, as (presumably) multiple nominations can be valuable information to staff.

![ex1](https://user-images.githubusercontent.com/44734341/71602759-09d18b00-2b5a-11ea-98ca-3948fd1fa927.PNG)

To fix this, make the bot's response include the user's name, such as below.

![ex2](https://user-images.githubusercontent.com/44734341/71602764-0b9b4e80-2b5a-11ea-86b1-f49269d016e9.PNG)

This should be a fairly trivial [fix here](https://github.com/python-discord/bot/blob/3df35089f0158130eff8c3a4d6ddba946e1798f4/bot/cogs/watchchannels/talentpool.py#L72).



Discussion:

Resolving patch:
diff --git a/bot/cogs/watchchannels/bigbrother.py b/bot/cogs/watchchannels/bigbrother.py
--- a/bot/cogs/watchchannels/bigbrother.py
+++ b/bot/cogs/watchchannels/bigbrother.py
@@ -62,7 +62,7 @@ async def watch_command(self, ctx: Context, user: Union[User, proxy_user], *, re
             return
 
         if user.id in self.watched_users:
-            await ctx.send(":x: The specified user is already being watched.")
+            await ctx.send(f":x: {user} is already being watched.")
             return
 
         response = await post_infraction(ctx, user, 'watch', reason, hidden=True)
diff --git a/bot/cogs/watchchannels/talentpool.py b/bot/cogs/watchchannels/talentpool.py
--- a/bot/cogs/watchchannels/talentpool.py
+++ b/bot/cogs/watchchannels/talentpool.py
@@ -69,7 +69,7 @@ async def watch_command(self, ctx: Context, user: Union[Member, User, proxy_user
             return
 
         if user.id in self.watched_users:
-            await ctx.send(":x: The specified user is already being watched in the talent pool")
+            await ctx.send(f":x: {user} is already being watched in the talent pool")
             return
 
         # Manual request with `raise_for_status` as False because we want the actual response


Test patch:
Repository: python-discord/bot

Issue:
PEP Command Fails on Empty Metadata
Currently, the PEP command assumes that if a metadata field is present in the PEP's summary table that the value is populated:

https://github.com/python-discord/bot/blob/74d990540a1072c1782fa7593d7d1abe3c165f49/bot/cogs/utils.py#L64-L72

However, this is not always the case, e.g. [PEP 249](https://www.python.org/dev/peps/pep-0249/):

![image](https://user-images.githubusercontent.com/5323929/72211253-23e26600-3496-11ea-847b-29300866532b.png)

Because of this, the embed field's `value` can be provided an empty string, causing an exception to be raised:

```
HTTPException: 400 BAD REQUEST (error code: 50035): Invalid Form Body
In embed.fields.1.value: This field is required
```

To fix this, there should be a catch for empty values to prevent a field being added if there's no value to populate.


Discussion:

Resolving patch:
diff --git a/bot/cogs/utils.py b/bot/cogs/utils.py
--- a/bot/cogs/utils.py
+++ b/bot/cogs/utils.py
@@ -62,14 +62,12 @@ async def pep_command(self, ctx: Context, pep_number: str) -> None:
                 pep_embed.set_thumbnail(url="https://www.python.org/static/opengraph-icon-200x200.png")
 
                 # Add the interesting information
-                if "Status" in pep_header:
-                    pep_embed.add_field(name="Status", value=pep_header["Status"])
-                if "Python-Version" in pep_header:
-                    pep_embed.add_field(name="Python-Version", value=pep_header["Python-Version"])
-                if "Created" in pep_header:
-                    pep_embed.add_field(name="Created", value=pep_header["Created"])
-                if "Type" in pep_header:
-                    pep_embed.add_field(name="Type", value=pep_header["Type"])
+                fields_to_check = ("Status", "Python-Version", "Created", "Type")
+                for field in fields_to_check:
+                    # Check for a PEP metadata field that is present but has an empty value
+                    # embed field values can't contain an empty string
+                    if pep_header.get(field, ""):
+                        pep_embed.add_field(name=field, value=pep_header[field])
 
             elif response.status != 404:
                 # any response except 200 and 404 is expected


Test patch:
Repository: python-discord/bot

Issue:
Allow for throw away words after the rules command call
fixes #723 
This simply catches all strings after a sequence of ints. This allows us to write a message after the list of rules we wish to display. 
Example:
`!rules 5 6 We do not allow for paid work, and that will break ToS of x and y` 

Disclaimer, didn't get site to respond properly so haven't tested this with bot+site.


Discussion:

Resolving patch:
diff --git a/bot/cogs/alias.py b/bot/cogs/alias.py
--- a/bot/cogs/alias.py
+++ b/bot/cogs/alias.py
@@ -3,7 +3,10 @@
 from typing import Union
 
 from discord import Colour, Embed, Member, User
-from discord.ext.commands import Cog, Command, Context, clean_content, command, group
+from discord.ext.commands import (
+    Cog, Command, Context, Greedy,
+    clean_content, command, group,
+)
 
 from bot.bot import Bot
 from bot.cogs.extensions import Extension
@@ -81,7 +84,7 @@ async def site_faq_alias(self, ctx: Context) -> None:
         await self.invoke(ctx, "site faq")
 
     @command(name="rules", aliases=("rule",), hidden=True)
-    async def site_rules_alias(self, ctx: Context, *rules: int) -> None:
+    async def site_rules_alias(self, ctx: Context, rules: Greedy[int], *_: str) -> None:
         """Alias for invoking <prefix>site rules."""
         await self.invoke(ctx, "site rules", *rules)
 


Test patch:
Repository: python-discord/bot

Issue:
User command fails for certain custom statuses
Basic support for handling custom user activity (status?) was added by #648 (Parent: #647) after Discord introduced the feature. However, this seems to be broken for the case where a user sets an emoji as their status without any accompanying text:

![image](https://user-images.githubusercontent.com/5323929/72485471-d3407500-37d5-11ea-8b06-156e860de22e.png)

In this scenario, `activity.status` is `None`, which causes `discord.utils.escape_markdown` to raise the above exception, as it's expecting something string-like.

We can guard against this by checking for a `None` status value & skipping the markdown escape util if necessary. Note that a [`CustomActivity`](https://discordpy.readthedocs.io/en/latest/api.html#discord.CustomActivity) class is introduced by d.py 1.3.0+, which will provide more robust handling for this case once officially released & we upgrade.


Discussion:

Resolving patch:
diff --git a/bot/cogs/information.py b/bot/cogs/information.py
--- a/bot/cogs/information.py
+++ b/bot/cogs/information.py
@@ -189,7 +189,11 @@ async def create_user_embed(self, ctx: Context, user: Member) -> Embed:
         # Custom status
         custom_status = ''
         for activity in user.activities:
-            if activity.name == 'Custom Status':
+            # Check activity.state for None value if user has a custom status set
+            # This guards against a custom status with an emoji but no text, which will cause
+            # escape_markdown to raise an exception
+            # This can be reworked after a move to d.py 1.3.0+, which adds a CustomActivity class
+            if activity.name == 'Custom Status' and activity.state:
                 state = escape_markdown(activity.state)
                 custom_status = f'Status: {state}\n'
 


Test patch:
Repository: python-discord/bot

Issue:
Pagniation breaks when skipping to last page
Using the ⏭️ reaction to skip to the last page causes an exception.

![image](https://user-images.githubusercontent.com/20041393/74332220-dbd19e80-4dc7-11ea-82dd-05ab17f593dd.png)

The prime suspect appears to be this line:

https://github.com/python-discord/bot/blob/7dbd4d41d8dd00d73a63195b4a83c728d40fb042/bot/pagination.py#L413

Should probably instead be:
```py
current_page = len(paginator.pages) - 1


Discussion:
Thanks! Good spot, ~~although your suggested fix is currently equal to the bug:~~ (you edited your post)

> Should probably instead be:
> 
> ```python
> current_page = len(paginator.pages - 1)
> ```

I suspect you mean this:

https://github.com/python-discord/bot/blob/7dbd4d41d8dd00d73a63195b4a83c728d40fb042/bot/pagination.py#L229

(This is from the LinePaginator, which does work)

Do you want to make a PR for this?

> ~~although your suggested fix is currently equal to the bug~~

Yeah, I only saw it after posting haha.

> Do you want to make a PR for this?

And sure thing.

Resolving patch:
diff --git a/bot/pagination.py b/bot/pagination.py
--- a/bot/pagination.py
+++ b/bot/pagination.py
@@ -410,7 +410,7 @@ def check_event(reaction_: Reaction, member: Member) -> bool:
                     log.debug("Got last page reaction, but we're on the last page - ignoring")
                     continue
 
-                current_page = len(paginator.pages - 1)
+                current_page = len(paginator.pages) - 1
                 reaction_type = "last"
 
             # Previous reaction press - [:arrow_left: ]


Test patch:
Repository: python-discord/bot

Issue:
Infraction scheduler raises exception when marking infraction as "permanent" during edit
When an existing temporary infraction is turned into a permanent infraction using the `!infraction edit` functionality, we ask the infraction scheduler to schedule a new task with `infraction["expires_at"] = None`. However, the scheduler expects to be called only for infractions that have a datetime string mapped to the `"expires_at"` key. This means that the scheduler will try to parse that `None` value with `dateutil.parse.isoparse`, which results in an exception:

```py
Traceback (most recent call last):
  File "/bot/bot/cogs/moderation/scheduler.py", line 415, in _scheduled_task
    expiry = dateutil.parser.isoparse(infraction["expires_at"]).replace(tzinfo=None)
  File "/usr/local/lib/python3.7/site-packages/dateutil/parser/isoparser.py", line 37, in func
    return f(self, str_in, *args, **kwargs)
  File "/usr/local/lib/python3.7/site-packages/dateutil/parser/isoparser.py", line 134, in isoparse
    components, pos = self._parse_isodate(dt_str)
  File "/usr/local/lib/python3.7/site-packages/dateutil/parser/isoparser.py", line 208, in _parse_isodate
    return self._parse_isodate_common(dt_str)
  File "/usr/local/lib/python3.7/site-packages/dateutil/parser/isoparser.py", line 213, in _parse_isodate_common
    len_str = len(dt_str)
TypeError: object of type 'NoneType' has no len()
```

I think the wisest course of action is tackle this at the level of the infraction edit method, not in the scheduler itself. We should just not try to schedule a new task when we've marked it as permanent. That means this part need to get an additional check:

https://github.com/python-discord/bot/blob/95ae05c773e753699e6899255783c1d7df936024/bot/cogs/moderation/management.py#L131-L134

**Important:** We should still *cancel* the existing scheduled task (which we currently do, it happens before the exception), so skipping this `if` block entirely will break the infraction edit in a more severe way: Cancelling the task is essential to guarantee that we don't accidentally "pardon" a now permanent infraction.


Discussion:

Resolving patch:
diff --git a/bot/cogs/moderation/management.py b/bot/cogs/moderation/management.py
--- a/bot/cogs/moderation/management.py
+++ b/bot/cogs/moderation/management.py
@@ -130,8 +130,11 @@ async def infraction_edit(
         # Re-schedule infraction if the expiration has been updated
         if 'expires_at' in request_data:
             self.infractions_cog.cancel_task(new_infraction['id'])
-            loop = asyncio.get_event_loop()
-            self.infractions_cog.schedule_task(loop, new_infraction['id'], new_infraction)
+
+            # If the infraction was not marked as permanent, schedule a new expiration task
+            if request_data['expires_at']:
+                loop = asyncio.get_event_loop()
+                self.infractions_cog.schedule_task(loop, new_infraction['id'], new_infraction)
 
             log_text += f"""
                 Previous expiry: {old_infraction['expires_at'] or "Permanent"}


Test patch: