This commit is contained in:
2023-07-21 22:57:14 +01:00
parent df927977ba
commit 57f0bb9371
16 changed files with 1963 additions and 19 deletions

20
webexmemebot/exit.py Normal file
View File

@ -0,0 +1,20 @@
from webex_bot.models.command import Command
class ExitCommand(Command):
def __init__(self) -> None:
super().__init__(
command_keyword="exit",
help_message="Exit",
delete_previous_message=True,
)
self.sender: str = ""
def pre_execute(self, message, attachment_actions, activity) -> None:
return
def execute(self, message, attachment_actions, activity) -> None:
return
def post_execute(self, message, attachment_actions, activity) -> None:
return

61
webexmemebot/img.py Normal file
View File

@ -0,0 +1,61 @@
import requests
def get_templates() -> list[dict]:
url: str = "https://api.memegen.link/templates"
req: requests.Response = requests.get(url=url, timeout=5)
req.raise_for_status()
data: dict = req.json()
templates: list = []
for tmpl in data:
if tmpl["lines"] != 2:
continue
if tmpl["id"] == "oprah":
tmpl["name"] = "Oprah You Get A..."
tmpl_ext: str = "gif" if "animated" in tmpl["styles"] else "jpg"
tmpl_data: dict = {
"id": tmpl["id"],
"name": tmpl["name"],
"ext": tmpl_ext,
"choiceval": tmpl["id"] + "." + tmpl_ext,
}
templates.append(tmpl_data)
templates = sorted(templates, key=lambda d: d["name"])
return templates
def generate_api_url(template: str, top_str: str, btm_str: str) -> str:
tmpl_name, tmpl_ext = template.split(".")
# https://memegen.link/#special-characters
top_str = top_str.replace("_", "__")
top_str = top_str.replace("-", "--")
top_str = top_str.replace(" ", "_")
top_str = top_str.replace("?", "~q")
top_str = top_str.replace("&", "~a")
top_str = top_str.replace("%", "~p")
top_str = top_str.replace("#", "~h")
top_str = top_str.replace("/", "~s")
top_str = top_str.replace("\\", "~b")
top_str = top_str.replace("<", "~l")
top_str = top_str.replace(">", "~g")
top_str = top_str.replace('"', "''")
btm_str = btm_str.replace("_", "__")
btm_str = btm_str.replace("-", "--")
btm_str = btm_str.replace(" ", "_")
btm_str = btm_str.replace("?", "~q")
btm_str = btm_str.replace("&", "~a")
btm_str = btm_str.replace("%", "~p")
btm_str = btm_str.replace("#", "~h")
btm_str = btm_str.replace("/", "~s")
btm_str = btm_str.replace("\\", "~b")
btm_str = btm_str.replace("<", "~l")
btm_str = btm_str.replace(">", "~g")
btm_str = btm_str.replace('"', "''")
url: str = (
f"https://api.memegen.link/images/{tmpl_name}/{top_str}/{btm_str}.{tmpl_ext}"
)
return url

34
webexmemebot/main.py Normal file
View File

@ -0,0 +1,34 @@
#!/usr/local/bin/python3
import os
from webex_bot.webex_bot import WebexBot
from webexmemebot import exit, meme
WBX_API_KEY: str = os.environ["WEBEX_API_KEY"]
def create_bot() -> WebexBot:
"""Create a Bot object."""
bot = WebexBot(
teams_bot_token=WBX_API_KEY,
approved_domains=["cisco.com"],
bot_name="MemeBot",
include_demo_commands=False,
)
return bot
def main():
bot: WebexBot = create_bot()
bot.add_command(meme.MakeMemeCommand())
bot.add_command(exit.ExitCommand())
bot.commands.remove(bot.help_command)
bot.help_command = meme.MakeMemeCommand()
bot.run()
if __name__ == "__main__":
main()

142
webexmemebot/meme.py Normal file
View File

@ -0,0 +1,142 @@
import json
from webex_bot.models.command import Command
from webex_bot.models.response import Response, response_from_adaptive_card
from webexteamssdk.models.cards import (
AdaptiveCard,
Column,
ColumnSet,
FontSize,
FontWeight,
Text,
TextBlock,
Choice,
Choices,
)
from webexteamssdk.models.cards.actions import Submit, OpenUrl
from webexmemebot import img
TEMPLATES = img.get_templates()
class MakeMemeCommand(Command):
def __init__(self) -> None:
super().__init__(
command_keyword="/meme",
help_message="Make a Meme",
chained_commands=[MakeMemeCallback()],
delete_previous_message=True,
)
def pre_execute(self, message, attachment_actions, activity) -> None:
return
def execute(self, message, attachment_actions, activity) -> Response:
card_body: list = [
ColumnSet(
columns=[
Column(
width=1,
items=[
TextBlock(
"Make a Meme",
weight=FontWeight.BOLDER,
size=FontSize.MEDIUM,
),
TextBlock(
"This bot uses memegen.link to generate memes.",
weight=FontWeight.LIGHTER,
size=FontSize.SMALL,
),
TextBlock(
"Click 'View Templates' to view available templates.",
weight=FontWeight.LIGHTER,
size=FontSize.SMALL,
),
],
),
]
),
ColumnSet(
columns=[
Column(
width=1,
items=[
Choices(
id="meme_type",
isMultiSelect=False,
choices=[
Choice(title=x["name"], value=x["choiceval"])
for x in TEMPLATES
],
),
Text(id="text_top", placeholder="Top Text", maxLength=100),
Text(
id="text_bottom",
placeholder="Bottom Text",
maxLength=100,
),
],
),
]
),
]
card: AdaptiveCard = AdaptiveCard(
body=card_body,
actions=[
Submit(
title="Go!",
data={"callback_keyword": "make_meme_callback_rbamzfyx"},
),
OpenUrl(url="https://memegen.link/#templates", title="View Templates"),
Submit(title="Cancel", data={"command_keyword": "exit"}),
],
)
return response_from_adaptive_card(card)
class MakeMemeCallback(Command):
def __init__(self) -> None:
super().__init__(
card_callback_keyword="make_meme_callback_rbamzfyx",
delete_previous_message=True,
)
self.error: bool = False
self.text_top: str = ""
self.text_bottom: str = ""
self.meme: str = ""
self.meme_filename: str = ""
def pre_execute(self, message, attachment_actions, activity) -> str:
self.meme: str = attachment_actions.inputs.get("meme_type")
self.text_top: str = attachment_actions.inputs.get("text_top")
self.text_bottom: str = attachment_actions.inputs.get("text_bottom")
if not self.text_top and not self.text_bottom:
self.error = True
return "Please provide at least one positional text argument."
if ".gif" in self.meme:
return "Generating your meme. GIF-based memes take a little longer. Please wait..."
return "Generating your meme..."
def execute(self, message, attachment_actions, activity) -> str:
if not self.error:
self.meme_filename: str = img.generate_api_url(
self.meme, self.text_top, self.text_bottom
)
msg: Response = Response(
attributes={
"roomId": activity["target"]["globalId"],
"parentId": "",
"files": [self.meme_filename],
}
)
return msg
def post_execute(self, message, attachment_actions, activity) -> None:
return