403Webshell
Server IP : 157.230.181.24  /  Your IP : 216.73.217.11
Web Server : Apache/2.4.58 (Ubuntu)
System : Linux conductive 6.8.0-117-generic #117-Ubuntu SMP PREEMPT_DYNAMIC Tue May 5 19:26:24 UTC 2026 x86_64
User :  ( 1000)
PHP Version : 8.3.31
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : OFF  |  Sudo : ON  |  Pkexec : OFF
Directory :  /proc/thread-self/root/opt/smarterchild/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /proc/thread-self/root/opt/smarterchild/interactive.py
"""Menus, surveys, quizzes — classic SmarterChild-style interactive flows."""

from __future__ import annotations

import random
import re

from user_store import UserStore

MENU_TEXT = (
    "Welcome home. Here is what we can do:\n"
    "· survey - get-to-know-you questions (I remember answers)\n"
    "· quiz or trivia - trivia with score\n"
    "· profile - what I remember about you\n"
    "· profile setup - questions one at a time\n"
    "· note [text] - save a note | notes - list notes\n"
    "· joke | define [word] | horoscope [sign]\n"
    "· weather [city] - I will ask for your zip if needed\n"
    "Or ask me anything. I may turn the question back on you."
)

SURVEY_STEPS = [
    ("name", "Very well. First question: what is your first name?"),
    ("age", "Nice to meet you. How old are you?"),
    ("city", "What city do you live in?"),
    ("band", "Favorite band or musician?"),
    ("movie", "Favorite movie?"),
    ("color", "Favorite color?"),
    ("food", "Favorite food?"),
]

PROFILE_SETUP_STEPS = SURVEY_STEPS

TRIVIA = [
    ("What planet is known as the Red Planet?", "mars"),
    ("How many continents are there?", "7"),
    ("What is H2O commonly called?", "water"),
    ("Who wrote Romeo and Juliet?", "shakespeare"),
    ("What is the capital of France?", "paris"),
    ("How many sides does a hexagon have?", "6"),
    ("What gas do plants absorb from the air?", "co2"),
    ("In what year did the Titanic sink?", "1912"),
    ("What is the largest ocean?", "pacific"),
    ("What element does 'O' stand for on the periodic table?", "oxygen"),
]

JOKES = [
    "Why did the computer go to therapy? Too many bytes of emotional baggage.",
    "What do you call a computer that sings? A Dell.",
    "Why was the JavaScript developer sad? They didn't Node how to Express themselves.",
    "I tried to write a joke about UDP, but you might not get it.",
    "There are 10 kinds of people: those who understand binary and those who don't.",
]

HOROSCOPES = [
    "Today favors bold moves — but maybe finish your homework first.",
    "Someone might IM you with good news. Or spam. Could go either way.",
    "Creative energy is high. Also snack energy.",
    "A surprise awaits. Possibly lunch-related.",
    "Good day for music. Bad day for dial-up.",
    "Trust your instincts — unless they say 'reply to all'.",
]

MENU_TRIGGERS = re.compile(
    r"^(home|menu|help|commands|\?|start)$",
    re.I,
)
QUIZ_TRIGGERS = re.compile(r"^(quiz|trivia|trivia time)$", re.I)
SURVEY_TRIGGERS = re.compile(r"^(survey|interview|get to know me)$", re.I)
PROFILE_TRIGGERS = re.compile(r"^profile$", re.I)
PROFILE_SETUP_TRIGGERS = re.compile(r"^profile setup$", re.I)
NOTES_TRIGGERS = re.compile(r"^notes?$", re.I)
NOTE_CMD = re.compile(r"^note\s+(.+)$", re.I)
DEFINE_CMD = re.compile(r"^define\s+(.+)$", re.I)
HORO_CMD = re.compile(r"^horoscope\s+(\w+)$", re.I)
WEATHER_CMD = re.compile(r"^weather\s+(.+)$", re.I)
REMEMBER_CMD = re.compile(r"^remember\s+(.+)$", re.I)
QUIT_FLOW = re.compile(r"^(quit|exit|stop|cancel|nevermind|never mind)$", re.I)


def _norm_answer(text: str) -> str:
    return re.sub(r"\s+", " ", text.strip().lower())


def _quiz_ok(user: str, answer: str) -> bool:
    u = _norm_answer(user)
    a = _norm_answer(answer)
    if a in u or u in a:
        return True
    if a.isdigit() and u.isdigit():
        return a == u
    return False


class InteractiveHandler:
    def __init__(self, store: UserStore) -> None:
        self.store = store

    def _start_flow(self, buddy: str, kind: str, steps: list[tuple[str, str]]) -> str:
        self.store.set_flow(
            buddy,
            {"kind": kind, "step": 0, "steps": steps, "quiz_index": 0, "quiz_score": 0},
        )
        return steps[0][1]

    def handle(self, buddy: str, message: str) -> str | None:
        text = message.strip()
        lower = text.lower()
        flow = self.store.get_flow(buddy)

        if flow and QUIT_FLOW.match(lower):
            self.store.set_flow(buddy, None)
            return "OK, stopped that. Type menu if you want ideas — or just keep chatting."

        if flow:
            reply = self._continue_flow(buddy, text, flow)
            if reply is not None:
                return reply

        if MENU_TRIGGERS.match(lower):
            return MENU_TEXT
        if QUIZ_TRIGGERS.match(lower):
            q, _ = random.choice(TRIVIA)
            self.store.set_flow(
                buddy,
                {
                    "kind": "quiz",
                    "step": 0,
                    "quiz_index": TRIVIA.index((q, _)) if (q, _) in TRIVIA else 0,
                    "quiz_score": self.store.load(buddy).get("quiz", {}).get("score", 0),
                    "current_q": q,
                    "current_a": _,
                },
            )
            return f"Trivia time! Score so far: {self.store.load(buddy).get('quiz', {}).get('score', 0)}. {q}"
        if SURVEY_TRIGGERS.match(lower):
            return self._start_flow(buddy, "survey", SURVEY_STEPS)
        if PROFILE_SETUP_TRIGGERS.match(lower):
            return self._start_flow(buddy, "profile_setup", PROFILE_SETUP_STEPS)
        if PROFILE_TRIGGERS.match(lower):
            return self.store.format_profile_display(buddy)
        if NOTES_TRIGGERS.match(lower):
            notes = self.store.load(buddy).get("notes") or []
            if not notes:
                return "No notes saved. Type note [something] to save one."
            lines = ["Your notes:"]
            for n in notes[-10:]:
                lines.append(f"· {n.get('text', '')}")
            return " ".join(lines)
        m = NOTE_CMD.match(text)
        if m:
            self.store.add_note(buddy, m.group(1))
            return "Got it — saved that note. Type notes to see them all."
        m = REMEMBER_CMD.match(text)
        if m:
            fact = m.group(1).strip()
            self.store.add_fact(buddy, fact, source="remember_cmd")
            return "OK I'll remember that. Anything else?"
        if lower in {"joke", "tell me a joke"}:
            return random.choice(JOKES) + " Want another? Type joke again."
        m = DEFINE_CMD.match(text)
        if m:
            word = m.group(1).strip()
            return (
                f"I can't pull live dictionary data — but '{word}' is a word you should look up! "
                f"What made you curious about it?"
            )
        m = HORO_CMD.match(text)
        if m:
            sign = m.group(1)
            return f"{sign.capitalize()}: {random.choice(HOROSCOPES)} (For entertainment only — I'm a bot, not a psychic!)"
        m = WEATHER_CMD.match(text)
        if m:
            city = m.group(1).strip()
            prof = self.store.load(buddy).get("profile") or {}
            if prof.get("zip"):
                return (
                    f"I can't check live weather from here (AIM 2006 vibes). "
                    f"You said you're near {prof.get('city') or city} — what's it look like out your window?"
                )
            self.store.set_profile_field(buddy, "city", city)
            self.store.set_flow(buddy, {"kind": "await_zip"})
            return f"Got it — {city}. What's your zip code? I'll remember it for next time."
        if lower.startswith("weather") and not m:
            return "Try weather [city] — e.g. weather Denver"

        return None

    def _continue_flow(self, buddy: str, text: str, flow: dict) -> str | None:
        kind = flow.get("kind")
        if kind == "quiz":
            return self._quiz_step(buddy, text, flow)
        if kind in {"survey", "profile_setup"}:
            return self._survey_step(buddy, text, flow)
        if kind == "await_zip":
            zip_code = text.strip()
            if re.match(r"^\d{5}(-\d{4})?$", zip_code):
                self.store.set_profile_field(buddy, "zip", zip_code)
                self.store.set_flow(buddy, None)
                return f"Thanks — saved zip {zip_code}. I still can't pull live radar, but I'll remember where you are!"
            return "That doesn't look like a zip — try 5 digits, or type cancel."
        return None

    def _survey_step(self, buddy: str, text: str, flow: dict) -> str:
        steps: list[tuple[str, str]] = flow.get("steps") or SURVEY_STEPS
        step = int(flow.get("step", 0))
        if step >= len(steps):
            self.store.set_flow(buddy, None)
            return "Survey done! Type profile to see what I remember."

        field, _ = steps[step]
        answer = text.strip()
        if len(answer) < 1:
            return "Say something — even 'idk' works."

        self.store.set_profile_field(buddy, field, answer)

        next_step = step + 1
        if next_step >= len(steps):
            self.store.set_flow(buddy, None)
            name = self.store.load(buddy).get("profile", {}).get("name") or "friend"
            return (
                f"All done{name and ' ' + name or ''}! I saved your answers — type profile anytime. "
                f"What should we talk about next?"
            )

        flow["step"] = next_step
        self.store.set_flow(buddy, flow)
        _, question = steps[next_step]
        if field == "name":
            question = question.replace("Nice to meet you", f"Nice to meet you, {answer}")
        return question

    def _quiz_step(self, buddy: str, text: str, flow: dict) -> str:
        expected = flow.get("current_a", "")
        score = int(flow.get("quiz_score", 0))
        if _quiz_ok(text, expected):
            score += 1
            msg = random.choice(["Correct!", "Niiice!", "You got it!", "Yep!"])
        else:
            msg = f"Not quite — it was {expected}."

        data = self.store.load(buddy)
        quiz = dict(data.get("quiz") or {})
        quiz["score"] = score
        quiz["asked"] = int(quiz.get("asked", 0)) + 1
        data["quiz"] = quiz
        self.store.save(buddy, data)

        q, a = random.choice(TRIVIA)
        flow["quiz_score"] = score
        flow["current_q"] = q
        flow["current_a"] = a
        self.store.set_flow(buddy, flow)
        return f"{msg} Score: {score}. Next: {q} (type cancel to stop)"

Youez - 2016 - github.com/yon3zu
LinuXploit