Implement gist-based pinboard - creates a gist for each channel that allows user pins

This commit is contained in:
roblabla 2019-03-03 14:29:46 +01:00
parent 4e0e26b1f9
commit 1fe7e21986
3 changed files with 54 additions and 17 deletions

View file

@ -1,7 +1,11 @@
import config import config
from discord.ext.commands import Cog from discord.ext.commands import Cog
from discord.enums import MessageType from discord.enums import MessageType
from discord import Embed
import aiohttp
import gidgethub.aiohttp
from helpers.checks import check_if_collaborator
from helpers.checks import check_if_pin_channel
class Pin(Cog): class Pin(Cog):
""" """
@ -11,16 +15,37 @@ class Pin(Cog):
def __init__(self, bot): def __init__(self, bot):
self.bot = bot self.bot = bot
async def get_pinboard(self, gh, channel):
# Find pinboard pin
pinboard_msg = None
for msg in reversed(await channel.pins()):
if msg.author == self.bot.user and len(msg.embeds) > 0 and msg.embeds[0].title == "Pinboard":
# Found pinboard, return content and gist id
id = msg.embeds[0].url.split("/")[-1]
data = await gh.getitem(f"/gists/{id}")
return (id, data["files"]["pinboard.md"]["content"])
# Create pinboard pin if it does not exist
data = await gh.post("/gists", data={"files": {"pinboard.md": {"content": "Old pins are available here:\n\n"}}, "description": f"Pinboard for SwitchRoot #{channel.name}", "public": True})
msg = await channel.send(embed=Embed(title="Pinboard", description="Old pins are moved to the pinboard to make space for new ones. Check it out!", url=data["html_url"]))
await msg.pin()
return (data["id"], data["files"]["pinboard.md"]["content"])
async def add_pin_to_pinboard(self, channel, data):
if config.github_oauth_token == "":
# Don't add to gist pinboard if we don't have an oauth token
return
async with aiohttp.ClientSession() as session:
gh = gidgethub.aiohttp.GitHubAPI(session, "RoboCop-NG", oauth_token=config.github_oauth_token)
(id, content) = await self.get_pinboard(gh, channel)
content += "- " + data + "\n"
await gh.patch(f"/gists/{id}", data={"files": {"pinboard.md": {"content": content}}})
# Use raw_reaction to allow pinning old messages. # Use raw_reaction to allow pinning old messages.
@Cog.listener() @Cog.listener()
async def on_raw_reaction_add(self, payload): async def on_raw_reaction_add(self, payload):
# TODO: handle more than 50 pinned message
# BODY: If there are more than 50 pinned messages,
# BODY: we should move the oldest pin to a pinboard
# BODY: channel to make room for the new pin.
# BODY: This is why we use the pin reaction to remember
# BODY: that a message is pinned.
# Check that the user wants to pin this message # Check that the user wants to pin this message
if payload.emoji.name not in ["📌", "📍"]: if payload.emoji.name not in ["📌", "📍"]:
return return
@ -45,8 +70,15 @@ class Pin(Cog):
if reaction.emoji == "📌": if reaction.emoji == "📌":
if reaction.me: if reaction.me:
return return
else:
break break
# Add pin to pinboard, create one if none is found
await self.add_pin_to_pinboard(target_chan, target_msg.jump_url)
# Avoid staying "stuck" waiting for the pin message if message
# was already manually pinned
if not target_msg.pinned:
# Wait for the automated "Pinned" message so we can delete it # Wait for the automated "Pinned" message so we can delete it
waitable = self.bot.wait_for('message', check=check) waitable = self.bot.wait_for('message', check=check)

View file

@ -94,3 +94,6 @@ spy_channels = general_channels
# Channels and roles where users can pin messages # Channels and roles where users can pin messages
allowed_pin_channels = [] allowed_pin_channels = []
allowed_pin_roles = [] allowed_pin_roles = []
# Used for the pinboard. Leave empty if you don't wish for a gist pinboard.
github_oauth_token = ""

View file

@ -4,3 +4,5 @@ asyncio
python-dateutil python-dateutil
humanize humanize
parsedatetime parsedatetime
aiohttp
gidgethub