mirror of
https://github.com/RYGhub/royalnet.git
synced 2024-11-27 13:34:28 +00:00
Add keyboard method!
This commit is contained in:
parent
364ef8779e
commit
9b5e06a46c
8 changed files with 147 additions and 78 deletions
|
@ -132,10 +132,10 @@ class GenericBot:
|
||||||
else:
|
else:
|
||||||
self.loop = loop
|
self.loop = loop
|
||||||
if sentry_dsn:
|
if sentry_dsn:
|
||||||
log.debug("Sentry int")
|
log.debug("Sentry integration enabled")
|
||||||
self.sentry = sentry_sdk.init(sentry_dsn)
|
self.sentry = sentry_sdk.init(sentry_dsn)
|
||||||
else:
|
else:
|
||||||
log.debug("Sentry integration not enabled")
|
log.debug("Sentry integration disabled")
|
||||||
try:
|
try:
|
||||||
if database_config is None:
|
if database_config is None:
|
||||||
self.alchemy = None
|
self.alchemy = None
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import telegram
|
import telegram
|
||||||
import telegram.utils.request
|
import telegram.utils.request
|
||||||
import typing
|
import typing
|
||||||
|
import uuid
|
||||||
import asyncio
|
import asyncio
|
||||||
import sentry_sdk
|
import sentry_sdk
|
||||||
import logging as _logging
|
import logging as _logging
|
||||||
|
@ -41,13 +42,23 @@ class TelegramBot(GenericBot):
|
||||||
name = self.interface_name
|
name = self.interface_name
|
||||||
prefix = "/"
|
prefix = "/"
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
|
self.keys_callbacks: typing.Dict[typing.Tuple[int, str], typing.Callable] = {}
|
||||||
|
|
||||||
|
def register_keyboard_key(interface, key_name: str, callback: typing.Callable):
|
||||||
|
interface.keys_callbacks[key_name] = callback
|
||||||
|
|
||||||
|
def unregister_keyboard_key(interface, key_name: str):
|
||||||
|
del interface.keys_callbacks[key_name]
|
||||||
|
|
||||||
return TelegramInterface
|
return TelegramInterface
|
||||||
|
|
||||||
def _data_factory(self) -> typing.Type[CommandData]:
|
def _data_factory(self) -> typing.Type[CommandData]:
|
||||||
# noinspection PyMethodParameters,PyAbstractClass
|
# noinspection PyMethodParameters,PyAbstractClass
|
||||||
class TelegramData(CommandData):
|
class TelegramData(CommandData):
|
||||||
def __init__(data, interface: CommandInterface, update: telegram.Update):
|
def __init__(data, interface: CommandInterface, update: telegram.Update):
|
||||||
data._interface = interface
|
data.interface = interface
|
||||||
data.update = update
|
data.update = update
|
||||||
|
|
||||||
async def reply(data, text: str):
|
async def reply(data, text: str):
|
||||||
|
@ -61,7 +72,7 @@ class TelegramBot(GenericBot):
|
||||||
if error_if_none:
|
if error_if_none:
|
||||||
raise UnregisteredError("No author for this message")
|
raise UnregisteredError("No author for this message")
|
||||||
return None
|
return None
|
||||||
query = data._interface.session.query(self.master_table)
|
query = data.interface.session.query(self.master_table)
|
||||||
for link in self.identity_chain:
|
for link in self.identity_chain:
|
||||||
query = query.join(link.mapper.class_)
|
query = query.join(link.mapper.class_)
|
||||||
query = query.filter(self.identity_column == user.id)
|
query = query.filter(self.identity_column == user.id)
|
||||||
|
@ -70,6 +81,18 @@ class TelegramBot(GenericBot):
|
||||||
raise UnregisteredError("Author is not registered")
|
raise UnregisteredError("Author is not registered")
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
async def keyboard(data, text: str, keyboard: typing.Dict[str, typing.Callable]) -> None:
|
||||||
|
tg_keyboard = []
|
||||||
|
for key in keyboard:
|
||||||
|
press_id = uuid.uuid4()
|
||||||
|
tg_keyboard.append([telegram.InlineKeyboardButton(key, callback_data=str(press_id))])
|
||||||
|
data.interface.register_keyboard_key(key_name=str(press_id), callback=keyboard[key])
|
||||||
|
await asyncify(data.update.effective_chat.send_message,
|
||||||
|
telegram_escape(text),
|
||||||
|
reply_markup=telegram.InlineKeyboardMarkup(tg_keyboard),
|
||||||
|
parse_mode="HTML",
|
||||||
|
disable_web_page_preview=True)
|
||||||
|
|
||||||
return TelegramData
|
return TelegramData
|
||||||
|
|
||||||
def __init__(self, *,
|
def __init__(self, *,
|
||||||
|
@ -87,8 +110,12 @@ class TelegramBot(GenericBot):
|
||||||
|
|
||||||
async def _handle_update(self, update: telegram.Update):
|
async def _handle_update(self, update: telegram.Update):
|
||||||
# Skip non-message updates
|
# Skip non-message updates
|
||||||
if update.message is None:
|
if update.message is not None:
|
||||||
return
|
await self._handle_message(update)
|
||||||
|
elif update.callback_query is not None:
|
||||||
|
await self._handle_callback_query(update)
|
||||||
|
|
||||||
|
async def _handle_message(self, update: telegram.Update):
|
||||||
message: telegram.Message = update.message
|
message: telegram.Message = update.message
|
||||||
text: str = message.text
|
text: str = message.text
|
||||||
# Try getting the caption instead
|
# Try getting the caption instead
|
||||||
|
@ -122,6 +149,21 @@ class TelegramBot(GenericBot):
|
||||||
error_message += '\n'.join(e.args)
|
error_message += '\n'.join(e.args)
|
||||||
await data.reply(error_message)
|
await data.reply(error_message)
|
||||||
|
|
||||||
|
async def _handle_callback_query(self, update: telegram.Update):
|
||||||
|
query: telegram.CallbackQuery = update.callback_query
|
||||||
|
source: telegram.Message = query.message
|
||||||
|
for command in self.commands.values():
|
||||||
|
try:
|
||||||
|
callback = command.interface.keys_callbacks[query.data]
|
||||||
|
except KeyError:
|
||||||
|
continue
|
||||||
|
await callback(data=self._Data(interface=command.interface, update=update))
|
||||||
|
await asyncify(query.answer)
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
await asyncify(source.edit_reply_markup, reply_markup=None)
|
||||||
|
await asyncify(query.answer, text="⛔️ This keyboard has expired.")
|
||||||
|
|
||||||
async def run(self):
|
async def run(self):
|
||||||
while True:
|
while True:
|
||||||
# Get the latest 100 updates
|
# Get the latest 100 updates
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
import typing
|
||||||
|
|
||||||
|
|
||||||
class CommandData:
|
class CommandData:
|
||||||
async def reply(self, text: str) -> None:
|
async def reply(self, text: str) -> None:
|
||||||
"""Send a text message to the channel where the call was made.
|
"""Send a text message to the channel where the call was made.
|
||||||
|
@ -16,3 +19,9 @@ class CommandData:
|
||||||
Raises:
|
Raises:
|
||||||
:py:exc:`royalnet.error.UnregisteredError` if ``error_if_none`` is set to True and no author is found."""
|
:py:exc:`royalnet.error.UnregisteredError` if ``error_if_none`` is set to True and no author is found."""
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
async def keyboard(self, text: str, keyboard: typing.Dict[str, typing.Callable]) -> None:
|
||||||
|
"""Send a keyboard having the keys of the dict as keys and calling the correspondent values on a press.
|
||||||
|
|
||||||
|
The function should be passed the :py:class:`CommandData` instance as a argument."""
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
|
@ -31,3 +31,9 @@ class CommandInterface:
|
||||||
message: The data to be sent. Must be :py:mod:`pickle`-able.
|
message: The data to be sent. Must be :py:mod:`pickle`-able.
|
||||||
destination: The destination of the request, either in UUID format or node name."""
|
destination: The destination of the request, either in UUID format or node name."""
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
def register_keyboard_key(self, key_name: str, callback: typing.Callable):
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
def unregister_keyboard_key(self, key_name: str):
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
from .debug_error import DebugErrorCommand
|
from .debug_error import DebugErrorCommand
|
||||||
|
from .debug_keyboard import DebugKeyboardCommand
|
||||||
|
|
||||||
__all__ = ["DebugErrorCommand"]
|
__all__ = ["DebugErrorCommand", "DebugKeyboardCommand"]
|
||||||
|
|
18
royalnet/commands/debug/debug_keyboard.py
Normal file
18
royalnet/commands/debug/debug_keyboard.py
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
import typing
|
||||||
|
from ..command import Command
|
||||||
|
from ..commandargs import CommandArgs
|
||||||
|
from ..commanddata import CommandData
|
||||||
|
|
||||||
|
|
||||||
|
class DebugKeyboardCommand(Command):
|
||||||
|
name: str = "debug_keyboard"
|
||||||
|
|
||||||
|
description: str = "Invia una tastiera di prova."
|
||||||
|
|
||||||
|
async def _callback(self, data: CommandData):
|
||||||
|
await data.reply("OK.")
|
||||||
|
|
||||||
|
async def run(self, args: CommandArgs, data: CommandData) -> None:
|
||||||
|
await data.keyboard("This is a keyboard.", {
|
||||||
|
"✅ OK": self._callback
|
||||||
|
})
|
|
@ -16,39 +16,32 @@ class SmecdsCommand(Command):
|
||||||
DS_LIST = ["della secca", "del seccatore", "del secchiello", "del secchio", "del secchione", "del secondino",
|
DS_LIST = ["della secca", "del seccatore", "del secchiello", "del secchio", "del secchione", "del secondino",
|
||||||
"del sedano", "del sedativo", "della sedia", "del sedicente", "del sedile", "della sega", "del segale",
|
"del sedano", "del sedativo", "della sedia", "del sedicente", "del sedile", "della sega", "del segale",
|
||||||
"della segatura", "della seggiola", "del seggiolino", "della seggiovia", "della segheria",
|
"della segatura", "della seggiola", "del seggiolino", "della seggiovia", "della segheria",
|
||||||
"del seghetto",
|
"del seghetto", "del segnalibro", "del segnaposto", "del segno", "del segretario", "della segreteria",
|
||||||
"del segnalibro", "del segnaposto", "del segno", "del segretario", "della segreteria", "del seguace",
|
"del seguace", "del segugio", "della selce", "della sella", "della selz", "della selva",
|
||||||
"del segugio", "della selce", "della sella", "della selz", "della selva", "della selvaggina",
|
"della selvaggina", "del semaforo", "del seme", "del semifreddo", "del seminario", "della seminarista",
|
||||||
"del semaforo",
|
"della semola", "del semolino", "del semplicione", "della senape", "del senatore", "del seno",
|
||||||
"del seme", "del semifreddo", "del seminario", "della seminarista", "della semola", "del semolino",
|
"del sensore", "della sentenza", "della sentinella", "del sentore", "della seppia", "del sequestratore",
|
||||||
"del semplicione", "della senape", "del senatore", "del seno", "del sensore", "della sentenza",
|
"della serenata", "del sergente", "del sermone", "della serpe", "del serpente", "della serpentina",
|
||||||
"della sentinella", "del sentore", "della seppia", "del sequestratore", "della serenata", "del sergente",
|
"della serra", "del serraglio", "del serramanico", "della serranda", "della serratura", "del servitore",
|
||||||
"del sermone", "della serpe", "del serpente", "della serpentina", "della serra", "del serraglio",
|
"della servitù", "del servizievole", "del servo", "del set", "della seta", "della setola", "del sigaro",
|
||||||
"del serramanico", "della serranda", "della serratura", "del servitore", "della servitù",
|
"del sidecar", "del siderurgico", "del sidro", "della siepe", "del sifone", "della sigaretta",
|
||||||
"del servizievole",
|
"del sigillo", "della signora", "della signorina", "del silenziatore", "della silhouette", "del silicio",
|
||||||
"del servo", "del set", "della seta", "della setola", "del sidecar", "del siderurgico", "del sidro",
|
"del silicone", "del siluro", "della sinagoga", "della sindacalista", "del sindacato", "del sindaco",
|
||||||
"della siepe", "del sifone", "della sigaretta", "del sigaro", "del sigillo", "della signora",
|
"della sindrome", "della sinfonia", "del sipario", "del sire", "della sirena", "della siringa",
|
||||||
"della signorina", "del silenziatore", "della silhouette", "del silicio", "del silicone", "del siluro",
|
"del sismografo", "del sobborgo", "del sobillatore", "del sobrio", "del soccorritore", "del socio",
|
||||||
"della sinagoga", "della sindacalista", "del sindacato", "del sindaco", "della sindrome",
|
"del sociologo", "della soda", "del sofà", "della soffitta", "del software", "dello sogghignare",
|
||||||
"della sinfonia",
|
"del soggiorno", "della sogliola", "del sognatore", "della soia", "del solaio", "del solco",
|
||||||
"del sipario", "del sire", "della sirena", "della siringa", "del sismografo", "del sobborgo",
|
"del soldato", "del soldo", "del sole", "della soletta", "della solista", "del solitario",
|
||||||
"del sobillatore", "del sobrio", "del soccorritore", "del socio", "del sociologo", "della soda",
|
"del sollazzare", "del sollazzo", "del sollecito", "del solleone", "del solletico", "del sollevare",
|
||||||
"del sofà",
|
"del sollievo", "del solstizio", "del solubile", "del solvente", "della soluzione", "del somaro",
|
||||||
"della soffitta", "del software", "dello sogghignare", "del soggiorno", "della sogliola",
|
"del sombrero", "del sommergibile", "del sommo", "della sommossa", "del sommozzatore", "del sonar",
|
||||||
"del sognatore",
|
"della sonda", "del sondaggio", "del sondare", "del sonnacchioso", "del sonnambulo", "del sonnellino",
|
||||||
"della soia", "del solaio", "del solco", "del soldato", "del soldo", "del sole", "della soletta",
|
"del sonnifero", "del sonno", "della sonnolenza", "del sontuoso", "del soppalco", "del soprabito",
|
||||||
"della solista", "del solitario", "del sollazzare", "del sollazzo", "del sollecito", "del solleone",
|
"del sopracciglio", "del sopraffare", "del sopraffino", "del sopraluogo", "del sopramobile",
|
||||||
"del solletico", "del sollevare", "del sollievo", "del solstizio", "del solubile", "del solvente",
|
"del soprannome", "del soprano", "del soprappensiero", "del soprassalto", "del soprassedere",
|
||||||
"della soluzione", "del somaro", "del sombrero", "del sommergibile", "del sommo", "della sommossa",
|
"del sopravvento", "del sopravvivere", "del soqquadro", "del sorbetto", "del sordido", "della sordina",
|
||||||
"del sommozzatore", "del sonar", "della sonda", "del sondaggio", "del sondare", "del sonnacchioso",
|
"del sordo", "della sorella", "della sorgente", "del sornione", "del sorpasso", "della sorpresa",
|
||||||
"del sonnambulo", "del sonnellino", "del sonnifero", "del sonno", "della sonnolenza", "del sontuoso",
|
"del sorreggere", "del sorridere", "della sorsata", "del sorteggio", "del sortilegio",
|
||||||
"del soppalco", "del soprabito", "del sopracciglio", "del sopraffare", "del sopraffino",
|
|
||||||
"del sopraluogo",
|
|
||||||
"del sopramobile", "del soprannome", "del soprano", "del soprappensiero", "del soprassalto",
|
|
||||||
"del soprassedere", "del sopravvento", "del sopravvivere", "del soqquadro", "del sorbetto",
|
|
||||||
"del sordido",
|
|
||||||
"della sordina", "del sordo", "della sorella", "della sorgente", "del sornione", "del sorpasso",
|
|
||||||
"della sorpresa", "del sorreggere", "del sorridere", "della sorsata", "del sorteggio", "del sortilegio",
|
|
||||||
"del sorvegliante", "del sorvolare", "del sosia", "del sospettoso", "del sospirare", "della sosta",
|
"del sorvegliante", "del sorvolare", "del sosia", "del sospettoso", "del sospirare", "della sosta",
|
||||||
"della sostanza", "del sostegno", "del sostenitore", "del sostituto", "del sottaceto", "della sottana",
|
"della sostanza", "del sostegno", "del sostenitore", "del sostituto", "del sottaceto", "della sottana",
|
||||||
"del sotterfugio", "del sotterraneo", "del sottile", "del sottilizzare", "del sottintendere",
|
"del sotterfugio", "del sotterraneo", "del sottile", "del sottilizzare", "del sottintendere",
|
||||||
|
@ -56,22 +49,18 @@ class SmecdsCommand(Command):
|
||||||
"del sottoscala", "della sottoscrizione", "del sottostare", "del sottosuolo", "del sottotetto",
|
"del sottoscala", "della sottoscrizione", "del sottostare", "del sottosuolo", "del sottotetto",
|
||||||
"del sottotitolo", "del sottovalutare", "del sottovaso", "della sottoveste", "del sottovuoto",
|
"del sottotitolo", "del sottovalutare", "del sottovaso", "della sottoveste", "del sottovuoto",
|
||||||
"del sottufficiale", "della soubrette", "del souvenir", "del soverchiare", "del sovrano",
|
"del sottufficiale", "della soubrette", "del souvenir", "del soverchiare", "del sovrano",
|
||||||
"del sovrapprezzo",
|
"del sovrapprezzo", "della sovvenzione", "del sovversivo", "del sozzo", "dello suadente", "del sub",
|
||||||
"della sovvenzione", "del sovversivo", "del sozzo", "dello suadente", "del sub", "del subalterno",
|
"del subalterno", "del subbuglio", "del subdolo", "del sublime", "del suburbano", "del successore",
|
||||||
"del subbuglio", "del subdolo", "del sublime", "del suburbano", "del successore", "del succo",
|
"del succo", "della succube", "del succulento", "della succursale", "del sudario", "della sudditanza",
|
||||||
"della succube", "del succulento", "della succursale", "del sudario", "della sudditanza", "del suddito",
|
"del suddito", "del sudicio", "del suffisso", "del suffragio", "del suffumigio", "del suggeritore",
|
||||||
"del sudicio", "del suffisso", "del suffragio", "del suffumigio", "del suggeritore", "del sughero",
|
"del sughero", "del sugo", "del suino", "della suite", "del sulfureo", "del sultano", "di Steffo",
|
||||||
"del sugo", "del suino", "della suite", "del sulfureo", "del sultano", "di Steffo", "di Spaggia",
|
"di Spaggia", "di Sabrina", "del sas", "del ses", "del sis", "del sos", "del sus", "della supremazia",
|
||||||
"di Sabrina", "del sas", "del ses", "del sis", "del sos", "del sus", "della supremazia",
|
"del Santissimo", "della scatola", "del supercalifragilistichespiralidoso", "del sale", "del salame",
|
||||||
"del Santissimo",
|
"di (Town of) Salem", "di Stronghold", "di SOMA", "dei Saints", "di S.T.A.L.K.E.R.", "di Sanctum",
|
||||||
"della scatola", "del supercalifragilistichespiralidoso", "del sale", "del salame", "di (Town of) Salem",
|
"dei Sims", "di Sid", "delle Skullgirls", "di Sonic", "di Spiral (Knights)", "di Spore", "di Starbound",
|
||||||
"di Stronghold", "di SOMA", "dei Saints", "di S.T.A.L.K.E.R.", "di Sanctum", "dei Sims", "di Sid",
|
"di SimCity", "di Sensei", "di Ssssssssssssss... Boom! E' esploso il dizionario", "della scala",
|
||||||
"delle Skullgirls", "di Sonic", "di Spiral (Knights)", "di Spore", "di Starbound", "di SimCity",
|
"di Sakura", "di Suzie", "di Shinji", "del senpai", "del support", "di Superman", "di Sekiro",
|
||||||
"di Sensei",
|
"dello Slime God", "del salassato", "della salsa"]
|
||||||
"di Ssssssssssssss... Boom! E' esploso il dizionario", "della scala", "di Sakura", "di Suzie",
|
|
||||||
"di Shinji",
|
|
||||||
"del senpai", "del support", "di Superman", "di Sekiro", "dello Slime God", "del salassato",
|
|
||||||
"della salsa"]
|
|
||||||
SMECDS = "🤔 Secondo me, è colpa {ds}."
|
SMECDS = "🤔 Secondo me, è colpa {ds}."
|
||||||
|
|
||||||
async def run(self, args: CommandArgs, data: CommandData) -> None:
|
async def run(self, args: CommandArgs, data: CommandData) -> None:
|
||||||
|
|
|
@ -18,35 +18,39 @@ stream_handler = logging.StreamHandler()
|
||||||
stream_handler.formatter = logging.Formatter("{asctime}\t{name}\t{levelname}\t{message}", style="{")
|
stream_handler.formatter = logging.Formatter("{asctime}\t{name}\t{levelname}\t{message}", style="{")
|
||||||
log.addHandler(stream_handler)
|
log.addHandler(stream_handler)
|
||||||
|
|
||||||
commands = [
|
|
||||||
CiaoruoziCommand,
|
|
||||||
ColorCommand,
|
|
||||||
CvCommand,
|
|
||||||
DiarioCommand,
|
|
||||||
Mp3Command,
|
|
||||||
PauseCommand,
|
|
||||||
PingCommand,
|
|
||||||
PlayCommand,
|
|
||||||
PlaymodeCommand,
|
|
||||||
QueueCommand,
|
|
||||||
RageCommand,
|
|
||||||
ReminderCommand,
|
|
||||||
ShipCommand,
|
|
||||||
SkipCommand,
|
|
||||||
SmecdsCommand,
|
|
||||||
SummonCommand,
|
|
||||||
VideochannelCommand,
|
|
||||||
DnditemCommand,
|
|
||||||
DndspellCommand
|
|
||||||
]
|
|
||||||
|
|
||||||
sentry_dsn = os.environ.get("SENTRY_DSN")
|
sentry_dsn = os.environ.get("SENTRY_DSN")
|
||||||
|
|
||||||
# noinspection PyUnreachableCode
|
# noinspection PyUnreachableCode
|
||||||
if __debug__:
|
if __debug__:
|
||||||
|
commands = [
|
||||||
|
DebugErrorCommand,
|
||||||
|
DebugKeyboardCommand
|
||||||
|
]
|
||||||
log.setLevel(logging.DEBUG)
|
log.setLevel(logging.DEBUG)
|
||||||
commands = [*commands, DebugErrorCommand]
|
|
||||||
else:
|
else:
|
||||||
|
commands = [
|
||||||
|
CiaoruoziCommand,
|
||||||
|
ColorCommand,
|
||||||
|
CvCommand,
|
||||||
|
DiarioCommand,
|
||||||
|
Mp3Command,
|
||||||
|
PauseCommand,
|
||||||
|
PingCommand,
|
||||||
|
PlayCommand,
|
||||||
|
PlaymodeCommand,
|
||||||
|
QueueCommand,
|
||||||
|
RageCommand,
|
||||||
|
ReminderCommand,
|
||||||
|
ShipCommand,
|
||||||
|
SkipCommand,
|
||||||
|
SmecdsCommand,
|
||||||
|
SummonCommand,
|
||||||
|
VideochannelCommand,
|
||||||
|
DnditemCommand,
|
||||||
|
DndspellCommand
|
||||||
|
]
|
||||||
log.setLevel(logging.INFO)
|
log.setLevel(logging.INFO)
|
||||||
|
|
||||||
address, port = "127.0.0.1", 1234
|
address, port = "127.0.0.1", 1234
|
||||||
|
|
Loading…
Reference in a new issue