Browse Source

Add post!

tags/v1.0.0
parent
commit
ab1a893611
Signed by: StDingenskirchen GPG Key ID: 14FE9712CC42FE8B
6 changed files with 151 additions and 5 deletions
  1. +8
    -0
      blimp/__main__.py
  2. +66
    -2
      blimp/cogs/tools.py
  3. +65
    -0
      blimp/message_formatter.py
  4. +2
    -2
      poetry.lock
  5. +1
    -0
      pyproject.toml
  6. +9
    -1
      schema.sql

+ 8
- 0
blimp/__main__.py View File

@@ -49,9 +49,17 @@ for cog in [
async def on_ready():
"""Hello world."""
bot.log.info(f"Logged in as {bot.user}")

bot.add_cog(cogs.Reminders(bot))
bot.owner_id = (await bot.application_info()).owner.id

# we can't use fstrings in docstrings, so insert the manual link manually here
post_command = [c for c in bot.commands if c.name[:-1] == "post"][0]
post_command.help = post_command.help.replace(
"MANUALLINKHERE",
f"[extended message formatting]({bot.config['info']['manual']}#extended-post-format)",
)


@bot.command(name="help")
async def _help(ctx: Blimp.Context, *, subject: Optional[str]):


+ 66
- 2
blimp/cogs/tools.py View File

@@ -1,11 +1,17 @@
import asyncio
from typing import Optional
from typing import Optional, Union

import discord
from discord.ext import commands
import toml

from ..customizations import Blimp, ParseableTimedelta
from .aliasing import MaybeAliasedCategoryChannel, MaybeAliasedTextChannel
from .aliasing import (
MaybeAliasedCategoryChannel,
MaybeAliasedTextChannel,
MaybeAliasedMessage,
)
from ..message_formatter import create_message_dict


class Tools(Blimp.Cog):
@@ -141,3 +147,61 @@ class Tools(Blimp.Cog):

await ctx.bot.post_log(channel.guild, embed=log_embed)
await ctx.reply(f"Updated channel name for {channel.mention}.")

@commands.command()
async def post(
self,
ctx: Blimp.Context,
where: Union[MaybeAliasedTextChannel, MaybeAliasedMessage],
*,
text: str,
):
"""Make the bot post something.

<where> may be a channel or a message created by this command to update.
<text> may be either plain text for the message content or TOML data for MANUALLINKHERE."""

if not ctx.privileged_modify(where.guild):
return

try:
text = toml.dumps(toml.loads(text))
except toml.TomlDecodeError:
pass

if isinstance(where, discord.TextChannel):
message = await where.send(**create_message_dict(text))
ctx.database.execute(
"INSERT INTO post_entries(message_oid, text) VALUES(:oid, :text)",
{
"oid": ctx.objects.make_object(m=[message.channel.id, message.id]),
"text": text,
},
)
else:
old = ctx.database.execute(
"SELECT * FROM post_entries WHERE message_oid=:oid",
{"oid": ctx.objects.by_data(m=[where.channel.id, where.id])},
).fetchone()
if not old:
return

log_embed = (
discord.Embed(
description=f"{ctx.author} updated "
f"[BLIMP post in #{where.channel.name}]({where.jump_url}).",
color=ctx.Color.I_GUESS,
)
.add_field(name="Old", value=old["text"])
.add_field(name="New", value=text)
)

ctx.database.execute(
"UPDATE post_entries SET text=:text WHERE message_oid=:oid",
{
"text": text,
"oid": ctx.objects.by_data(m=[where.channel.id, where.id]),
},
)
await where.edit(**create_message_dict(text))
await ctx.bot.post_log(where.guild, embed=log_embed)

+ 65
- 0
blimp/message_formatter.py View File

@@ -0,0 +1,65 @@
import discord
from toml import loads, TomlDecodeError

from .customizations import Blimp


def create_message_dict(text: str) -> dict:
"Turn a string into a dict that can be deconstructed into a message create/edit call."

try:
return message_dict_from_toml(loads(text))
except TomlDecodeError:
return {"content": text}


def message_dict_from_toml(toml: dict) -> dict:
"Turn a TOML-supplied dict into message create/edit call dict."
output = {"content": toml.get("content")}

embed_data = toml.get("embed")
if embed_data:
output["embed"] = discord.Embed(
title=embed_data.get("title"),
description=embed_data.get("description"),
url=embed_data.get("url"),
)

color = embed_data.get("color")
if color and isinstance(color, int) and color in range(0, (0xFF_FF_FF + 1)):
output["embed"].color = color
elif isinstance(color, str) and color in dir(Blimp.Context.Color):
output["embed"].color = Blimp.Context.Color[color]

footer = embed_data.get("footer")
if isinstance(footer, dict):
output["embed"].set_footer(
text=footer.get("text", discord.Embed.Empty),
icon_url=footer.get("icon_url", discord.Embed.Empty),
)

image = embed_data.get("image_url")
if isinstance(image, str):
output["embed"].set_image(url=image)

thumbnail = embed_data.get("thumbnail_url")
if isinstance(thumbnail, str):
output["embed"].set_thumbnail(url=thumbnail)

author = embed_data.get("author")
if isinstance(author, dict):
output["embed"].set_author(
name=author.get("name", discord.Embed.Empty),
icon_url=author.get("icon_url", discord.Embed.Empty),
)

fields = embed_data.get("fields")
if isinstance(fields, list):
for field in fields:
output["embed"].add_field(
name=field["name"],
value=field["value"],
inline=field.get("inline", False),
)

return output

+ 2
- 2
poetry.lock View File

@@ -219,7 +219,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
version = "1.15.0"

[[package]]
category = "dev"
category = "main"
description = "Python Library for Tom's Obvious, Minimal Language"
name = "toml"
optional = false
@@ -275,7 +275,7 @@ python = "<3.8"
version = ">=3.7.4"

[metadata]
content-hash = "ad41d14a017ede38d9c2a80fa5330780dbcfbd2f3a5a17115589209eb14558de"
content-hash = "8a0fa15f87d5ffac1332de194cc1959b5cb39dcdfd3e04b079374e55d38b46af"
python-versions = "^3.7"

[metadata.files]


+ 1
- 0
pyproject.toml View File

@@ -8,6 +8,7 @@ license = "AGPL-3.0"
[tool.poetry.dependencies]
python = "^3.7"
"discord.py" = "~1.3"
toml = "^0.10.1"

[tool.poetry.dev-dependencies]
black = "^20.8b1"


+ 9
- 1
schema.sql View File

@@ -132,5 +132,13 @@ CREATE TABLE IF NOT EXISTS trigger_entries (
command STRING NOT NULL,

FOREIGN KEY (message_oid) REFERENCES objects(oid),
PRIMARY KEY(message_oid, emoji)
PRIMARY KEY (message_oid, emoji)
);

CREATE TABLE IF NOT EXISTS post_entries (
message_oid INTEGER NOT NULL,
text STRING NOT NULL,

FOREIGN KEY (message_oid) REFERENCES objects(oid),
PRIMARY KEY (message_oid)
);

Loading…
Cancel
Save