-
Notifications
You must be signed in to change notification settings - Fork 10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Collapse long messages into gist command #362
Changes from 9 commits
25e4069
76bf201
5dab69e
d8f3ec9
408d6b8
7da5791
d205943
aa2ab41
bd275a3
9e03516
8007f9b
54bb0ae
78411d2
ad00df6
4a21268
e325735
d12b2a7
306fae2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -34,6 +34,7 @@ | |
str_builder, | ||
unicode, | ||
utils, | ||
gist, | ||
) | ||
|
||
__version__ = "0.6.2" |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,8 +21,8 @@ | |
import discord | ||
from discord.ext import commands | ||
|
||
from futaba import permissions | ||
from futaba.converters import MemberConv, UserConv | ||
from futaba import permissions, gist | ||
from futaba.converters import MemberConv, UserConv, MessageConv | ||
from futaba.enums import PunishAction | ||
from futaba.exceptions import CommandFailed, ManualCheckFailure | ||
from futaba.navi import PunishTask | ||
|
@@ -439,3 +439,41 @@ async def unban(self, ctx, user: UserConv, *, reason: str): | |
raise ManualCheckFailure( | ||
content="I don't have permission to unban this user" | ||
) | ||
|
||
@commands.command(name="msgcollapse", aliases=["gist"]) | ||
@commands.guild_only() | ||
async def msgcollapse(self, ctx, *messages: MessageConv): | ||
""" | ||
Concatenates the range of messages and uploads to a gist. | ||
The original messages are deleted and a link to the gist is posted. | ||
|
||
Note: The messages specified should be by the same user | ||
""" | ||
|
||
if not self.bot.config.gist_oauth_token: | ||
raise CommandFailed(content="The gist oauth token is not configured.") | ||
|
||
if not permissions.has_perm(ctx, "manage_messages") and any( | ||
message.author.id != ctx.author.id for message in messages | ||
): | ||
# check if the messages were created by the same user | ||
raise ManualCheckFailure(content="I can only collapse your messages") | ||
|
||
logger.info("Collapsing %d messages into a gist", len(messages)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add the guild ID and the user ID requesting it, and possibly the message IDs that were requested as well. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
|
||
gist_url = await gist.create_single_gist( | ||
token=self.bot.config.gist_oauth_token, | ||
content=" \n".join(str(message.content) for message in messages), | ||
filename="collapsed.md", | ||
description="Discord collapsed messages", | ||
public=False, | ||
) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As mentioned above, I would recommend a generic method on There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So should I add these & token into settings(cog & sql)? Or maybe move the whole functionality into like an optional cog so that it's distinct from moderation, and would use the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This can be in the main cog I think, I'm just suggesting you have a helper method for creating gists. This way it's easier for other parts of the bot in the future to also use it without violating DRY. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh ok, I just thought that there might be an issue with storing the github token in the main config because the bot might be used by multiple guilds. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is it okay that the helper method is also a command? Because otherwise it would just be a passthrough method. I also changed the in-code string literals to configuration options. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. futaba is only in 3 guilds, however having the allowing a github token per guild would be fine, lets the guild manage the gists created, a help method was just suggested in case we want other thing to be added to a gist that way it can be managed in one place |
||
|
||
embed = discord.Embed(description="Done! Messages successfully collapsed!") | ||
embed.add_field(name="Permalink", value=gist_url) | ||
embed.colour = discord.Colour.dark_teal() | ||
|
||
for message in messages: | ||
await message.delete() | ||
|
||
await ctx.send(embed=embed) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
# | ||
# gist.py | ||
# | ||
# futaba - A Discord Mod bot for the Programming server | ||
# Copyright (c) 2017-2020 Jake Richardson, Ammon Smith, jackylam5 | ||
# | ||
# futaba is available free of charge under the terms of the MIT | ||
# License. You are free to redistribute and/or modify it under those | ||
# terms. It is distributed in the hopes that it will be useful, but | ||
# WITHOUT ANY WARRANTY. See the LICENSE file for more details. | ||
# | ||
|
||
import logging | ||
import urllib.parse | ||
|
||
import aiohttp | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
__all__ = ["create_single_gist"] | ||
|
||
github_api_url = "https://api.github.com/" | ||
github_gist_endpoint = urllib.parse.urljoin(github_api_url, "/gists") | ||
|
||
|
||
async def create_single_gist( | ||
token, content, filename="message.md", description="", public: bool = True | ||
) -> str: | ||
""" | ||
Creates a new gist as specified by the parameters | ||
Returns the url that the new gist can be accessed by | ||
""" | ||
|
||
github_headers = { | ||
"Accept": "application/vnd.github.v3+json", | ||
"Authorization": f"token {token}", | ||
} | ||
request_data = { | ||
"description": description, | ||
"public": public, | ||
"files": {filename: {"content": content}}, | ||
} | ||
|
||
async with aiohttp.ClientSession( | ||
headers=github_headers, raise_for_status=True | ||
) as session: | ||
async with session.post(github_gist_endpoint, json=request_data) as resp: | ||
response_object = await resp.json() | ||
return response_object.get("html_url") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had a thought: we could have
!gist
create a gist of arbitrary messages kind of like!msg
does, and then have!mvgist
or something that does what this currently performs. Then you have a generic helper method do the actual gist-ing. This can be a separate PR ofc.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done, since I was splitting the command into a helper function, it might as well be its own command.