diff --git a/keipack/stars/api_kei.py b/keipack/stars/api_kei.py index 3c4aaa4f..42809ec4 100644 --- a/keipack/stars/api_kei.py +++ b/keipack/stars/api_kei.py @@ -30,7 +30,7 @@ class ApiKei(PageStar): kpid = form["kpid"] convid = form["convid"] - message = form.get("message") + msg = form.get("message") previous = form.get("previous") first = form.get("first", False) @@ -38,7 +38,7 @@ class ApiKei(PageStar): if person is None: person = self.alchemy.get(KeiPerson)(kpid=kpid) session.add(person) - message = self.alchemy.get(KeiMessage)(kei_person=person, message=message, previous=previous) + message = self.alchemy.get(KeiMessage)(kei_person=person, message=msg, previous=previous) session.add(message) await asyncify(session.commit) # Find conversation diff --git a/keipack/tables/keimessages.py b/keipack/tables/keimessages.py index 577907ed..587f5581 100644 --- a/keipack/tables/keimessages.py +++ b/keipack/tables/keimessages.py @@ -1,29 +1,34 @@ +from typing import * from sqlalchemy import * from sqlalchemy.orm import relationship from sqlalchemy.ext.declarative import declared_attr +if TYPE_CHECKING: + from .keipeople import KeiPerson + + class KeiMessage: __tablename__ = "keimessages" @declared_attr - def kmid(self): + def kmid(self) -> int: return Column(Integer, primary_key=True) @declared_attr - def kei_person_id(self): + def kei_person_id(self) -> str: return Column(String, ForeignKey("keipeople.kpid"), nullable=False) @declared_attr - def kei_person(self): + def kei_person(self) -> "KeiPerson": return relationship("KeiPerson", foreign_keys=self.kei_person_id, backref="kei_messages") @declared_attr - def previous(self): + def previous(self) -> Optional[str]: return Column(String) @declared_attr - def message(self): + def message(self) -> str: return Column(String, nullable=False) def __repr__(self): diff --git a/keipack/tables/keipeople.py b/keipack/tables/keipeople.py index ad089853..a4f8965f 100644 --- a/keipack/tables/keipeople.py +++ b/keipack/tables/keipeople.py @@ -1,23 +1,31 @@ +from typing import * from sqlalchemy import * from sqlalchemy.orm import relationship from sqlalchemy.ext.declarative import declared_attr +if TYPE_CHECKING: + from royalnet.backpack.tables import User + class KeiPerson: __tablename__ = "keipeople" @declared_attr - def kpid(self): + def kpid(self) -> str: return Column(String, primary_key=True) @declared_attr - def user_id(self): + def user_id(self) -> Optional[int]: return Column(Integer, ForeignKey("users.uid")) @declared_attr - def user(self): + def user(self) -> Optional[User]: return relationship("User", foreign_keys=self.user_id, backref="kei_people") + @declared_attr + def name(self) -> Optional[str]: + return Column(String) + def __repr__(self): return f"<{self.__class__.__qualname__} {self.kpid}{' ' + self.user.username if self.user is not None else ''}>" diff --git a/keipack/utils/__init__.py b/keipack/utils/__init__.py index 55ee2886..ec6aa1ce 100644 --- a/keipack/utils/__init__.py +++ b/keipack/utils/__init__.py @@ -1,8 +1,10 @@ from .emotion import Emotion from .conversation import Conversation, ExampleConversation +from .anyinstring import any_in_string __all__ = [ "Emotion", "Conversation", "ExampleConversation", + "any_in_string", ] diff --git a/keipack/utils/anyinstring.py b/keipack/utils/anyinstring.py new file mode 100644 index 00000000..51c2400c --- /dev/null +++ b/keipack/utils/anyinstring.py @@ -0,0 +1,9 @@ +from typing import * +import re + + +def any_in_string(patterns: List[str], string: str) -> bool: + for pattern in patterns: + if re.search(pattern, string): + return True + return False diff --git a/keipack/utils/conversation.py b/keipack/utils/conversation.py index 3e06f574..deb9ad58 100644 --- a/keipack/utils/conversation.py +++ b/keipack/utils/conversation.py @@ -1,5 +1,10 @@ +import re +from typing import * from royalnet.commands import CommandInterface +from royalnet.utils import * from .emotion import Emotion +from ..tables import KeiPerson, KeiMessage +from ..utils import any_in_string class Conversation: @@ -7,10 +12,10 @@ class Conversation: self.generator = self._generator() self.interface: CommandInterface = interface - self._person = None + self._person: Optional[KeiPerson] = None + self._message: Optional[KeiMessage] = None + self._previous: Optional[str] = None self._session = None - self._message = None - self._previous = None async def _generator(self): yield @@ -35,7 +40,6 @@ class Conversation: class ExampleConversation(Conversation): async def _generator(self): yield - yield Emotion.HAPPY, "Ciao!" response = await self.interface.call_herald_event("discord", "discord_cv") yield Emotion.SURPRISED, f"Ci sono {len(response['guild']['members'])} persone in RYG." @@ -43,3 +47,65 @@ class ExampleConversation(Conversation): yield Emotion.NEUTRAL, "Questa è una conversazione di prova." yield await ExampleConversation.create(self.interface) yield Emotion.WORRIED, "Questo non dovrebbe mai venire fuori." + + +# noinspection PyTupleAssignmentBalance +class FirstConversation(Conversation): + async def _generator(self): + yield + yield Emotion.NEUTRAL, "Ciao!" + yield Emotion.QUESTION, "Come sei arrivato qui...?" + yield Emotion.HAPPY, "Capisco... Ad ogni modo, sono Kei! Tu come ti chiami?" + yield NameConversation.create(self.interface) + + +class NameConversation(Conversation): + async def _generator(self): + yield + + while True: + name = self._message.message.strip().strip(".,;:!?").lower() + name = re.sub(r"\s*mi\s*chiamo\s*", "", name) + name = re.sub(r"\s*il\s*mio\s*nome\s*[eèé]\s*", "", name) + name = re.sub(r"\s*sono\s*", "", name) + name = re.sub(r"\W", "", name) + + if name == "kei": + yield Emotion.SURPRISED, "Davvero ti chiami come me?\n" \ + "Perche' non mi dici un nome diverso?\n" \ + "Altrimenti rischiamo di confonderci..." + continue + + self._person.name = name + await asyncify(self._session.commit()) + break + + yield Emotion.GRIN, f"O-kei! {self._person.name}!" + yield Emotion.HAPPY, "Saro' sempre a tua disposizione quando mi vorrai dire qualcosa!" + yield Emotion.QUESTION, "Pero' prima ti vorrei chiedere un favore..." + yield Emotion.NEUTRAL, "Qualcuno ha criptato con delle password tutti i miei file...\n" \ + "Se ne trovi qualcuna in giro, potresti dirmela?\n" + + while True: + if self._message.message == "no": + yield Emotion.CRY, "Non farmi questo... Per piacere, accetta!" + else: + break + + yield Emotion.HAPPY, "Grazie! Prometto che quando riavro' tutto ti ricompensero' adeguatamente!" + + +class MainConversation(Conversation): + async def _generator(self): + yield + + yield Emotion.HAPPY, "Di cosa vuoi parlare?" + + while True: + msg = self._message.message + + if any_in_string([r"gatt[oiae]", "ny[ae]+", "mi+a+o+", "me+o+w+", "felin[oi]", "mici[ao]"], msg): + yield Emotion.CAT, "Nyan!" + + else: + yield Emotion.QUESTION, "...?" diff --git a/requests/kei.http b/requests/kei.http index 1aaa7880..e238e9c2 100644 --- a/requests/kei.http +++ b/requests/kei.http @@ -16,7 +16,7 @@ POST http://localhost:44445/api/kei Accept: application/json Content-Type: application/x-www-form-urlencoded -kpid=test&convid=1&first=true&message=lul +kpid=TEST&convid=TEST&message=Hi!&previous=Hoy! ###