Browse Source

Implement riddle

Kirk Trombley 4 years ago
parent
commit
4c83f8c9fa
2 changed files with 46 additions and 1 deletions
  1. 2 0
      drivers/command_driver.py
  2. 44 1
      src/commands/querying.py

+ 2 - 0
drivers/command_driver.py

@@ -14,6 +14,8 @@ class TerminalBot(rollbot.Rollbot[str]):
     def read_config(self, key):
         if key == "democracy.candidates":
             return ["cand1", "cand2"]
+        if key == "riddle.sleep":
+            return 10
         return key
 
     def parse(self, raw):

+ 44 - 1
src/commands/querying.py

@@ -1,10 +1,11 @@
 from logging import Logger
+import random
 import asyncio
 
 from bs4 import BeautifulSoup
 
 from rollbot import as_command, RollbotFailure, Attachment
-from rollbot.injection import Request, Args, Arg
+from rollbot.injection import Request, Args, Arg, Config
 
 
 @as_command
@@ -79,3 +80,45 @@ async def scp(
 
     obj_class, title = await asyncio.gather(get_obj_class(), get_title())
     return f"Item # {number}\n{obj_class}\n{title}\n{page_url}"
+
+
+@as_command
+async def riddle(args: Args, req: Request, logger: Logger, sleep: Config("riddle.sleep")):
+    if args.lower() != "me piss":
+        RollbotFailure.INVALID_ARGUMENTS.raise_exc()
+
+    rnum = None
+    riddle = None
+    for n in range(20):
+        rnum = random.randint(2, 10050)
+        async with req.get(f"https://www.riddles.com/{rnum}") as res:
+            riddle_page = BeautifulSoup(await res.text(), "html.parser")
+
+        riddle_panel = riddle_page.find("div", class_="panel-body")
+        if riddle_panel is not None:
+            parts = [p.text for p in riddle_panel.find_all("p")]
+            if (
+                len(parts) == 2
+                and not parts[0].startswith("Riddle Status: User Rejected")
+                and not parts[0].startswith("Riddle Status: User Moderated")
+            ):
+                riddle = parts[0]
+                answer = parts[1]
+                break
+        logger.info(f"Failed to parse riddle #{rnum}, attempt #{n}")
+
+    else:
+        RollbotFailure.SERVICE_DOWN.raise_exc(detail="Failed to find a riddle fast enough")
+
+    yield "\n\n".join(
+        (
+            f"Riddle #{rnum}",
+            riddle,
+            f"I'll post the response in about {sleep} seconds!",
+        )
+    )
+
+    # TODO need to confirm this works without blocking in a proper task deploying system
+    await asyncio.sleep(sleep)
+
+    yield "\n\n".join(("Here's the riddle answer from before!", riddle, answer))