mirror of
https://gitlab.com/octospacc/WinDog.git
synced 2025-06-05 22:09:20 +02:00
Cleanup Locale system, remove legacy Locale API, add command help handling, misc
This commit is contained in:
@ -36,7 +36,7 @@ def MastodonMakeInputMessageData(status:dict) -> InputMessageData:
|
|||||||
while command_tokens[0].strip().startswith('@') or not command_tokens[0]:
|
while command_tokens[0].strip().startswith('@') or not command_tokens[0]:
|
||||||
command_tokens.pop(0)
|
command_tokens.pop(0)
|
||||||
data.command = ParseCommand(" ".join(command_tokens))
|
data.command = ParseCommand(" ".join(command_tokens))
|
||||||
data.user = SafeNamespace(
|
data.user = UserData(
|
||||||
id = ("mastodon:" + strip_url_scheme(status["account"]["uri"])),
|
id = ("mastodon:" + strip_url_scheme(status["account"]["uri"])),
|
||||||
name = status["account"]["display_name"],
|
name = status["account"]["display_name"],
|
||||||
)
|
)
|
||||||
|
@ -48,6 +48,7 @@ def MatrixMain() -> bool:
|
|||||||
await MatrixClient.sync(30000) # resync old messages first to "skip read ones"
|
await MatrixClient.sync(30000) # resync old messages first to "skip read ones"
|
||||||
asyncio.ensure_future(queue_handler())
|
asyncio.ensure_future(queue_handler())
|
||||||
MatrixClient.add_event_callback(MatrixMessageHandler, nio.RoomMessage)
|
MatrixClient.add_event_callback(MatrixMessageHandler, nio.RoomMessage)
|
||||||
|
MatrixClient.add_event_callback(MatrixInviteHandler, nio.InviteEvent)
|
||||||
await MatrixClient.sync_forever(timeout=30000)
|
await MatrixClient.sync_forever(timeout=30000)
|
||||||
Thread(target=lambda:asyncio.run(client_main())).start()
|
Thread(target=lambda:asyncio.run(client_main())).start()
|
||||||
return True
|
return True
|
||||||
@ -63,7 +64,7 @@ def MatrixMakeInputMessageData(room:nio.MatrixRoom, event:nio.RoomMessage) -> In
|
|||||||
id = f"matrix:{room.room_id}",
|
id = f"matrix:{room.room_id}",
|
||||||
name = room.display_name,
|
name = room.display_name,
|
||||||
),
|
),
|
||||||
user = SafeNamespace(
|
user = UserData(
|
||||||
id = f"matrix:{event.sender}",
|
id = f"matrix:{event.sender}",
|
||||||
#name = , # TODO name must be get via a separate API request (and so maybe we should cache it)
|
#name = , # TODO name must be get via a separate API request (and so maybe we should cache it)
|
||||||
),
|
),
|
||||||
@ -75,6 +76,9 @@ def MatrixMakeInputMessageData(room:nio.MatrixRoom, event:nio.RoomMessage) -> In
|
|||||||
data.user.settings = (GetUserSettings(data.user.id) or SafeNamespace())
|
data.user.settings = (GetUserSettings(data.user.id) or SafeNamespace())
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
async def MatrixInviteHandler(room:nio.MatrixRoom, event:nio.InviteEvent) -> None:
|
||||||
|
await MatrixClient.join(room.room_id)
|
||||||
|
|
||||||
async def MatrixMessageHandler(room:nio.MatrixRoom, event:nio.RoomMessage) -> None:
|
async def MatrixMessageHandler(room:nio.MatrixRoom, event:nio.RoomMessage) -> None:
|
||||||
if MatrixUsername == event.sender:
|
if MatrixUsername == event.sender:
|
||||||
return # ignore messages that come from the bot itself
|
return # ignore messages that come from the bot itself
|
||||||
|
@ -32,6 +32,13 @@ def TelegramMain() -> bool:
|
|||||||
#app.run_polling(allowed_updates=Update.ALL_TYPES)
|
#app.run_polling(allowed_updates=Update.ALL_TYPES)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def TelegramMakeUserData(user:telegram.User) -> UserData:
|
||||||
|
return UserData(
|
||||||
|
id = f"telegram:{user.id}",
|
||||||
|
tag = user.username,
|
||||||
|
name = user.first_name,
|
||||||
|
)
|
||||||
|
|
||||||
def TelegramMakeInputMessageData(message:telegram.Message) -> InputMessageData:
|
def TelegramMakeInputMessageData(message:telegram.Message) -> InputMessageData:
|
||||||
#if not message:
|
#if not message:
|
||||||
# return None
|
# return None
|
||||||
@ -40,11 +47,7 @@ def TelegramMakeInputMessageData(message:telegram.Message) -> InputMessageData:
|
|||||||
datetime = int(time.mktime(message.date.timetuple())),
|
datetime = int(time.mktime(message.date.timetuple())),
|
||||||
text_plain = message.text,
|
text_plain = message.text,
|
||||||
text_markdown = message.text_markdown_v2,
|
text_markdown = message.text_markdown_v2,
|
||||||
user = SafeNamespace(
|
user = TelegramMakeUserData(message.from_user),
|
||||||
id = f"telegram:{message.from_user.id}",
|
|
||||||
tag = message.from_user.username,
|
|
||||||
name = message.from_user.first_name,
|
|
||||||
),
|
|
||||||
room = SafeNamespace(
|
room = SafeNamespace(
|
||||||
id = f"telegram:{message.chat.id}",
|
id = f"telegram:{message.chat.id}",
|
||||||
tag = message.chat.username,
|
tag = message.chat.username,
|
||||||
@ -105,5 +108,13 @@ def TelegramLinker(data:InputMessageData) -> SafeNamespace:
|
|||||||
linked.message = f"https://t.me/c/{room_id}/{message_id}"
|
linked.message = f"https://t.me/c/{room_id}/{message_id}"
|
||||||
return linked
|
return linked
|
||||||
|
|
||||||
RegisterPlatform(name="Telegram", main=TelegramMain, sender=TelegramSender, linker=TelegramLinker, event_class=telegram.Update, manager_class=(lambda:TelegramClient))
|
RegisterPlatform(
|
||||||
|
name="Telegram",
|
||||||
|
main=TelegramMain,
|
||||||
|
sender=TelegramSender,
|
||||||
|
linker=TelegramLinker,
|
||||||
|
event_class=telegram.Update,
|
||||||
|
manager_class=(lambda:TelegramClient),
|
||||||
|
agent_info=(lambda:TelegramMakeUserData(TelegramClient.bot.get_me())),
|
||||||
|
)
|
||||||
|
|
||||||
|
@ -70,7 +70,7 @@ def WebMakeInputMessageData(text:str, uuid:str) -> InputMessageData:
|
|||||||
room = SafeNamespace(
|
room = SafeNamespace(
|
||||||
id = f"web:{uuid}",
|
id = f"web:{uuid}",
|
||||||
),
|
),
|
||||||
user = SafeNamespace(
|
user = UserData(
|
||||||
settings = SafeNamespace(),
|
settings = SafeNamespace(),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
0
LibWinDog/Platforms/Web/multithread_http_server.py
Normal file → Executable file
0
LibWinDog/Platforms/Web/multithread_http_server.py
Normal file → Executable file
@ -5,18 +5,29 @@
|
|||||||
|
|
||||||
from types import SimpleNamespace
|
from types import SimpleNamespace
|
||||||
|
|
||||||
class SafeNamespace(SimpleNamespace):
|
class DictNamespace(SimpleNamespace):
|
||||||
def __getattribute__(self, value):
|
def __iter__(self):
|
||||||
|
return self.__dict__.__iter__()
|
||||||
|
def __getitem__(self, key):
|
||||||
|
return self.__getattribute__(key)
|
||||||
|
def __setitem__(self, key, value):
|
||||||
|
return self.__setattr__(key, value)
|
||||||
|
|
||||||
|
class SafeNamespace(DictNamespace):
|
||||||
|
def __getattribute__(self, key):
|
||||||
try:
|
try:
|
||||||
return super().__getattribute__(value)
|
return super().__getattribute__(key)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# we just use these for type hinting:
|
# we just use these for type hinting and clearer code:
|
||||||
|
|
||||||
class EventContext(SafeNamespace):
|
class EventContext(SafeNamespace):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
class UserData(SafeNamespace):
|
||||||
|
pass
|
||||||
|
|
||||||
class MessageData(SafeNamespace):
|
class MessageData(SafeNamespace):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -1,42 +0,0 @@
|
|||||||
{
|
|
||||||
"help": [
|
|
||||||
"*There's no one around to help (yet).*"
|
|
||||||
],
|
|
||||||
"wish": {
|
|
||||||
"empty": [
|
|
||||||
"*You wished for nothing! ✨*\n\n_Nothing happens..._"
|
|
||||||
],
|
|
||||||
"done": [
|
|
||||||
"*Your wish has been cast! ✨*\n\n_Chance of success: *{Percent}%*._"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"hug": {
|
|
||||||
"empty": [
|
|
||||||
"*Hug? You didn't reply to anyone...*"
|
|
||||||
],
|
|
||||||
"bot": [],
|
|
||||||
"self": [],
|
|
||||||
"others": [
|
|
||||||
"*{0} hugs {1} tightly... :3*"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"level": {
|
|
||||||
"empty": [
|
|
||||||
"Check what's your level of something.\n\n*Usage*: {Cmd} <Thing>."
|
|
||||||
],
|
|
||||||
"done": [
|
|
||||||
"_Your level of *{Thing}* is... *{Percent}%*._"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"hash": {
|
|
||||||
"usage": [
|
|
||||||
"*Usage*: {0} <Algorithm> <Text to Hash>.\n\n*Available algorithms*: {1}."
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"eval": [
|
|
||||||
"This feature is not implemented [Security Issue]."
|
|
||||||
],
|
|
||||||
"time": [
|
|
||||||
"Local time: *{0}*."
|
|
||||||
]
|
|
||||||
}
|
|
139
Locale/it.json
139
Locale/it.json
@ -1,139 +0,0 @@
|
|||||||
{
|
|
||||||
"help": [
|
|
||||||
"*Non c'è nessuno qui ad aiutarti (per ora).*"
|
|
||||||
],
|
|
||||||
"wish": {
|
|
||||||
"empty": [
|
|
||||||
"*Non hai desiderato nulla! ✨*\n\n_Non succede niente..._"
|
|
||||||
],
|
|
||||||
"done": [
|
|
||||||
"*Il tuo desiderio è stato espresso! ✨*\n\n_Probabilità che si avveri: *{Percent}%*._"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"level": {
|
|
||||||
"empty": [
|
|
||||||
"Controlla il tuo livello di qualcosa.\n\n*Uso*: {Cmd} <Cosa>."
|
|
||||||
],
|
|
||||||
"done": [
|
|
||||||
"_Il tuo livello di *{Thing}* è... *{Percent}%*._"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"hug": {
|
|
||||||
"empty": [
|
|
||||||
"*Chi vuoi abbracciare? Rispondi a qualcuno.*",
|
|
||||||
"*Un abbraccio a chi? Non hai risposto a nessuno...*"
|
|
||||||
],
|
|
||||||
"bot": [
|
|
||||||
"*...Grazie uwu <3*",
|
|
||||||
"*Non puoi abbracciarmi ☁️ :/*"
|
|
||||||
],
|
|
||||||
"self": [
|
|
||||||
"*{0} allunga le braccia attorno a sè, si stringe forte, e si sente ora meno triste.*"
|
|
||||||
],
|
|
||||||
"others": [
|
|
||||||
"*{0} abbraccia {1} forte forte... :3*",
|
|
||||||
"*{0} ti ha dato un abbraccio!*"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"pat": {
|
|
||||||
"empty": [
|
|
||||||
"*Chi vuoi accarezzare? Rispondi a qualcuno.*",
|
|
||||||
"*Una carezza a chi? Non hai risposto a nessuno...*"
|
|
||||||
],
|
|
||||||
"bot": [
|
|
||||||
"*Rawrrr xDDdd*",
|
|
||||||
"*Come vuoi accarezzarmi? Vivo nel cloud... :(*"
|
|
||||||
],
|
|
||||||
"self": [
|
|
||||||
"*{0} allunga goffamente la mano dietro di sè per accarezzarsi in testa 🙃*"
|
|
||||||
],
|
|
||||||
"others": [
|
|
||||||
"*{0} fa patpat a {1} ^.^*",
|
|
||||||
"*{0} ti accarezza con dolcezza.*"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"poke": {
|
|
||||||
"empty": [
|
|
||||||
"*Chi vuoi punzecchiare? Rispondi a qualcuno.*",
|
|
||||||
"*Punzecchiare chi? Non hai risposto a nessuno...*"
|
|
||||||
],
|
|
||||||
"bot": [
|
|
||||||
"*>_< perché?*",
|
|
||||||
"*heh ☁️😌*"
|
|
||||||
],
|
|
||||||
"self": [
|
|
||||||
"*{0} si punzecchia :o*"
|
|
||||||
],
|
|
||||||
"others": [
|
|
||||||
"*{0} punzecchia {1} 👀*",
|
|
||||||
"*{0} ti punzecchia con impertinenza 👉*"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"cuddle": {
|
|
||||||
"empty": [
|
|
||||||
"*A chi vuoi fare le coccole? Rispondi a qualcuno.*",
|
|
||||||
"*Le coccole? A chi? Non hai risposto a nessuno...*"
|
|
||||||
],
|
|
||||||
"bot": [
|
|
||||||
"*Aww.. grazie :3*",
|
|
||||||
"*Vorrei anche io le coccole ma... ☁️😔*"
|
|
||||||
],
|
|
||||||
"self": [
|
|
||||||
"*{0} si stende sul letto e prova a farsi le coccole, per sentirsi meglio.*"
|
|
||||||
],
|
|
||||||
"others": [
|
|
||||||
"*{0} fa le coccole a {1} 🥰*",
|
|
||||||
"*{0} ti fa le coccole! 🤗️*"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"floor": {
|
|
||||||
"empty": [
|
|
||||||
"*Il pavimento?*",
|
|
||||||
"*Il pavimentowo?*",
|
|
||||||
"*Vuoi mettere qualcuno sul pavimento? Rispondi ad un suo messaggio.*"
|
|
||||||
],
|
|
||||||
"bot": [
|
|
||||||
"*Sono già sul pavimento.. sono sempre sul pavimento.*"
|
|
||||||
],
|
|
||||||
"self": [
|
|
||||||
"*{0} si mette sul pavimento.*"
|
|
||||||
],
|
|
||||||
"others": [
|
|
||||||
"*{0} solleva {1} dal pavimento.*",
|
|
||||||
"*{0} ti prende in braccio e ti appoggia con delicatezza sul pavimento.*"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"empty": [
|
|
||||||
"*Le t.me/manineuwu? 😳️*",
|
|
||||||
"*A chi vuoi dare le manine? Rispondi a qualcuno.*"
|
|
||||||
],
|
|
||||||
"bot": [
|
|
||||||
"*Io non le ho le manine,.,. 😭️*"
|
|
||||||
],
|
|
||||||
"self": [
|
|
||||||
"*{0} fa handholding in solitudine... 😶️*",
|
|
||||||
"*{0} non ha nessuno a cui dare la mano 😐️*"
|
|
||||||
],
|
|
||||||
"others": [
|
|
||||||
"*{0} prende le mani di {1} 😳️❤️*",
|
|
||||||
"*{0} vuole darti la sua manina 🥺👉️👈️*"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"sessocto": {
|
|
||||||
"empty": [
|
|
||||||
"*Sessocto?!?! 😳️*",
|
|
||||||
"*Vuoi fare sessocto con qualcuno? Rispondi ad un suo messaggio.*"
|
|
||||||
],
|
|
||||||
"bot": [
|
|
||||||
"*Vorrei anche io sessocto ma non ho un corpo... 😥️*"
|
|
||||||
],
|
|
||||||
"self": [
|
|
||||||
"*{0} fa sessocto in singleplayer 😳️*"
|
|
||||||
],
|
|
||||||
"others": [
|
|
||||||
"*{0} vuole fare sessocto con te... 👀️*",
|
|
||||||
"*{0} e {1} fanno sessocto insieme 💑️*"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
@ -38,12 +38,12 @@ def cPing(context:EventContext, data:InputMessageData) -> None:
|
|||||||
# CharEscape(choice(Locale.__('time')).format(time.ctime().replace(' ', ' ')), 'MARKDOWN_SPEECH'),
|
# CharEscape(choice(Locale.__('time')).format(time.ctime().replace(' ', ' ')), 'MARKDOWN_SPEECH'),
|
||||||
# reply_to_message_id=update.message.message_id)
|
# reply_to_message_id=update.message.message_id)
|
||||||
|
|
||||||
def cEval(context:EventContext, data:InputMessageData) -> None:
|
#def cEval(context:EventContext, data:InputMessageData) -> None:
|
||||||
SendMessage(context, {"Text": choice(Locale.__('eval'))})
|
# SendMessage(context, {"Text": choice(Locale.__('eval'))})
|
||||||
|
|
||||||
RegisterModule(name="Base", endpoints=[
|
RegisterModule(name="Base", endpoints=[
|
||||||
SafeNamespace(names=["source"], handler=cSource),
|
SafeNamespace(names=["source"], handler=cSource),
|
||||||
SafeNamespace(names=["config"], handler=cConfig, arguments={
|
SafeNamespace(names=["config"], handler=cConfig, body=False, arguments={
|
||||||
"get": True,
|
"get": True,
|
||||||
}),
|
}),
|
||||||
#SafeNamespace(names=["gdpr"], summary="Operations for european citizens regarding your personal data.", handler=cGdpr),
|
#SafeNamespace(names=["gdpr"], summary="Operations for european citizens regarding your personal data.", handler=cGdpr),
|
||||||
|
0
ModWinDog/Base/Base.yaml
Normal file → Executable file
0
ModWinDog/Base/Base.yaml
Normal file → Executable file
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
def cBroadcast(context:EventContext, data:InputMessageData) -> None:
|
def cBroadcast(context:EventContext, data:InputMessageData) -> None:
|
||||||
if (data.user.id not in AdminIds) and (data.user.tag not in AdminIds):
|
if (data.user.id not in AdminIds) and (data.user.tag not in AdminIds):
|
||||||
return SendMessage(context, {"Text": choice(Locale.__('eval'))})
|
return SendMessage(context, {"Text": "Permission denied."})
|
||||||
destination = data.command.arguments["destination"]
|
destination = data.command.arguments["destination"]
|
||||||
text = data.command.body
|
text = data.command.body
|
||||||
if not (destination and text):
|
if not (destination and text):
|
||||||
@ -14,7 +14,7 @@ def cBroadcast(context:EventContext, data:InputMessageData) -> None:
|
|||||||
SendMessage(context, OutputMessageData(text_plain="Executed."))
|
SendMessage(context, OutputMessageData(text_plain="Executed."))
|
||||||
|
|
||||||
RegisterModule(name="Broadcast", endpoints=[
|
RegisterModule(name="Broadcast", endpoints=[
|
||||||
SafeNamespace(names=["broadcast"], handler=cBroadcast, arguments={
|
SafeNamespace(names=["broadcast"], handler=cBroadcast, body=True, arguments={
|
||||||
"destination": True,
|
"destination": True,
|
||||||
}),
|
}),
|
||||||
])
|
])
|
||||||
|
0
ModWinDog/Broadcast/Broadcast.yaml
Normal file → Executable file
0
ModWinDog/Broadcast/Broadcast.yaml
Normal file → Executable file
@ -6,11 +6,12 @@
|
|||||||
from json import dumps as json_dumps
|
from json import dumps as json_dumps
|
||||||
|
|
||||||
def cDump(context:EventContext, data:InputMessageData):
|
def cDump(context:EventContext, data:InputMessageData):
|
||||||
if not (message := ObjGet(data, "quoted")):
|
SendMessage(context, {
|
||||||
pass # TODO send error message
|
"text_html": (f'<pre>{json_dumps(message, default=(lambda obj: obj.__dict__), indent=" ")}</pre>'
|
||||||
SendMessage(context, {"TextPlain": json_dumps(message, default=(lambda obj: obj.__dict__), indent=" ")})
|
if (message := ObjGet(data, "quoted"))
|
||||||
|
else context.endpoint.help_text(data.user.settings.language))})
|
||||||
|
|
||||||
RegisterModule(name="Dumper", group="Geek", endpoints=[
|
RegisterModule(name="Dumper", group="Geek", endpoints=[
|
||||||
SafeNamespace(names=["dump"], handler=cDump),
|
SafeNamespace(names=["dump"], handler=cDump, quoted=True),
|
||||||
])
|
])
|
||||||
|
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
summary:
|
summary:
|
||||||
en: Functions for dumping of various data.
|
en: Functions for dumping of various data.
|
||||||
dump:
|
endpoints:
|
||||||
|
dump:
|
||||||
summary:
|
summary:
|
||||||
en: Dumps the data for a quoted message and returns the JSON representation.
|
en: Dumps the data for a quoted message and returns the JSON representation.
|
||||||
|
body:
|
||||||
|
en: Target message
|
||||||
|
|
||||||
|
@ -5,21 +5,22 @@
|
|||||||
|
|
||||||
def cEcho(context:EventContext, data:InputMessageData) -> None:
|
def cEcho(context:EventContext, data:InputMessageData) -> None:
|
||||||
if not (text := ObjGet(data, "command.body")):
|
if not (text := ObjGet(data, "command.body")):
|
||||||
return SendMessage(context, {"text_html": context.endpoint.get_string("empty", data.user.settings.language)})
|
return SendMessage(context, {
|
||||||
|
"text_html": context.endpoint.get_string("empty", data.user.settings.language)})
|
||||||
prefix = f'<a href="{data.message_url}">🗣️</a> '
|
prefix = f'<a href="{data.message_url}">🗣️</a> '
|
||||||
#prefix = f"[🗣️]({context.linker(data).message}) "
|
if len(data.command.tokens) == 2: # text is a single word
|
||||||
if len(data.command.tokens) == 2:
|
|
||||||
nonascii = True
|
nonascii = True
|
||||||
for char in data.command.tokens[1]:
|
for char in data.command.tokens[1]:
|
||||||
if ord(char) < 256:
|
if ord(char) < 256:
|
||||||
nonascii = False
|
nonascii = False
|
||||||
break
|
break
|
||||||
if nonascii:
|
if nonascii:
|
||||||
# text is not ascii, probably an emoji (altough not necessarily), so just pass as is (useful for Telegram emojis)
|
# word is not ascii, probably an emoji (altough not necessarily)
|
||||||
|
# so just pass it as is (useful for Telegram emojis)
|
||||||
prefix = ''
|
prefix = ''
|
||||||
SendMessage(context, {"text_html": (prefix + html_escape(text))})
|
SendMessage(context, {"text_html": (prefix + html_escape(text))})
|
||||||
|
|
||||||
RegisterModule(name="Echo", endpoints=[
|
RegisterModule(name="Echo", endpoints=[
|
||||||
SafeNamespace(names=["echo"], handler=cEcho),
|
SafeNamespace(names=["echo"], handler=cEcho, body=True),
|
||||||
])
|
])
|
||||||
|
|
||||||
|
@ -18,6 +18,6 @@ def cGpt(context:EventContext, data:InputMessageData) -> None:
|
|||||||
return SendMessage(context, {"TextPlain": f"[🤖️ GPT]\n\n{output}"})
|
return SendMessage(context, {"TextPlain": f"[🤖️ GPT]\n\n{output}"})
|
||||||
|
|
||||||
RegisterModule(name="GPT", endpoints=[
|
RegisterModule(name="GPT", endpoints=[
|
||||||
SafeNamespace(names=["gpt", "chatgpt"], handler=cGpt),
|
SafeNamespace(names=["gpt", "chatgpt"], handler=cGpt, body=True),
|
||||||
])
|
])
|
||||||
|
|
||||||
|
0
ModWinDog/GPT/GPT.yaml
Normal file → Executable file
0
ModWinDog/GPT/GPT.yaml
Normal file → Executable file
@ -6,15 +6,17 @@
|
|||||||
import hashlib
|
import hashlib
|
||||||
|
|
||||||
def cHash(context:EventContext, data:InputMessageData):
|
def cHash(context:EventContext, data:InputMessageData):
|
||||||
text_input = ObjGet(data, "command.body")
|
text_input = (data.command.body or (data.quoted and data.quoted.text_plain))
|
||||||
algorithm = ObjGet(data, "command.arguments.algorithm")
|
algorithm = data.command.arguments.algorithm
|
||||||
|
language = data.user.settings.language
|
||||||
if not (text_input and (algorithm in hashlib.algorithms_available)):
|
if not (text_input and (algorithm in hashlib.algorithms_available)):
|
||||||
return SendMessage(context, {"Text": choice(Locale.__('hash.usage')).format(data.command.tokens[0], hashlib.algorithms_available)})
|
return SendMessage(context, {
|
||||||
|
"text_html": f'{context.endpoint.help_text(language)}\n\n{context.endpoint.get_string("algorithms", language)}: {hashlib.algorithms_available}'})
|
||||||
hashed = hashlib.new(algorithm, text_input.encode()).hexdigest()
|
hashed = hashlib.new(algorithm, text_input.encode()).hexdigest()
|
||||||
return SendMessage(context, OutputMessageData(text_plain=hashed, text_html=f"<pre>{hashed}</pre>"))
|
return SendMessage(context, {"text_html": f"<pre>{hashed}</pre>"})
|
||||||
|
|
||||||
RegisterModule(name="Hashing", group="Geek", endpoints=[
|
RegisterModule(name="Hashing", group="Geek", endpoints=[
|
||||||
SafeNamespace(names=["hash"], handler=cHash, arguments={
|
SafeNamespace(names=["hash"], handler=cHash, body=False, quoted=False, arguments={
|
||||||
"algorithm": True,
|
"algorithm": True,
|
||||||
}),
|
}),
|
||||||
])
|
])
|
||||||
|
@ -4,7 +4,10 @@ summary:
|
|||||||
endpoints:
|
endpoints:
|
||||||
hash:
|
hash:
|
||||||
summary:
|
summary:
|
||||||
en: Responds with the hash-sum of the received message.
|
en: Responds with the hash-sum of the included or quoted text.
|
||||||
|
algorithms:
|
||||||
|
en: Available algorithms
|
||||||
|
it: Algoritmi disponibili
|
||||||
arguments:
|
arguments:
|
||||||
algorithm:
|
algorithm:
|
||||||
en: Algorithm
|
en: Algorithm
|
||||||
|
@ -5,16 +5,16 @@
|
|||||||
|
|
||||||
# TODO: implement /help <commandname> feature
|
# TODO: implement /help <commandname> feature
|
||||||
def cHelp(context:EventContext, data:InputMessageData) -> None:
|
def cHelp(context:EventContext, data:InputMessageData) -> None:
|
||||||
module_list = ''
|
text = (context.endpoint.get_string(lang=data.user.settings.language) or '')
|
||||||
language = data.user.settings.language
|
language = data.user.settings.language
|
||||||
for module in Modules:
|
for module in Modules:
|
||||||
summary = Modules[module].get_string("summary", language)
|
summary = Modules[module].get_string("summary", language)
|
||||||
endpoints = Modules[module].endpoints
|
endpoints = Modules[module].endpoints
|
||||||
module_list += (f"\n\n{module}" + (f": {summary}" if summary else ''))
|
text += (f"\n\n{module}" + (f": {summary}" if summary else ''))
|
||||||
for endpoint in endpoints:
|
for endpoint in endpoints:
|
||||||
summary = Modules[module].get_string(f"endpoints.{endpoint.names[0]}.summary", language)
|
summary = Modules[module].get_string(f"endpoints.{endpoint.names[0]}.summary", language)
|
||||||
module_list += (f"\n* /{', /'.join(endpoint.names)}" + (f": {summary}" if summary else ''))
|
text += (f"\n* /{', /'.join(endpoint.names)}" + (f": {summary}" if summary else ''))
|
||||||
SendMessage(context, OutputMessageData(text=module_list))
|
SendMessage(context, {"text_html": text})
|
||||||
|
|
||||||
RegisterModule(name="Help", group="Basic", endpoints=[
|
RegisterModule(name="Help", group="Basic", endpoints=[
|
||||||
SafeNamespace(names=["help"], handler=cHelp),
|
SafeNamespace(names=["help"], handler=cHelp),
|
||||||
|
5
ModWinDog/Help/Help.yaml
Normal file → Executable file
5
ModWinDog/Help/Help.yaml
Normal file → Executable file
@ -2,4 +2,9 @@ endpoints:
|
|||||||
help:
|
help:
|
||||||
summary:
|
summary:
|
||||||
en: Provides help for the bot. For now, it just lists the commands.
|
en: Provides help for the bot. For now, it just lists the commands.
|
||||||
|
help:
|
||||||
|
en: >
|
||||||
|
<b>There's no one around to help.</b> However, you can have the commands list:
|
||||||
|
it: >
|
||||||
|
<b>Non c'è nessuno qui ad aiutarti.</b> Tuttavia, puoi avere la lista dei comandi:
|
||||||
|
|
||||||
|
@ -137,13 +137,13 @@ def cSafebooru(context:EventContext, data:InputMessageData) -> None:
|
|||||||
raise
|
raise
|
||||||
|
|
||||||
RegisterModule(name="Internet", endpoints=[
|
RegisterModule(name="Internet", endpoints=[
|
||||||
SafeNamespace(names=["embedded"], handler=cEmbedded),
|
SafeNamespace(names=["embedded"], handler=cEmbedded, body=False, quoted=False),
|
||||||
SafeNamespace(names=["web"], handler=cWeb),
|
SafeNamespace(names=["web"], handler=cWeb, body=True),
|
||||||
SafeNamespace(names=["translate"], handler=cTranslate, arguments={
|
SafeNamespace(names=["translate"], handler=cTranslate, body=False, quoted=False, arguments={
|
||||||
"language_to": True,
|
"language_to": True,
|
||||||
"language_from": False,
|
"language_from": False,
|
||||||
}),
|
}),
|
||||||
#SafeNamespace(names=["unsplash"], summary="Sends a picture sourced from Unsplash.", handler=cUnsplash),
|
#SafeNamespace(names=["unsplash"], summary="Sends a picture sourced from Unsplash.", handler=cUnsplash),
|
||||||
SafeNamespace(names=["safebooru"], handler=cSafebooru),
|
SafeNamespace(names=["safebooru"], handler=cSafebooru, body=False),
|
||||||
])
|
])
|
||||||
|
|
||||||
|
0
ModWinDog/Internet/Internet.yaml
Normal file → Executable file
0
ModWinDog/Internet/Internet.yaml
Normal file → Executable file
@ -4,23 +4,22 @@
|
|||||||
# ================================== #
|
# ================================== #
|
||||||
|
|
||||||
def mMultifun(context:EventContext, data:InputMessageData) -> None:
|
def mMultifun(context:EventContext, data:InputMessageData) -> None:
|
||||||
cmdkey = data.command.name
|
reply_to = None
|
||||||
replyToId = None
|
fun_strings = {}
|
||||||
|
for key in ("empty", "bot", "self", "others"):
|
||||||
|
fun_strings[key] = context.endpoint.get_string(key, data.user.settings.language)
|
||||||
if data.quoted:
|
if data.quoted:
|
||||||
replyFromUid = data.quoted.user.id
|
if fun_strings["bot"] and (data.quoted.user.id == Platforms[context.platform].agent_info.id):
|
||||||
# TODO work on all platforms for the bot id
|
text = choice(fun_strings["bot"])
|
||||||
if replyFromUid.split(':')[1] == TelegramToken.split(':')[0] and 'bot' in Locale.__(cmdkey):
|
elif fun_strings["self"] and (data.quoted.user.id == data.user.id):
|
||||||
Text = choice(Locale.__(f'{cmdkey}.bot'))
|
text = choice(fun_strings["self"]).format(data.user.name)
|
||||||
elif replyFromUid == data.user.id and 'self' in Locale.__(cmdkey):
|
elif fun_strings["others"]:
|
||||||
Text = choice(Locale.__(f'{cmdkey}.self')).format(data.user.name)
|
text = choice(fun_strings["others"]).format(data.user.name, data.quoted.user.name)
|
||||||
|
reply_to = data.quoted.message_id
|
||||||
else:
|
else:
|
||||||
if 'others' in Locale.__(cmdkey):
|
if fun_strings["empty"]:
|
||||||
Text = choice(Locale.__(f'{cmdkey}.others')).format(data.user.name, data.quoted.user.name)
|
text = choice(fun_strings["empty"])
|
||||||
replyToId = data.quoted.message_id
|
SendMessage(context, {"text_html": text, "ReplyTo": reply_to})
|
||||||
else:
|
|
||||||
if 'empty' in Locale.__(cmdkey):
|
|
||||||
Text = choice(Locale.__(f'{cmdkey}.empty'))
|
|
||||||
SendMessage(context, {"Text": Text, "ReplyTo": replyToId})
|
|
||||||
|
|
||||||
RegisterModule(name="Multifun", endpoints=[
|
RegisterModule(name="Multifun", endpoints=[
|
||||||
SafeNamespace(names=["hug", "pat", "poke", "cuddle", "hands", "floor", "sessocto"], handler=mMultifun),
|
SafeNamespace(names=["hug", "pat", "poke", "cuddle", "hands", "floor", "sessocto"], handler=mMultifun),
|
||||||
|
116
ModWinDog/Multifun/Multifun.yaml
Normal file → Executable file
116
ModWinDog/Multifun/Multifun.yaml
Normal file → Executable file
@ -1,3 +1,119 @@
|
|||||||
summary:
|
summary:
|
||||||
en: Provides fun trough preprogrammed text-based toys.
|
en: Provides fun trough preprogrammed text-based toys.
|
||||||
|
endpoints:
|
||||||
|
hug:
|
||||||
|
empty:
|
||||||
|
en:
|
||||||
|
- <b>Hug? You haven't replied to anyone...</b>
|
||||||
|
it:
|
||||||
|
- <b>Chi vuoi abbracciare? Rispondi a qualcuno.</b>
|
||||||
|
- <b>Un abbraccio a chi? Non hai risposto a nessuno...</b>
|
||||||
|
bot:
|
||||||
|
it:
|
||||||
|
- <b>...Grazie uwu <3</b>
|
||||||
|
- <b>Non puoi abbracciarmi ☁️ :/</b>
|
||||||
|
self:
|
||||||
|
it:
|
||||||
|
- <b>{0} allunga le braccia attorno a sè, si stringe forte, e si sente ora meno triste.</b>
|
||||||
|
others:
|
||||||
|
en:
|
||||||
|
- <b>{0} hugs {1} tightly... :3</b>
|
||||||
|
it:
|
||||||
|
- <b>{0} abbraccia {1} forte forte... :3</b>
|
||||||
|
- <b>{0} ti ha dato un abbraccio!</b>
|
||||||
|
pat:
|
||||||
|
empty:
|
||||||
|
it:
|
||||||
|
- <b>Chi vuoi accarezzare? Rispondi a qualcuno.</b>
|
||||||
|
- <b>Una carezza a chi? Non hai risposto a nessuno...</b>
|
||||||
|
bot:
|
||||||
|
it:
|
||||||
|
- <b>Rawrrr xDDdd</b>
|
||||||
|
- <b>Come vuoi accarezzarmi? Vivo nel cloud... :(</b>
|
||||||
|
self:
|
||||||
|
it:
|
||||||
|
- <b>{0} allunga goffamente la mano dietro di sè per accarezzarsi in testa 🙃</b>
|
||||||
|
others:
|
||||||
|
it:
|
||||||
|
- <b>{0} fa patpat a {1} ^.^</b>
|
||||||
|
- <b>{0} ti accarezza con dolcezza.</b>
|
||||||
|
poke:
|
||||||
|
empty:
|
||||||
|
it:
|
||||||
|
- <b>Chi vuoi punzecchiare? Rispondi a qualcuno.</b>
|
||||||
|
- <b>Punzecchiare chi? Non hai risposto a nessuno...</b>
|
||||||
|
bot:
|
||||||
|
it:
|
||||||
|
- <b>>_< perché?</b>
|
||||||
|
- <b>heh ☁️😌</b>
|
||||||
|
self:
|
||||||
|
it:
|
||||||
|
- <b>{0} si punzecchia :o</b>
|
||||||
|
others:
|
||||||
|
it:
|
||||||
|
- <b>{0} punzecchia {1} 👀*</b>
|
||||||
|
- <b>{0} ti punzecchia con impertinenza 👉</b>
|
||||||
|
cuddle:
|
||||||
|
empty:
|
||||||
|
it:
|
||||||
|
- <b>A chi vuoi fare le coccole? Rispondi a qualcuno.</b>
|
||||||
|
- <b>Le coccole? A chi? Non hai risposto a nessuno...</b>
|
||||||
|
bot:
|
||||||
|
it:
|
||||||
|
- <b>Aww.. grazie :3</b>
|
||||||
|
- <b>Vorrei anche io le coccole ma... ☁️😔</b>
|
||||||
|
self:
|
||||||
|
it:
|
||||||
|
- <b>{0} si stende sul letto e prova a farsi le coccole, per sentirsi meglio.</b>
|
||||||
|
others:
|
||||||
|
it:
|
||||||
|
- <b>{0} fa le coccole a {1} 🥰</b>
|
||||||
|
- <b>{0} ti fa le coccole! 🤗️</b>
|
||||||
|
floor:
|
||||||
|
empty:
|
||||||
|
it:
|
||||||
|
- <b>Il pavimento?</b>
|
||||||
|
- <b>Il pavimentowo?</b>
|
||||||
|
- <b>Vuoi mettere qualcuno sul pavimento? Rispondi ad un suo messaggio.</b>
|
||||||
|
bot:
|
||||||
|
it:
|
||||||
|
- <b>Sono già sul pavimento.. sono sempre sul pavimento.</b>
|
||||||
|
self:
|
||||||
|
it:
|
||||||
|
- <b>{0} si mette sul pavimento.</b>
|
||||||
|
others:
|
||||||
|
it:
|
||||||
|
- <b>{0} solleva {1} dal pavimento.</b>
|
||||||
|
- <b>{0} ti prende in braccio e ti appoggia con delicatezza sul pavimento.</b>
|
||||||
|
hands:
|
||||||
|
empty:
|
||||||
|
it:
|
||||||
|
- <b>Le t.me/manineuwu? 😳️</b>
|
||||||
|
- <b>A chi vuoi dare le manine? Rispondi a qualcuno.</b>
|
||||||
|
bot:
|
||||||
|
it:
|
||||||
|
- <b>Io non le ho le manine,.,. 😭️</b>
|
||||||
|
self:
|
||||||
|
it:
|
||||||
|
- <b>{0} fa handholding in solitudine... 😶️</b>
|
||||||
|
- <b>{0} non ha nessuno a cui dare la mano 😐️</b>
|
||||||
|
others:
|
||||||
|
it:
|
||||||
|
- <b>{0} prende le mani di {1} 😳️❤️</b>
|
||||||
|
- <b>{0} vuole darti la sua manina 🥺👉️👈️</b>
|
||||||
|
sessocto:
|
||||||
|
empty:
|
||||||
|
it:
|
||||||
|
- <b>Sessocto?!?! 😳️</b>
|
||||||
|
- <b>Vuoi fare sessocto con qualcuno? Rispondi ad un suo messaggio.</b>
|
||||||
|
bot:
|
||||||
|
it:
|
||||||
|
- <b>Vorrei anche io sessocto ma non ho un corpo... 😥️</b>
|
||||||
|
self:
|
||||||
|
it:
|
||||||
|
- <b>{0} fa sessocto in singleplayer 😳️</b>
|
||||||
|
others:
|
||||||
|
it:
|
||||||
|
- <b>{0} vuole fare sessocto con te... 👀️</b>
|
||||||
|
- <b>{0} e {1} fanno sessocto insieme 💑️</b>
|
||||||
|
|
||||||
|
@ -4,10 +4,13 @@
|
|||||||
# ==================================== #
|
# ==================================== #
|
||||||
|
|
||||||
def mPercenter(context:EventContext, data:InputMessageData) -> None:
|
def mPercenter(context:EventContext, data:InputMessageData) -> None:
|
||||||
SendMessage(context, {"Text": choice(Locale.__(f'{data.command.name}.{"done" if data.command.body else "empty"}')).format(
|
SendMessage(context, {"text_html": (context.endpoint.get_string(
|
||||||
Cmd=data.command.tokens[0], Percent=RandPercent(), Thing=data.command.body)})
|
("done" if data.command.body else "empty"),
|
||||||
|
data.user.settings.language
|
||||||
|
) or context.endpoint.help_text(data.user.settings.language)
|
||||||
|
).format(RandPercent(), data.command.body)})
|
||||||
|
|
||||||
RegisterModule(name="Percenter", endpoints=[
|
RegisterModule(name="Percenter", endpoints=[
|
||||||
SafeNamespace(names=["wish", "level"], handler=mPercenter),
|
SafeNamespace(names=["wish", "level"], handler=mPercenter, body=True),
|
||||||
])
|
])
|
||||||
|
|
||||||
|
27
ModWinDog/Percenter/Percenter.yaml
Normal file → Executable file
27
ModWinDog/Percenter/Percenter.yaml
Normal file → Executable file
@ -1,3 +1,30 @@
|
|||||||
summary:
|
summary:
|
||||||
en: Provides fun trough percentage-based toys.
|
en: Provides fun trough percentage-based toys.
|
||||||
|
endpoints:
|
||||||
|
wish:
|
||||||
|
empty:
|
||||||
|
en: |
|
||||||
|
<b>You wished for nothing! ✨</b>
|
||||||
|
|
||||||
|
<i>Nothing happens...</i>
|
||||||
|
it: |
|
||||||
|
<b>Non hai desiderato nulla! ✨</b>
|
||||||
|
|
||||||
|
<i>Non succede niente...</i>
|
||||||
|
done:
|
||||||
|
en: |
|
||||||
|
<b>Your wish has been cast! ✨</b>
|
||||||
|
|
||||||
|
<i>Chance of success: <b>{0}%</b>.</i>
|
||||||
|
it: |
|
||||||
|
<b>Il tuo desiderio è stato espresso! ✨</b>
|
||||||
|
|
||||||
|
<i>Probabilità che si avveri: <b>{0}%</b>.</i>
|
||||||
|
level:
|
||||||
|
summary:
|
||||||
|
en: Check what's your level of something.
|
||||||
|
it: Controlla il tuo livello di qualcosa.
|
||||||
|
done:
|
||||||
|
en: <i>Your level of <b>{1}</b> is... <b>{0}%</b>.</i>
|
||||||
|
it: <i>Il tuo livello di <b>{1}</b> è... <b>{0}%</b>.</i>
|
||||||
|
|
||||||
|
@ -119,7 +119,7 @@ def cCraiyonSelenium(context:EventContext, data:InputMessageData) -> None:
|
|||||||
closeSelenium(driver_index, driver)
|
closeSelenium(driver_index, driver)
|
||||||
|
|
||||||
RegisterModule(name="Scrapers", endpoints=[
|
RegisterModule(name="Scrapers", endpoints=[
|
||||||
SafeNamespace(names=["dalle"], handler=cDalleSelenium),
|
SafeNamespace(names=["dalle"], handler=cDalleSelenium, body=True),
|
||||||
SafeNamespace(names=["craiyon", "crayion"], handler=cCraiyonSelenium),
|
SafeNamespace(names=["craiyon", "crayion"], handler=cCraiyonSelenium, body=True),
|
||||||
])
|
])
|
||||||
|
|
||||||
|
0
ModWinDog/Scrapers/Scrapers.yaml
Normal file → Executable file
0
ModWinDog/Scrapers/Scrapers.yaml
Normal file → Executable file
@ -53,6 +53,6 @@ end)()"""))
|
|||||||
SendMessage(context, {"TextPlain": textOutput})
|
SendMessage(context, {"TextPlain": textOutput})
|
||||||
|
|
||||||
RegisterModule(name="Scripting", group="Geek", endpoints=[
|
RegisterModule(name="Scripting", group="Geek", endpoints=[
|
||||||
SafeNamespace(names=["lua"], handler=cLua),
|
SafeNamespace(names=["lua"], handler=cLua, body=False, quoted=False),
|
||||||
])
|
])
|
||||||
|
|
||||||
|
0
ModWinDog/Scripting/Scripting.yaml
Normal file → Executable file
0
ModWinDog/Scripting/Scripting.yaml
Normal file → Executable file
0
ModWinDog/Start/Start.py
Normal file → Executable file
0
ModWinDog/Start/Start.py
Normal file → Executable file
0
ModWinDog/Start/Start.yaml
Normal file → Executable file
0
ModWinDog/Start/Start.yaml
Normal file → Executable file
4
ModWinDog/System/System.py
Normal file → Executable file
4
ModWinDog/System/System.py
Normal file → Executable file
@ -15,7 +15,7 @@ from re import compile as re_compile
|
|||||||
|
|
||||||
def cExec(context:EventContext, data:InputMessageData) -> None:
|
def cExec(context:EventContext, data:InputMessageData) -> None:
|
||||||
if not (len(data.command.tokens) >= 2 and data.command.tokens[1].lower() in ExecAllowed):
|
if not (len(data.command.tokens) >= 2 and data.command.tokens[1].lower() in ExecAllowed):
|
||||||
return SendMessage(context, {"Text": choice(Locale.__('eval'))})
|
return SendMessage(context, {"Text": "This feature is not implemented [Security Issue]."})
|
||||||
command = data.command.tokens[1].lower()
|
command = data.command.tokens[1].lower()
|
||||||
output = subprocess.run(
|
output = subprocess.run(
|
||||||
("sh", "-c", f"export PATH=$PATH:/usr/games; {command}"),
|
("sh", "-c", f"export PATH=$PATH:/usr/games; {command}"),
|
||||||
@ -26,6 +26,6 @@ def cExec(context:EventContext, data:InputMessageData) -> None:
|
|||||||
text_plain=text, text_html=f"<pre>{html_escape(text)}</pre>"))
|
text_plain=text, text_html=f"<pre>{html_escape(text)}</pre>"))
|
||||||
|
|
||||||
RegisterModule(name="System", endpoints=[
|
RegisterModule(name="System", endpoints=[
|
||||||
SafeNamespace(names=["exec"], handler=cExec),
|
SafeNamespace(names=["exec"], handler=cExec, body=True),
|
||||||
])
|
])
|
||||||
|
|
||||||
|
0
ModWinDog/System/System.yaml
Normal file → Executable file
0
ModWinDog/System/System.yaml
Normal file → Executable file
89
WinDog.py
89
WinDog.py
@ -49,39 +49,6 @@ def Log(text:str, level:str="?", *, newline:bool|None=None, inline:bool=False) -
|
|||||||
if LogToFile:
|
if LogToFile:
|
||||||
open("./Log.txt", 'a').write(text + endline)
|
open("./Log.txt", 'a').write(text + endline)
|
||||||
|
|
||||||
def SetupLocales() -> None:
|
|
||||||
global Locale
|
|
||||||
for file in listdir('./Locale'):
|
|
||||||
lang = file.split('.')[0]
|
|
||||||
try:
|
|
||||||
with open(f'./Locale/{file}') as file:
|
|
||||||
Locale[lang] = json.load(file)
|
|
||||||
except Exception:
|
|
||||||
Log(f'Cannot load {lang} locale, exiting.')
|
|
||||||
raise
|
|
||||||
exit(1)
|
|
||||||
for key in Locale[DefaultLanguage]:
|
|
||||||
Locale['Fallback'][key] = Locale[DefaultLanguage][key]
|
|
||||||
for lang in Locale:
|
|
||||||
for key in Locale[lang]:
|
|
||||||
if not key in Locale['Fallback']:
|
|
||||||
Locale['Fallback'][key] = Locale[lang][key]
|
|
||||||
def querier(query:str, lang:str=DefaultLanguage):
|
|
||||||
value = None
|
|
||||||
query = query.split('.')
|
|
||||||
try:
|
|
||||||
value = Locale.Locale[lang]
|
|
||||||
for key in query:
|
|
||||||
value = value[key]
|
|
||||||
except Exception:
|
|
||||||
value = Locale.Locale['Fallback']
|
|
||||||
for key in query:
|
|
||||||
value = value[key]
|
|
||||||
return value
|
|
||||||
Locale['__'] = querier
|
|
||||||
Locale['Locale'] = Locale
|
|
||||||
Locale = SimpleNamespace(**Locale)
|
|
||||||
|
|
||||||
def SureArray(array:any) -> list|tuple:
|
def SureArray(array:any) -> list|tuple:
|
||||||
return (array if type(array) in [list, tuple] else [array])
|
return (array if type(array) in [list, tuple] else [array])
|
||||||
|
|
||||||
@ -112,12 +79,39 @@ def isinstanceSafe(clazz:any, instance:any, /) -> bool:
|
|||||||
return isinstance(clazz, instance)
|
return isinstance(clazz, instance)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def get_string(bank:dict, query:str|dict, lang:str=None, /):
|
def good_yaml_load(text:str):
|
||||||
|
return yaml_load(text.replace("\t", " "), Loader=yaml_BaseLoader)
|
||||||
|
|
||||||
|
def get_string(bank:dict, query:str|dict, lang:str=None) -> str|list[str]|None:
|
||||||
if not (result := ObjGet(bank, f"{query}.{lang or DefaultLanguage}")):
|
if not (result := ObjGet(bank, f"{query}.{lang or DefaultLanguage}")):
|
||||||
if not (result := ObjGet(bank, f"{query}.en")):
|
if not (result := ObjGet(bank, f"{query}.en")):
|
||||||
result = ObjGet(bank, query)
|
result = ObjGet(bank, query)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
def help_text(endpoint, lang:str=None) -> str:
|
||||||
|
global_string = (lambda query: get_string(GlobalStrings, query, lang))
|
||||||
|
text = f'{endpoint.get_string("summary", lang) or ""}\n\n{global_string("usage")}:'
|
||||||
|
if endpoint.arguments:
|
||||||
|
for argument in endpoint.arguments:
|
||||||
|
if endpoint.arguments[argument]:
|
||||||
|
text += f' <{endpoint.get_string(f"arguments.{argument}", lang) or argument}>'
|
||||||
|
body_help = endpoint.get_string("body", lang)
|
||||||
|
quoted_help = (global_string("quoted_message") + (f': {body_help}' if body_help else ''))
|
||||||
|
if not body_help:
|
||||||
|
body_help = global_string("text")
|
||||||
|
if endpoint.body == False and endpoint.quoted == False:
|
||||||
|
text += f' <{global_string("text")} {global_string("or")} {global_string("quoted_message")}: {body_help}>'
|
||||||
|
else:
|
||||||
|
if endpoint.body == True:
|
||||||
|
text += f' <{body_help}>'
|
||||||
|
elif endpoint.body == False:
|
||||||
|
text += f' [{body_help}]'
|
||||||
|
if endpoint.quoted == True:
|
||||||
|
text += f' <{quoted_help}>'
|
||||||
|
elif endpoint.quoted == False:
|
||||||
|
text += f' [{quoted_help}]'
|
||||||
|
return text
|
||||||
|
|
||||||
def strip_url_scheme(url:str) -> str:
|
def strip_url_scheme(url:str) -> str:
|
||||||
tokens = urlparse.urlparse(url)
|
tokens = urlparse.urlparse(url)
|
||||||
return f"{tokens.netloc}{tokens.path}"
|
return f"{tokens.netloc}{tokens.path}"
|
||||||
@ -172,7 +166,6 @@ def GetUserSettings(user_id:str) -> SafeNamespace|None:
|
|||||||
except EntitySettings.DoesNotExist:
|
except EntitySettings.DoesNotExist:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# TODO ignore tagged commands when they are not directed to the bot's username
|
|
||||||
def ParseCommand(text:str) -> SafeNamespace|None:
|
def ParseCommand(text:str) -> SafeNamespace|None:
|
||||||
if not text:
|
if not text:
|
||||||
return None
|
return None
|
||||||
@ -184,12 +177,15 @@ def ParseCommand(text:str) -> SafeNamespace|None:
|
|||||||
return None
|
return None
|
||||||
command = SafeNamespace()
|
command = SafeNamespace()
|
||||||
command.tokens = text.split()
|
command.tokens = text.split()
|
||||||
command.name = command.tokens[0][1:].lower().split('@')[0]
|
command.name, command_target = (command.tokens[0][1:].lower().split('@') + [''])
|
||||||
|
# TODO ignore tagged commands when they are not directed to the bot's username
|
||||||
|
if command_target and not command_target:
|
||||||
|
return None
|
||||||
command.body = text[len(command.tokens[0]):].strip()
|
command.body = text[len(command.tokens[0]):].strip()
|
||||||
if command.name not in Endpoints:
|
if command.name not in Endpoints:
|
||||||
return command
|
return command
|
||||||
if (endpoint_arguments := Endpoints[command.name].arguments):
|
if (endpoint_arguments := Endpoints[command.name].arguments):
|
||||||
command.arguments = {}
|
command.arguments = SafeNamespace()
|
||||||
index = 1
|
index = 1
|
||||||
for key in endpoint_arguments:
|
for key in endpoint_arguments:
|
||||||
if not endpoint_arguments[key]:
|
if not endpoint_arguments[key]:
|
||||||
@ -300,14 +296,14 @@ def SendNotice(context:EventContext, data) -> None:
|
|||||||
def DeleteMessage(context:EventContext, data) -> None:
|
def DeleteMessage(context:EventContext, data) -> None:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def RegisterPlatform(name:str, main:callable, sender:callable, linker:callable=None, *, event_class=None, manager_class=None) -> None:
|
def RegisterPlatform(name:str, main:callable, sender:callable, linker:callable=None, *, event_class=None, manager_class=None, agent_info=None) -> None:
|
||||||
Platforms[name.lower()] = SafeNamespace(name=name, main=main, sender=sender, linker=linker, event_class=event_class, manager_class=manager_class)
|
Platforms[name.lower()] = SafeNamespace(name=name, main=main, sender=sender, linker=linker, event_class=event_class, manager_class=manager_class, agent_info=agent_info)
|
||||||
Log(f"{name}, ", inline=True)
|
Log(f"{name}, ", inline=True)
|
||||||
|
|
||||||
def RegisterModule(name:str, endpoints:dict, *, group:str|None=None) -> None:
|
def RegisterModule(name:str, endpoints:dict, *, group:str|None=None) -> None:
|
||||||
module = SafeNamespace(group=group, endpoints=endpoints, get_string=(lambda query, lang=None, /: None))
|
module = SafeNamespace(group=group, endpoints=endpoints, get_string=(lambda query, lang=None: None))
|
||||||
if isfile(file := f"./ModWinDog/{name}/{name}.yaml"):
|
if isfile(file := f"./ModWinDog/{name}/{name}.yaml"):
|
||||||
module.strings = yaml_load(open(file, 'r').read().replace("\t", " "), Loader=yaml_BaseLoader)
|
module.strings = good_yaml_load(open(file, 'r').read())
|
||||||
module.get_string = (lambda query, lang=None: get_string(module.strings, query, lang))
|
module.get_string = (lambda query, lang=None: get_string(module.strings, query, lang))
|
||||||
Modules[name] = module
|
Modules[name] = module
|
||||||
Log(f"{name}, ", inline=True)
|
Log(f"{name}, ", inline=True)
|
||||||
@ -318,9 +314,13 @@ def RegisterModule(name:str, endpoints:dict, *, group:str|None=None) -> None:
|
|||||||
|
|
||||||
def CallEndpoint(name:str, context:EventContext, data:InputMessageData):
|
def CallEndpoint(name:str, context:EventContext, data:InputMessageData):
|
||||||
endpoint = Endpoints[name]
|
endpoint = Endpoints[name]
|
||||||
context.endpoint = endpoint
|
|
||||||
context.module = endpoint.module
|
context.module = endpoint.module
|
||||||
context.endpoint.get_string = (lambda query, lang=None, /: endpoint.module.get_string(f"endpoints.{data.command.name}.{query}", lang))
|
context.endpoint = endpoint
|
||||||
|
context.endpoint.get_string = (lambda query=data.command.name, lang=None:
|
||||||
|
endpoint.module.get_string(f"endpoints.{data.command.name}.{query}", lang))
|
||||||
|
context.endpoint.help_text = (lambda lang=None: help_text(endpoint, lang))
|
||||||
|
if callable(agent_info := Platforms[context.platform].agent_info):
|
||||||
|
Platforms[context.platform].agent_info = agent_info()
|
||||||
return endpoint.handler(context, data)
|
return endpoint.handler(context, data)
|
||||||
|
|
||||||
def WriteNewConfig() -> None:
|
def WriteNewConfig() -> None:
|
||||||
@ -341,7 +341,6 @@ def WriteNewConfig() -> None:
|
|||||||
|
|
||||||
def Main() -> None:
|
def Main() -> None:
|
||||||
#SetupDb()
|
#SetupDb()
|
||||||
SetupLocales()
|
|
||||||
Log(f"📨️ Initializing Platforms... ", newline=False)
|
Log(f"📨️ Initializing Platforms... ", newline=False)
|
||||||
for platform in Platforms.values():
|
for platform in Platforms.values():
|
||||||
if platform.main():
|
if platform.main():
|
||||||
@ -353,7 +352,7 @@ def Main() -> None:
|
|||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
Log("🌞️ WinDog Starting...")
|
Log("🌞️ WinDog Starting...")
|
||||||
Locale = {"Fallback": {}}
|
GlobalStrings = good_yaml_load(open("./WinDog.yaml", 'r').read())
|
||||||
Platforms, Modules, ModuleGroups, Endpoints = {}, {}, {}, {}
|
Platforms, Modules, ModuleGroups, Endpoints = {}, {}, {}, {}
|
||||||
|
|
||||||
for folder in ("LibWinDog/Platforms", "ModWinDog"):
|
for folder in ("LibWinDog/Platforms", "ModWinDog"):
|
||||||
|
13
WinDog.yaml
Normal file
13
WinDog.yaml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
or:
|
||||||
|
en: or
|
||||||
|
it: o
|
||||||
|
quoted_message:
|
||||||
|
en: Quoted Message
|
||||||
|
it: Messaggio Citato
|
||||||
|
text:
|
||||||
|
en: Text
|
||||||
|
it: Testo
|
||||||
|
usage:
|
||||||
|
en: Usage
|
||||||
|
it: Uso
|
||||||
|
|
Reference in New Issue
Block a user