v0.1.0
This commit is contained in:
20
webexmemebot/exit.py
Normal file
20
webexmemebot/exit.py
Normal 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
61
webexmemebot/img.py
Normal 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
34
webexmemebot/main.py
Normal 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
142
webexmemebot/meme.py
Normal 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
|
Reference in New Issue
Block a user