We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
!reminders list returning all reminders in DB
The reminders cog is currently returning a list of all reminders in the DB rather than those specific to the user.

For example, if I have no reminders created I still get a list of reminders:

![image](https://user-images.githubusercontent.com/5323929/65425255-90e4c980-dddb-11e9-813f-4638c8c9f7e9.png)


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `bot/cogs/reminders.py`
Content:
```
1 import asyncio
2 import logging
3 import random
4 import textwrap
5 from datetime import datetime
6 from operator import itemgetter
7 from typing import Optional
8 
9 from dateutil.relativedelta import relativedelta
10 from discord import Colour, Embed, Message
11 from discord.ext.commands import Bot, Cog, Context, group
12 
13 from bot.constants import Channels, Icons, NEGATIVE_REPLIES, POSITIVE_REPLIES, STAFF_ROLES
14 from bot.converters import Duration
15 from bot.pagination import LinePaginator
16 from bot.utils.checks import without_role_check
17 from bot.utils.scheduling import Scheduler
18 from bot.utils.time import humanize_delta, wait_until
19 
20 log = logging.getLogger(__name__)
21 
22 WHITELISTED_CHANNELS = (Channels.bot,)
23 MAXIMUM_REMINDERS = 5
24 
25 
26 class Reminders(Scheduler, Cog):
27     """Provide in-channel reminder functionality."""
28 
29     def __init__(self, bot: Bot):
30         self.bot = bot
31         super().__init__()
32 
33     @Cog.listener()
34     async def on_ready(self) -> None:
35         """Get all current reminders from the API and reschedule them."""
36         response = await self.bot.api_client.get(
37             'bot/reminders',
38             params={'active': 'true'}
39         )
40 
41         now = datetime.utcnow()
42         loop = asyncio.get_event_loop()
43 
44         for reminder in response:
45             remind_at = datetime.fromisoformat(reminder['expiration'][:-1])
46 
47             # If the reminder is already overdue ...
48             if remind_at < now:
49                 late = relativedelta(now, remind_at)
50                 await self.send_reminder(reminder, late)
51 
52             else:
53                 self.schedule_task(loop, reminder["id"], reminder)
54 
55     @staticmethod
56     async def _send_confirmation(ctx: Context, on_success: str) -> None:
57         """Send an embed confirming the reminder change was made successfully."""
58         embed = Embed()
59         embed.colour = Colour.green()
60         embed.title = random.choice(POSITIVE_REPLIES)
61         embed.description = on_success
62         await ctx.send(embed=embed)
63 
64     async def _scheduled_task(self, reminder: dict) -> None:
65         """A coroutine which sends the reminder once the time is reached, and cancels the running task."""
66         reminder_id = reminder["id"]
67         reminder_datetime = datetime.fromisoformat(reminder['expiration'][:-1])
68 
69         # Send the reminder message once the desired duration has passed
70         await wait_until(reminder_datetime)
71         await self.send_reminder(reminder)
72 
73         log.debug(f"Deleting reminder {reminder_id} (the user has been reminded).")
74         await self._delete_reminder(reminder_id)
75 
76         # Now we can begone with it from our schedule list.
77         self.cancel_task(reminder_id)
78 
79     async def _delete_reminder(self, reminder_id: str) -> None:
80         """Delete a reminder from the database, given its ID, and cancel the running task."""
81         await self.bot.api_client.delete('bot/reminders/' + str(reminder_id))
82 
83         # Now we can remove it from the schedule list
84         self.cancel_task(reminder_id)
85 
86     async def _reschedule_reminder(self, reminder: dict) -> None:
87         """Reschedule a reminder object."""
88         loop = asyncio.get_event_loop()
89 
90         self.cancel_task(reminder["id"])
91         self.schedule_task(loop, reminder["id"], reminder)
92 
93     async def send_reminder(self, reminder: dict, late: relativedelta = None) -> None:
94         """Send the reminder."""
95         channel = self.bot.get_channel(reminder["channel_id"])
96         user = self.bot.get_user(reminder["author"])
97 
98         embed = Embed()
99         embed.colour = Colour.blurple()
100         embed.set_author(
101             icon_url=Icons.remind_blurple,
102             name="It has arrived!"
103         )
104 
105         embed.description = f"Here's your reminder: `{reminder['content']}`"
106 
107         if late:
108             embed.colour = Colour.red()
109             embed.set_author(
110                 icon_url=Icons.remind_red,
111                 name=f"Sorry it arrived {humanize_delta(late, max_units=2)} late!"
112             )
113 
114         await channel.send(
115             content=user.mention,
116             embed=embed
117         )
118         await self._delete_reminder(reminder["id"])
119 
120     @group(name="remind", aliases=("reminder", "reminders"), invoke_without_command=True)
121     async def remind_group(self, ctx: Context, expiration: Duration, *, content: str) -> None:
122         """Commands for managing your reminders."""
123         await ctx.invoke(self.new_reminder, expiration=expiration, content=content)
124 
125     @remind_group.command(name="new", aliases=("add", "create"))
126     async def new_reminder(self, ctx: Context, expiration: Duration, *, content: str) -> Optional[Message]:
127         """
128         Set yourself a simple reminder.
129 
130         Expiration is parsed per: http://strftime.org/
131         """
132         embed = Embed()
133 
134         # If the user is not staff, we need to verify whether or not to make a reminder at all.
135         if without_role_check(ctx, *STAFF_ROLES):
136 
137             # If they don't have permission to set a reminder in this channel
138             if ctx.channel.id not in WHITELISTED_CHANNELS:
139                 embed.colour = Colour.red()
140                 embed.title = random.choice(NEGATIVE_REPLIES)
141                 embed.description = "Sorry, you can't do that here!"
142 
143                 return await ctx.send(embed=embed)
144 
145             # Get their current active reminders
146             active_reminders = await self.bot.api_client.get(
147                 'bot/reminders',
148                 params={
149                     'user__id': str(ctx.author.id)
150                 }
151             )
152 
153             # Let's limit this, so we don't get 10 000
154             # reminders from kip or something like that :P
155             if len(active_reminders) > MAXIMUM_REMINDERS:
156                 embed.colour = Colour.red()
157                 embed.title = random.choice(NEGATIVE_REPLIES)
158                 embed.description = "You have too many active reminders!"
159 
160                 return await ctx.send(embed=embed)
161 
162         # Now we can attempt to actually set the reminder.
163         reminder = await self.bot.api_client.post(
164             'bot/reminders',
165             json={
166                 'author': ctx.author.id,
167                 'channel_id': ctx.message.channel.id,
168                 'content': content,
169                 'expiration': expiration.isoformat()
170             }
171         )
172 
173         # Confirm to the user that it worked.
174         await self._send_confirmation(
175             ctx, on_success="Your reminder has been created successfully!"
176         )
177 
178         loop = asyncio.get_event_loop()
179         self.schedule_task(loop, reminder["id"], reminder)
180 
181     @remind_group.command(name="list")
182     async def list_reminders(self, ctx: Context) -> Optional[Message]:
183         """View a paginated embed of all reminders for your user."""
184         # Get all the user's reminders from the database.
185         data = await self.bot.api_client.get(
186             'bot/reminders',
187             params={'user__id': str(ctx.author.id)}
188         )
189 
190         now = datetime.utcnow()
191 
192         # Make a list of tuples so it can be sorted by time.
193         reminders = sorted(
194             (
195                 (rem['content'], rem['expiration'], rem['id'])
196                 for rem in data
197             ),
198             key=itemgetter(1)
199         )
200 
201         lines = []
202 
203         for content, remind_at, id_ in reminders:
204             # Parse and humanize the time, make it pretty :D
205             remind_datetime = datetime.fromisoformat(remind_at[:-1])
206             time = humanize_delta(relativedelta(remind_datetime, now))
207 
208             text = textwrap.dedent(f"""
209             **Reminder #{id_}:** *expires in {time}* (ID: {id_})
210             {content}
211             """).strip()
212 
213             lines.append(text)
214 
215         embed = Embed()
216         embed.colour = Colour.blurple()
217         embed.title = f"Reminders for {ctx.author}"
218 
219         # Remind the user that they have no reminders :^)
220         if not lines:
221             embed.description = "No active reminders could be found."
222             return await ctx.send(embed=embed)
223 
224         # Construct the embed and paginate it.
225         embed.colour = Colour.blurple()
226 
227         await LinePaginator.paginate(
228             lines,
229             ctx, embed,
230             max_lines=3,
231             empty=True
232         )
233 
234     @remind_group.group(name="edit", aliases=("change", "modify"), invoke_without_command=True)
235     async def edit_reminder_group(self, ctx: Context) -> None:
236         """Commands for modifying your current reminders."""
237         await ctx.invoke(self.bot.get_command("help"), "reminders", "edit")
238 
239     @edit_reminder_group.command(name="duration", aliases=("time",))
240     async def edit_reminder_duration(self, ctx: Context, id_: int, expiration: Duration) -> None:
241         """
242          Edit one of your reminder's expiration.
243 
244         Expiration is parsed per: http://strftime.org/
245         """
246         # Send the request to update the reminder in the database
247         reminder = await self.bot.api_client.patch(
248             'bot/reminders/' + str(id_),
249             json={'expiration': expiration.isoformat()}
250         )
251 
252         # Send a confirmation message to the channel
253         await self._send_confirmation(
254             ctx, on_success="That reminder has been edited successfully!"
255         )
256 
257         await self._reschedule_reminder(reminder)
258 
259     @edit_reminder_group.command(name="content", aliases=("reason",))
260     async def edit_reminder_content(self, ctx: Context, id_: int, *, content: str) -> None:
261         """Edit one of your reminder's content."""
262         # Send the request to update the reminder in the database
263         reminder = await self.bot.api_client.patch(
264             'bot/reminders/' + str(id_),
265             json={'content': content}
266         )
267 
268         # Send a confirmation message to the channel
269         await self._send_confirmation(
270             ctx, on_success="That reminder has been edited successfully!"
271         )
272         await self._reschedule_reminder(reminder)
273 
274     @remind_group.command("delete", aliases=("remove",))
275     async def delete_reminder(self, ctx: Context, id_: int) -> None:
276         """Delete one of your active reminders."""
277         await self._delete_reminder(id_)
278         await self._send_confirmation(
279             ctx, on_success="That reminder has been deleted successfully!"
280         )
281 
282 
283 def setup(bot: Bot) -> None:
284     """Reminders cog load."""
285     bot.add_cog(Reminders(bot))
286     log.info("Cog loaded: Reminders")
287
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/bot/cogs/reminders.py b/bot/cogs/reminders.py
--- a/bot/cogs/reminders.py
+++ b/bot/cogs/reminders.py
@@ -146,7 +146,7 @@
             active_reminders = await self.bot.api_client.get(
                 'bot/reminders',
                 params={
-                    'user__id': str(ctx.author.id)
+                    'author__id': str(ctx.author.id)
                 }
             )
 
@@ -184,7 +184,7 @@
         # Get all the user's reminders from the database.
         data = await self.bot.api_client.get(
             'bot/reminders',
-            params={'user__id': str(ctx.author.id)}
+            params={'author__id': str(ctx.author.id)}
         )
 
         now = datetime.utcnow()

{"golden_diff": "diff --git a/bot/cogs/reminders.py b/bot/cogs/reminders.py\n--- a/bot/cogs/reminders.py\n+++ b/bot/cogs/reminders.py\n@@ -146,7 +146,7 @@\n             active_reminders = await self.bot.api_client.get(\n                 'bot/reminders',\n                 params={\n-                    'user__id': str(ctx.author.id)\n+                    'author__id': str(ctx.author.id)\n                 }\n             )\n \n@@ -184,7 +184,7 @@\n         # Get all the user's reminders from the database.\n         data = await self.bot.api_client.get(\n             'bot/reminders',\n-            params={'user__id': str(ctx.author.id)}\n+            params={'author__id': str(ctx.author.id)}\n         )\n \n         now = datetime.utcnow()\n", "issue": "!reminders list returning all reminders in DB\nThe reminders cog is currently returning a list of all reminders in the DB rather than those specific to the user.\r\n\r\nFor example, if I have no reminders created I still get a list of reminders:\r\n\r\n![image](https://user-images.githubusercontent.com/5323929/65425255-90e4c980-dddb-11e9-813f-4638c8c9f7e9.png)\r\n\n", "before_files": [{"content": "import asyncio\nimport logging\nimport random\nimport textwrap\nfrom datetime import datetime\nfrom operator import itemgetter\nfrom typing import Optional\n\nfrom dateutil.relativedelta import relativedelta\nfrom discord import Colour, Embed, Message\nfrom discord.ext.commands import Bot, Cog, Context, group\n\nfrom bot.constants import Channels, Icons, NEGATIVE_REPLIES, POSITIVE_REPLIES, STAFF_ROLES\nfrom bot.converters import Duration\nfrom bot.pagination import LinePaginator\nfrom bot.utils.checks import without_role_check\nfrom bot.utils.scheduling import Scheduler\nfrom bot.utils.time import humanize_delta, wait_until\n\nlog = logging.getLogger(__name__)\n\nWHITELISTED_CHANNELS = (Channels.bot,)\nMAXIMUM_REMINDERS = 5\n\n\nclass Reminders(Scheduler, Cog):\n    \"\"\"Provide in-channel reminder functionality.\"\"\"\n\n    def __init__(self, bot: Bot):\n        self.bot = bot\n        super().__init__()\n\n    @Cog.listener()\n    async def on_ready(self) -> None:\n        \"\"\"Get all current reminders from the API and reschedule them.\"\"\"\n        response = await self.bot.api_client.get(\n            'bot/reminders',\n            params={'active': 'true'}\n        )\n\n        now = datetime.utcnow()\n        loop = asyncio.get_event_loop()\n\n        for reminder in response:\n            remind_at = datetime.fromisoformat(reminder['expiration'][:-1])\n\n            # If the reminder is already overdue ...\n            if remind_at < now:\n                late = relativedelta(now, remind_at)\n                await self.send_reminder(reminder, late)\n\n            else:\n                self.schedule_task(loop, reminder[\"id\"], reminder)\n\n    @staticmethod\n    async def _send_confirmation(ctx: Context, on_success: str) -> None:\n        \"\"\"Send an embed confirming the reminder change was made successfully.\"\"\"\n        embed = Embed()\n        embed.colour = Colour.green()\n        embed.title = random.choice(POSITIVE_REPLIES)\n        embed.description = on_success\n        await ctx.send(embed=embed)\n\n    async def _scheduled_task(self, reminder: dict) -> None:\n        \"\"\"A coroutine which sends the reminder once the time is reached, and cancels the running task.\"\"\"\n        reminder_id = reminder[\"id\"]\n        reminder_datetime = datetime.fromisoformat(reminder['expiration'][:-1])\n\n        # Send the reminder message once the desired duration has passed\n        await wait_until(reminder_datetime)\n        await self.send_reminder(reminder)\n\n        log.debug(f\"Deleting reminder {reminder_id} (the user has been reminded).\")\n        await self._delete_reminder(reminder_id)\n\n        # Now we can begone with it from our schedule list.\n        self.cancel_task(reminder_id)\n\n    async def _delete_reminder(self, reminder_id: str) -> None:\n        \"\"\"Delete a reminder from the database, given its ID, and cancel the running task.\"\"\"\n        await self.bot.api_client.delete('bot/reminders/' + str(reminder_id))\n\n        # Now we can remove it from the schedule list\n        self.cancel_task(reminder_id)\n\n    async def _reschedule_reminder(self, reminder: dict) -> None:\n        \"\"\"Reschedule a reminder object.\"\"\"\n        loop = asyncio.get_event_loop()\n\n        self.cancel_task(reminder[\"id\"])\n        self.schedule_task(loop, reminder[\"id\"], reminder)\n\n    async def send_reminder(self, reminder: dict, late: relativedelta = None) -> None:\n        \"\"\"Send the reminder.\"\"\"\n        channel = self.bot.get_channel(reminder[\"channel_id\"])\n        user = self.bot.get_user(reminder[\"author\"])\n\n        embed = Embed()\n        embed.colour = Colour.blurple()\n        embed.set_author(\n            icon_url=Icons.remind_blurple,\n            name=\"It has arrived!\"\n        )\n\n        embed.description = f\"Here's your reminder: `{reminder['content']}`\"\n\n        if late:\n            embed.colour = Colour.red()\n            embed.set_author(\n                icon_url=Icons.remind_red,\n                name=f\"Sorry it arrived {humanize_delta(late, max_units=2)} late!\"\n            )\n\n        await channel.send(\n            content=user.mention,\n            embed=embed\n        )\n        await self._delete_reminder(reminder[\"id\"])\n\n    @group(name=\"remind\", aliases=(\"reminder\", \"reminders\"), invoke_without_command=True)\n    async def remind_group(self, ctx: Context, expiration: Duration, *, content: str) -> None:\n        \"\"\"Commands for managing your reminders.\"\"\"\n        await ctx.invoke(self.new_reminder, expiration=expiration, content=content)\n\n    @remind_group.command(name=\"new\", aliases=(\"add\", \"create\"))\n    async def new_reminder(self, ctx: Context, expiration: Duration, *, content: str) -> Optional[Message]:\n        \"\"\"\n        Set yourself a simple reminder.\n\n        Expiration is parsed per: http://strftime.org/\n        \"\"\"\n        embed = Embed()\n\n        # If the user is not staff, we need to verify whether or not to make a reminder at all.\n        if without_role_check(ctx, *STAFF_ROLES):\n\n            # If they don't have permission to set a reminder in this channel\n            if ctx.channel.id not in WHITELISTED_CHANNELS:\n                embed.colour = Colour.red()\n                embed.title = random.choice(NEGATIVE_REPLIES)\n                embed.description = \"Sorry, you can't do that here!\"\n\n                return await ctx.send(embed=embed)\n\n            # Get their current active reminders\n            active_reminders = await self.bot.api_client.get(\n                'bot/reminders',\n                params={\n                    'user__id': str(ctx.author.id)\n                }\n            )\n\n            # Let's limit this, so we don't get 10 000\n            # reminders from kip or something like that :P\n            if len(active_reminders) > MAXIMUM_REMINDERS:\n                embed.colour = Colour.red()\n                embed.title = random.choice(NEGATIVE_REPLIES)\n                embed.description = \"You have too many active reminders!\"\n\n                return await ctx.send(embed=embed)\n\n        # Now we can attempt to actually set the reminder.\n        reminder = await self.bot.api_client.post(\n            'bot/reminders',\n            json={\n                'author': ctx.author.id,\n                'channel_id': ctx.message.channel.id,\n                'content': content,\n                'expiration': expiration.isoformat()\n            }\n        )\n\n        # Confirm to the user that it worked.\n        await self._send_confirmation(\n            ctx, on_success=\"Your reminder has been created successfully!\"\n        )\n\n        loop = asyncio.get_event_loop()\n        self.schedule_task(loop, reminder[\"id\"], reminder)\n\n    @remind_group.command(name=\"list\")\n    async def list_reminders(self, ctx: Context) -> Optional[Message]:\n        \"\"\"View a paginated embed of all reminders for your user.\"\"\"\n        # Get all the user's reminders from the database.\n        data = await self.bot.api_client.get(\n            'bot/reminders',\n            params={'user__id': str(ctx.author.id)}\n        )\n\n        now = datetime.utcnow()\n\n        # Make a list of tuples so it can be sorted by time.\n        reminders = sorted(\n            (\n                (rem['content'], rem['expiration'], rem['id'])\n                for rem in data\n            ),\n            key=itemgetter(1)\n        )\n\n        lines = []\n\n        for content, remind_at, id_ in reminders:\n            # Parse and humanize the time, make it pretty :D\n            remind_datetime = datetime.fromisoformat(remind_at[:-1])\n            time = humanize_delta(relativedelta(remind_datetime, now))\n\n            text = textwrap.dedent(f\"\"\"\n            **Reminder #{id_}:** *expires in {time}* (ID: {id_})\n            {content}\n            \"\"\").strip()\n\n            lines.append(text)\n\n        embed = Embed()\n        embed.colour = Colour.blurple()\n        embed.title = f\"Reminders for {ctx.author}\"\n\n        # Remind the user that they have no reminders :^)\n        if not lines:\n            embed.description = \"No active reminders could be found.\"\n            return await ctx.send(embed=embed)\n\n        # Construct the embed and paginate it.\n        embed.colour = Colour.blurple()\n\n        await LinePaginator.paginate(\n            lines,\n            ctx, embed,\n            max_lines=3,\n            empty=True\n        )\n\n    @remind_group.group(name=\"edit\", aliases=(\"change\", \"modify\"), invoke_without_command=True)\n    async def edit_reminder_group(self, ctx: Context) -> None:\n        \"\"\"Commands for modifying your current reminders.\"\"\"\n        await ctx.invoke(self.bot.get_command(\"help\"), \"reminders\", \"edit\")\n\n    @edit_reminder_group.command(name=\"duration\", aliases=(\"time\",))\n    async def edit_reminder_duration(self, ctx: Context, id_: int, expiration: Duration) -> None:\n        \"\"\"\n         Edit one of your reminder's expiration.\n\n        Expiration is parsed per: http://strftime.org/\n        \"\"\"\n        # Send the request to update the reminder in the database\n        reminder = await self.bot.api_client.patch(\n            'bot/reminders/' + str(id_),\n            json={'expiration': expiration.isoformat()}\n        )\n\n        # Send a confirmation message to the channel\n        await self._send_confirmation(\n            ctx, on_success=\"That reminder has been edited successfully!\"\n        )\n\n        await self._reschedule_reminder(reminder)\n\n    @edit_reminder_group.command(name=\"content\", aliases=(\"reason\",))\n    async def edit_reminder_content(self, ctx: Context, id_: int, *, content: str) -> None:\n        \"\"\"Edit one of your reminder's content.\"\"\"\n        # Send the request to update the reminder in the database\n        reminder = await self.bot.api_client.patch(\n            'bot/reminders/' + str(id_),\n            json={'content': content}\n        )\n\n        # Send a confirmation message to the channel\n        await self._send_confirmation(\n            ctx, on_success=\"That reminder has been edited successfully!\"\n        )\n        await self._reschedule_reminder(reminder)\n\n    @remind_group.command(\"delete\", aliases=(\"remove\",))\n    async def delete_reminder(self, ctx: Context, id_: int) -> None:\n        \"\"\"Delete one of your active reminders.\"\"\"\n        await self._delete_reminder(id_)\n        await self._send_confirmation(\n            ctx, on_success=\"That reminder has been deleted successfully!\"\n        )\n\n\ndef setup(bot: Bot) -> None:\n    \"\"\"Reminders cog load.\"\"\"\n    bot.add_cog(Reminders(bot))\n    log.info(\"Cog loaded: Reminders\")\n", "path": "bot/cogs/reminders.py"}], "after_files": [{"content": "import asyncio\nimport logging\nimport random\nimport textwrap\nfrom datetime import datetime\nfrom operator import itemgetter\nfrom typing import Optional\n\nfrom dateutil.relativedelta import relativedelta\nfrom discord import Colour, Embed, Message\nfrom discord.ext.commands import Bot, Cog, Context, group\n\nfrom bot.constants import Channels, Icons, NEGATIVE_REPLIES, POSITIVE_REPLIES, STAFF_ROLES\nfrom bot.converters import Duration\nfrom bot.pagination import LinePaginator\nfrom bot.utils.checks import without_role_check\nfrom bot.utils.scheduling import Scheduler\nfrom bot.utils.time import humanize_delta, wait_until\n\nlog = logging.getLogger(__name__)\n\nWHITELISTED_CHANNELS = (Channels.bot,)\nMAXIMUM_REMINDERS = 5\n\n\nclass Reminders(Scheduler, Cog):\n    \"\"\"Provide in-channel reminder functionality.\"\"\"\n\n    def __init__(self, bot: Bot):\n        self.bot = bot\n        super().__init__()\n\n    @Cog.listener()\n    async def on_ready(self) -> None:\n        \"\"\"Get all current reminders from the API and reschedule them.\"\"\"\n        response = await self.bot.api_client.get(\n            'bot/reminders',\n            params={'active': 'true'}\n        )\n\n        now = datetime.utcnow()\n        loop = asyncio.get_event_loop()\n\n        for reminder in response:\n            remind_at = datetime.fromisoformat(reminder['expiration'][:-1])\n\n            # If the reminder is already overdue ...\n            if remind_at < now:\n                late = relativedelta(now, remind_at)\n                await self.send_reminder(reminder, late)\n\n            else:\n                self.schedule_task(loop, reminder[\"id\"], reminder)\n\n    @staticmethod\n    async def _send_confirmation(ctx: Context, on_success: str) -> None:\n        \"\"\"Send an embed confirming the reminder change was made successfully.\"\"\"\n        embed = Embed()\n        embed.colour = Colour.green()\n        embed.title = random.choice(POSITIVE_REPLIES)\n        embed.description = on_success\n        await ctx.send(embed=embed)\n\n    async def _scheduled_task(self, reminder: dict) -> None:\n        \"\"\"A coroutine which sends the reminder once the time is reached, and cancels the running task.\"\"\"\n        reminder_id = reminder[\"id\"]\n        reminder_datetime = datetime.fromisoformat(reminder['expiration'][:-1])\n\n        # Send the reminder message once the desired duration has passed\n        await wait_until(reminder_datetime)\n        await self.send_reminder(reminder)\n\n        log.debug(f\"Deleting reminder {reminder_id} (the user has been reminded).\")\n        await self._delete_reminder(reminder_id)\n\n        # Now we can begone with it from our schedule list.\n        self.cancel_task(reminder_id)\n\n    async def _delete_reminder(self, reminder_id: str) -> None:\n        \"\"\"Delete a reminder from the database, given its ID, and cancel the running task.\"\"\"\n        await self.bot.api_client.delete('bot/reminders/' + str(reminder_id))\n\n        # Now we can remove it from the schedule list\n        self.cancel_task(reminder_id)\n\n    async def _reschedule_reminder(self, reminder: dict) -> None:\n        \"\"\"Reschedule a reminder object.\"\"\"\n        loop = asyncio.get_event_loop()\n\n        self.cancel_task(reminder[\"id\"])\n        self.schedule_task(loop, reminder[\"id\"], reminder)\n\n    async def send_reminder(self, reminder: dict, late: relativedelta = None) -> None:\n        \"\"\"Send the reminder.\"\"\"\n        channel = self.bot.get_channel(reminder[\"channel_id\"])\n        user = self.bot.get_user(reminder[\"author\"])\n\n        embed = Embed()\n        embed.colour = Colour.blurple()\n        embed.set_author(\n            icon_url=Icons.remind_blurple,\n            name=\"It has arrived!\"\n        )\n\n        embed.description = f\"Here's your reminder: `{reminder['content']}`\"\n\n        if late:\n            embed.colour = Colour.red()\n            embed.set_author(\n                icon_url=Icons.remind_red,\n                name=f\"Sorry it arrived {humanize_delta(late, max_units=2)} late!\"\n            )\n\n        await channel.send(\n            content=user.mention,\n            embed=embed\n        )\n        await self._delete_reminder(reminder[\"id\"])\n\n    @group(name=\"remind\", aliases=(\"reminder\", \"reminders\"), invoke_without_command=True)\n    async def remind_group(self, ctx: Context, expiration: Duration, *, content: str) -> None:\n        \"\"\"Commands for managing your reminders.\"\"\"\n        await ctx.invoke(self.new_reminder, expiration=expiration, content=content)\n\n    @remind_group.command(name=\"new\", aliases=(\"add\", \"create\"))\n    async def new_reminder(self, ctx: Context, expiration: Duration, *, content: str) -> Optional[Message]:\n        \"\"\"\n        Set yourself a simple reminder.\n\n        Expiration is parsed per: http://strftime.org/\n        \"\"\"\n        embed = Embed()\n\n        # If the user is not staff, we need to verify whether or not to make a reminder at all.\n        if without_role_check(ctx, *STAFF_ROLES):\n\n            # If they don't have permission to set a reminder in this channel\n            if ctx.channel.id not in WHITELISTED_CHANNELS:\n                embed.colour = Colour.red()\n                embed.title = random.choice(NEGATIVE_REPLIES)\n                embed.description = \"Sorry, you can't do that here!\"\n\n                return await ctx.send(embed=embed)\n\n            # Get their current active reminders\n            active_reminders = await self.bot.api_client.get(\n                'bot/reminders',\n                params={\n                    'author__id': str(ctx.author.id)\n                }\n            )\n\n            # Let's limit this, so we don't get 10 000\n            # reminders from kip or something like that :P\n            if len(active_reminders) > MAXIMUM_REMINDERS:\n                embed.colour = Colour.red()\n                embed.title = random.choice(NEGATIVE_REPLIES)\n                embed.description = \"You have too many active reminders!\"\n\n                return await ctx.send(embed=embed)\n\n        # Now we can attempt to actually set the reminder.\n        reminder = await self.bot.api_client.post(\n            'bot/reminders',\n            json={\n                'author': ctx.author.id,\n                'channel_id': ctx.message.channel.id,\n                'content': content,\n                'expiration': expiration.isoformat()\n            }\n        )\n\n        # Confirm to the user that it worked.\n        await self._send_confirmation(\n            ctx, on_success=\"Your reminder has been created successfully!\"\n        )\n\n        loop = asyncio.get_event_loop()\n        self.schedule_task(loop, reminder[\"id\"], reminder)\n\n    @remind_group.command(name=\"list\")\n    async def list_reminders(self, ctx: Context) -> Optional[Message]:\n        \"\"\"View a paginated embed of all reminders for your user.\"\"\"\n        # Get all the user's reminders from the database.\n        data = await self.bot.api_client.get(\n            'bot/reminders',\n            params={'author__id': str(ctx.author.id)}\n        )\n\n        now = datetime.utcnow()\n\n        # Make a list of tuples so it can be sorted by time.\n        reminders = sorted(\n            (\n                (rem['content'], rem['expiration'], rem['id'])\n                for rem in data\n            ),\n            key=itemgetter(1)\n        )\n\n        lines = []\n\n        for content, remind_at, id_ in reminders:\n            # Parse and humanize the time, make it pretty :D\n            remind_datetime = datetime.fromisoformat(remind_at[:-1])\n            time = humanize_delta(relativedelta(remind_datetime, now))\n\n            text = textwrap.dedent(f\"\"\"\n            **Reminder #{id_}:** *expires in {time}* (ID: {id_})\n            {content}\n            \"\"\").strip()\n\n            lines.append(text)\n\n        embed = Embed()\n        embed.colour = Colour.blurple()\n        embed.title = f\"Reminders for {ctx.author}\"\n\n        # Remind the user that they have no reminders :^)\n        if not lines:\n            embed.description = \"No active reminders could be found.\"\n            return await ctx.send(embed=embed)\n\n        # Construct the embed and paginate it.\n        embed.colour = Colour.blurple()\n\n        await LinePaginator.paginate(\n            lines,\n            ctx, embed,\n            max_lines=3,\n            empty=True\n        )\n\n    @remind_group.group(name=\"edit\", aliases=(\"change\", \"modify\"), invoke_without_command=True)\n    async def edit_reminder_group(self, ctx: Context) -> None:\n        \"\"\"Commands for modifying your current reminders.\"\"\"\n        await ctx.invoke(self.bot.get_command(\"help\"), \"reminders\", \"edit\")\n\n    @edit_reminder_group.command(name=\"duration\", aliases=(\"time\",))\n    async def edit_reminder_duration(self, ctx: Context, id_: int, expiration: Duration) -> None:\n        \"\"\"\n         Edit one of your reminder's expiration.\n\n        Expiration is parsed per: http://strftime.org/\n        \"\"\"\n        # Send the request to update the reminder in the database\n        reminder = await self.bot.api_client.patch(\n            'bot/reminders/' + str(id_),\n            json={'expiration': expiration.isoformat()}\n        )\n\n        # Send a confirmation message to the channel\n        await self._send_confirmation(\n            ctx, on_success=\"That reminder has been edited successfully!\"\n        )\n\n        await self._reschedule_reminder(reminder)\n\n    @edit_reminder_group.command(name=\"content\", aliases=(\"reason\",))\n    async def edit_reminder_content(self, ctx: Context, id_: int, *, content: str) -> None:\n        \"\"\"Edit one of your reminder's content.\"\"\"\n        # Send the request to update the reminder in the database\n        reminder = await self.bot.api_client.patch(\n            'bot/reminders/' + str(id_),\n            json={'content': content}\n        )\n\n        # Send a confirmation message to the channel\n        await self._send_confirmation(\n            ctx, on_success=\"That reminder has been edited successfully!\"\n        )\n        await self._reschedule_reminder(reminder)\n\n    @remind_group.command(\"delete\", aliases=(\"remove\",))\n    async def delete_reminder(self, ctx: Context, id_: int) -> None:\n        \"\"\"Delete one of your active reminders.\"\"\"\n        await self._delete_reminder(id_)\n        await self._send_confirmation(\n            ctx, on_success=\"That reminder has been deleted successfully!\"\n        )\n\n\ndef setup(bot: Bot) -> None:\n    \"\"\"Reminders cog load.\"\"\"\n    bot.add_cog(Reminders(bot))\n    log.info(\"Cog loaded: Reminders\")\n", "path": "bot/cogs/reminders.py"}]}