Compare commits
1 Commits
177ec2c783
...
a896fbe38a
Author | SHA1 | Date | |
---|---|---|---|
a896fbe38a |
@ -40,15 +40,11 @@ jobs:
|
||||
|
||||
- name: Install dependencies
|
||||
run: uv sync
|
||||
|
||||
# - name: Lint
|
||||
# run: |
|
||||
# uv run pylint --fail-under=8 --recursive=yes --output-format=parseable --output=lintreport.txt app/ tests/
|
||||
# cat lintreport.txt
|
||||
|
||||
- name: Lint
|
||||
run: |
|
||||
uv run pylint --fail-under=8 --recursive=yes --output-format=parseable app/ tests/
|
||||
uv run pylint --fail-under=8 --recursive=yes --output-format=parseable app/ tests/ # --output=lintreport.txt
|
||||
cat lintreport.txt
|
||||
|
||||
- name: Unit Test
|
||||
run: |
|
||||
|
14
app/close.py
14
app/close.py
@ -1,13 +1,8 @@
|
||||
"""Command module for handling the 'exit' command in the Webex meme bot."""
|
||||
|
||||
from webex_bot.models.command import Command
|
||||
|
||||
|
||||
class ExitCommand(Command):
|
||||
"""Command to handle the 'exit' command in the Webex meme bot."""
|
||||
|
||||
def __init__(self) -> None:
|
||||
"""Initialize the ExitCommand with command keyword and help message."""
|
||||
super().__init__(
|
||||
command_keyword="exit",
|
||||
help_message="Exit",
|
||||
@ -15,14 +10,11 @@ class ExitCommand(Command):
|
||||
)
|
||||
self.sender: str = ""
|
||||
|
||||
def pre_execute(self, message, attachment_actions, activity) -> None: # pylint: disable=unused-argument
|
||||
"""Pre-execution logic for the exit command."""
|
||||
def pre_execute(self, message, attachment_actions, activity) -> None:
|
||||
return
|
||||
|
||||
def execute(self, message, attachment_actions, activity) -> None: # pylint: disable=unused-argument
|
||||
"""Execute the exit command."""
|
||||
def execute(self, message, attachment_actions, activity) -> None:
|
||||
return
|
||||
|
||||
def post_execute(self, message, attachment_actions, activity) -> None: # pylint: disable=unused-argument
|
||||
"""Post-execution logic for the exit command."""
|
||||
def post_execute(self, message, attachment_actions, activity) -> None:
|
||||
return
|
||||
|
29
app/img.py
29
app/img.py
@ -1,5 +1,3 @@
|
||||
"""Generates meme images using the memegen.link API."""
|
||||
|
||||
import requests
|
||||
|
||||
CHAR_REPLACEMENTS: list = [
|
||||
@ -19,11 +17,6 @@ CHAR_REPLACEMENTS: list = [
|
||||
|
||||
|
||||
def get_templates() -> list[dict]:
|
||||
"""Fetches available meme templates from the memegen.link API.
|
||||
|
||||
Returns:
|
||||
list[dict]: A list of dictionaries containing meme template information.
|
||||
"""
|
||||
url: str = "https://api.memegen.link/templates"
|
||||
req: requests.Response = requests.get(url=url, timeout=10)
|
||||
req.raise_for_status()
|
||||
@ -47,14 +40,6 @@ def get_templates() -> list[dict]:
|
||||
|
||||
|
||||
def format_meme_string(input_string: str) -> str:
|
||||
"""Formats a string for use in a meme image URL.
|
||||
|
||||
Args:
|
||||
input_string (str): The string to format.
|
||||
|
||||
Returns:
|
||||
str: The formatted string suitable for meme image URLs.
|
||||
"""
|
||||
# https://memegen.link/#special-characters
|
||||
out_string: str = input_string
|
||||
for char_replacement in CHAR_REPLACEMENTS:
|
||||
@ -63,16 +48,6 @@ def format_meme_string(input_string: str) -> str:
|
||||
|
||||
|
||||
def generate_api_url(template: str, top_str: str, btm_str: str) -> str:
|
||||
"""Generates a meme image URL using the memegen.link API.
|
||||
|
||||
Args:
|
||||
template (str): The template identifier in the format "name.ext".
|
||||
top_str (str): The text for the top line of the meme.
|
||||
btm_str (str): The text for the bottom line of the meme.
|
||||
|
||||
Returns:
|
||||
str: The complete URL for the meme image.
|
||||
"""
|
||||
tmpl_name: str
|
||||
tmpl_ext: str
|
||||
tmpl_name, tmpl_ext = template.split(".")
|
||||
@ -80,5 +55,7 @@ def generate_api_url(template: str, top_str: str, btm_str: str) -> str:
|
||||
top_str = format_meme_string(top_str)
|
||||
btm_str = format_meme_string(btm_str)
|
||||
|
||||
url: str = f"https://api.memegen.link/images/{tmpl_name}/{top_str}/{btm_str}.{tmpl_ext}"
|
||||
url: str = (
|
||||
f"https://api.memegen.link/images/{tmpl_name}/{top_str}/{btm_str}.{tmpl_ext}"
|
||||
)
|
||||
return url
|
||||
|
@ -1,7 +1,5 @@
|
||||
#!/usr/local/bin/python3
|
||||
|
||||
"""Main entry point for the Webex Bot application."""
|
||||
|
||||
from webex_bot.webex_bot import WebexBot
|
||||
|
||||
from app import close, meme
|
||||
@ -20,7 +18,6 @@ def create_bot() -> WebexBot:
|
||||
|
||||
|
||||
def main() -> None:
|
||||
"""Main function to run the Webex Bot."""
|
||||
bot: WebexBot = create_bot()
|
||||
bot.add_command(meme.MakeMemeCommand())
|
||||
bot.add_command(close.ExitCommand())
|
||||
|
32
app/meme.py
32
app/meme.py
@ -1,5 +1,3 @@
|
||||
"""Generates meme images using the memegen.link API."""
|
||||
|
||||
from webex_bot.models.command import Command
|
||||
from webex_bot.models.response import Response, response_from_adaptive_card
|
||||
from webexteamssdk.models.cards import (
|
||||
@ -24,7 +22,6 @@ class MakeMemeCommand(Command):
|
||||
"""Class for initial Webex interactive card."""
|
||||
|
||||
def __init__(self) -> None:
|
||||
"""Initialize the MakeMemeCommand with command keyword and help message."""
|
||||
super().__init__(
|
||||
command_keyword="/meme",
|
||||
help_message="Make a Meme",
|
||||
@ -32,12 +29,10 @@ class MakeMemeCommand(Command):
|
||||
delete_previous_message=True,
|
||||
)
|
||||
|
||||
def pre_execute(self, message, attachment_actions, activity) -> None: # pylint: disable=unused-argument
|
||||
"""Pre-execution logic for the MakeMemeCommand."""
|
||||
def pre_execute(self, message, attachment_actions, activity) -> None:
|
||||
return
|
||||
|
||||
def execute(self, message, attachment_actions, activity) -> Response: # pylint: disable=unused-argument
|
||||
"""Execute the MakeMemeCommand and return an adaptive card."""
|
||||
def execute(self, message, attachment_actions, activity) -> Response:
|
||||
card_body: list = [
|
||||
ColumnSet(
|
||||
columns=[
|
||||
@ -50,13 +45,13 @@ class MakeMemeCommand(Command):
|
||||
size=FontSize.MEDIUM,
|
||||
),
|
||||
TextBlock(
|
||||
"This bot uses memegen.link to generate memes. Click 'View Templates' to view available templates.", # pylint: disable=line-too-long
|
||||
"This bot uses memegen.link to generate memes. Click 'View Templates' to view available templates.",
|
||||
weight=FontWeight.LIGHTER,
|
||||
size=FontSize.SMALL,
|
||||
wrap=True,
|
||||
),
|
||||
TextBlock(
|
||||
"Both fields are required. If you do not want to specify a value, please type a space.", # pylint: disable=line-too-long
|
||||
"Both fields are required. If you do not want to specify a value, please type a space.",
|
||||
weight=FontWeight.LIGHTER,
|
||||
size=FontSize.SMALL,
|
||||
wrap=True,
|
||||
@ -73,7 +68,10 @@ class MakeMemeCommand(Command):
|
||||
Choices(
|
||||
id="meme_type",
|
||||
isMultiSelect=False,
|
||||
choices=[Choice(title=x["name"], value=x["choiceval"]) for x in TEMPLATES],
|
||||
choices=[
|
||||
Choice(title=x["name"], value=x["choiceval"])
|
||||
for x in TEMPLATES
|
||||
],
|
||||
),
|
||||
Text(id="text_top", placeholder="Top Text", maxLength=100),
|
||||
Text(
|
||||
@ -105,7 +103,6 @@ class MakeMemeCallback(Command):
|
||||
"""Class to process user data and return meme."""
|
||||
|
||||
def __init__(self) -> None:
|
||||
"""Initialize the MakeMemeCallback with command keyword and help message."""
|
||||
super().__init__(
|
||||
card_callback_keyword="make_meme_callback_rbamzfyx",
|
||||
delete_previous_message=True,
|
||||
@ -116,8 +113,7 @@ class MakeMemeCallback(Command):
|
||||
self.meme: str = ""
|
||||
self.meme_filename: str = ""
|
||||
|
||||
def pre_execute(self, message, attachment_actions, activity) -> str: # pylint: disable=unused-argument
|
||||
"""Pre-execution logic for the MakeMemeCallback."""
|
||||
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")
|
||||
@ -131,12 +127,13 @@ class MakeMemeCallback(Command):
|
||||
|
||||
return "Generating your meme..."
|
||||
|
||||
def execute(self, message, attachment_actions, activity) -> Response | None: # pylint: disable=unused-argument
|
||||
"""Execute the MakeMemeCallback and return a response with the meme image."""
|
||||
def execute(self, message, attachment_actions, activity) -> Response | None:
|
||||
if self.error:
|
||||
return None
|
||||
|
||||
self.meme_filename: str = img.generate_api_url(self.meme, self.text_top, self.text_bottom)
|
||||
self.meme_filename: str = img.generate_api_url(
|
||||
self.meme, self.text_top, self.text_bottom
|
||||
)
|
||||
msg: Response = Response(
|
||||
attributes={
|
||||
"roomId": activity["target"]["globalId"],
|
||||
@ -146,6 +143,5 @@ class MakeMemeCallback(Command):
|
||||
)
|
||||
return msg
|
||||
|
||||
def post_execute(self, message, attachment_actions, activity) -> None: # pylint: disable=unused-argument
|
||||
"""Post-execution logic for the MakeMemeCallback."""
|
||||
def post_execute(self, message, attachment_actions, activity) -> None:
|
||||
return
|
||||
|
@ -32,6 +32,3 @@ includes = []
|
||||
[build-system]
|
||||
requires = ["pdm-backend"]
|
||||
build-backend = "pdm.backend"
|
||||
|
||||
[tool.black]
|
||||
line-length = 120
|
||||
|
@ -2,22 +2,19 @@
|
||||
|
||||
import os
|
||||
|
||||
env_vars: dict = {
|
||||
vars: dict = {
|
||||
"APP_VERSION": "dev",
|
||||
"WEBEX_API_KEY": "testing",
|
||||
}
|
||||
|
||||
|
||||
for var, value in env_vars.items():
|
||||
for var, value in vars.items():
|
||||
os.environ[var] = value
|
||||
|
||||
# needs to be imported AFTER environment variables are set
|
||||
from app.config import (
|
||||
config,
|
||||
) # pylint: disable=wrong-import-position # pragma: no cover # noqa: E402
|
||||
from app.config import config # pragma: no cover # noqa: E402
|
||||
|
||||
|
||||
def test_config() -> None:
|
||||
"""Test the configuration settings."""
|
||||
assert config.webex_token == env_vars["WEBEX_API_KEY"]
|
||||
assert config.version == env_vars["APP_VERSION"]
|
||||
assert config.webex_token == vars["WEBEX_API_KEY"]
|
||||
assert config.version == vars["APP_VERSION"]
|
||||
|
@ -29,4 +29,8 @@ def test_error_false() -> None:
|
||||
callback.text_top = "TEST"
|
||||
callback.text_bottom = "TEST"
|
||||
result: Response = callback.execute(None, None, {"target": {"globalId": "TEST"}})
|
||||
assert isinstance(result, Response) and result.roomId == "TEST" and result.files[0] == callback.meme_filename
|
||||
assert (
|
||||
isinstance(result, Response)
|
||||
and result.roomId == "TEST"
|
||||
and result.files[0] == callback.meme_filename
|
||||
)
|
||||
|
Loading…
x
Reference in New Issue
Block a user