1
Fork 0
mirror of https://github.com/RYGhub/royalnet.git synced 2024-11-23 19:44:20 +00:00

Add keyboard method!

This commit is contained in:
Steffo 2019-09-03 01:34:51 +02:00
parent 364ef8779e
commit 9b5e06a46c
8 changed files with 147 additions and 78 deletions

View file

@ -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

View file

@ -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

View file

@ -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()

View file

@ -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()

View file

@ -1,3 +1,4 @@
from .debug_error import DebugErrorCommand from .debug_error import DebugErrorCommand
from .debug_keyboard import DebugKeyboardCommand
__all__ = ["DebugErrorCommand"] __all__ = ["DebugErrorCommand", "DebugKeyboardCommand"]

View 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
})

View file

@ -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:

View file

@ -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