mirror of
https://gitlab.com/octospacc/WinDog.git
synced 2025-06-05 22:09:20 +02:00
More work on Matrix, move commands to new HTML locales, fix Mastodon
This commit is contained in:
@@ -3,11 +3,6 @@
|
||||
# Licensed under AGPLv3 by OctoSpacc #
|
||||
# ==================================== #
|
||||
|
||||
import re, subprocess
|
||||
|
||||
def cStart(context:EventContext, data:InputMessageData) -> None:
|
||||
SendMessage(context, {"Text": choice(Locale.__('start')).format(data.User.Name)})
|
||||
|
||||
def cSource(context:EventContext, data:InputMessageData) -> None:
|
||||
SendMessage(context, {"TextPlain": ("""\
|
||||
* Original Code: {https://gitlab.com/octospacc/WinDog}
|
||||
@@ -20,8 +15,12 @@ def cGdpr(context:EventContext, data:InputMessageData) -> None:
|
||||
def cConfig(context:EventContext, data:InputMessageData) -> None:
|
||||
if not (settings := GetUserSettings(data.user.id)):
|
||||
User.update(settings=EntitySettings.create()).where(User.id == data.user.id).execute()
|
||||
if (get := ObjGet(data, "command.arguments.get")):
|
||||
SendMessage(context, OutputMessageData(text_plain=str(ObjGet(data.user.settings, get))))
|
||||
if (to_set := ObjGet(data, "command.arguments.set")):
|
||||
pass # TODO set in db, but first we need to ensure data is handled safely
|
||||
if (to_get := ObjGet(data, "command.arguments.get")):
|
||||
# TODO show a hint on possible options?
|
||||
return SendMessage(context, OutputMessageData(text_plain=str(ObjGet(data.user.settings, to_get))))
|
||||
# TODO show general help when no useful parameters are passed
|
||||
#Cmd = TelegramHandleCmd(update)
|
||||
#if not Cmd: return
|
||||
# ... area: eu, us, ...
|
||||
@@ -39,30 +38,14 @@ def cPing(context:EventContext, data:InputMessageData) -> None:
|
||||
def cEval(context:EventContext, data:InputMessageData) -> None:
|
||||
SendMessage(context, {"Text": choice(Locale.__('eval'))})
|
||||
|
||||
def cExec(context:EventContext, data:InputMessageData) -> None:
|
||||
if len(data.Tokens) >= 2 and data.Tokens[1].lower() in ExecAllowed:
|
||||
cmd = data.Tokens[1].lower()
|
||||
Out = subprocess.run(('sh', '-c', f'export PATH=$PATH:/usr/games; {cmd}'),
|
||||
stdout=subprocess.PIPE, stderr=subprocess.STDOUT).stdout.decode()
|
||||
# <https://stackoverflow.com/a/14693789>
|
||||
Caption = (re.compile(r'\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])').sub('', Out))
|
||||
SendMessage(context, {
|
||||
"TextPlain": Caption,
|
||||
"TextMarkdown": MarkdownCode(Caption, True),
|
||||
})
|
||||
else:
|
||||
SendMessage(context, {"Text": choice(Locale.__('eval'))})
|
||||
|
||||
RegisterModule(name="Misc", endpoints=[
|
||||
SafeNamespace(names=["start"], summary="Salutes the user, hinting that the bot is working and providing basic quick help.", handler=cStart),
|
||||
RegisterModule(name="Base", endpoints=[
|
||||
SafeNamespace(names=["source"], summary="Provides a copy of the bot source codes and/or instructions on how to get it.", handler=cSource),
|
||||
SafeNamespace(names=["config"], handler=cConfig, arguments={
|
||||
"get": True,
|
||||
}),
|
||||
#SafeNamespace(names=["gdpr"], summary="Operations for european citizens regarding your personal data.", handler=cGdpr),
|
||||
SafeNamespace(names=["ping"], summary="Responds pong, useful for testing messaging latency.", handler=cPing),
|
||||
SafeNamespace(names=["eval"], summary="Execute a Python command (or safe literal operation) in the current context. Currently not implemented.", handler=cEval),
|
||||
SafeNamespace(names=["exec"], summary="Execute a system command from the allowed ones and return stdout+stderr.", handler=cExec),
|
||||
#SafeNamespace(names=["eval"], summary="Execute a Python command (or safe literal operation) in the current context. Currently not implemented.", handler=cEval),
|
||||
#SafeNamespace(names=["format"], summary="Reformat text using an handful of rules. Not yet implemented.", handler=cFormat),
|
||||
#SafeNamespace(names=["frame"], summary="Frame someone's message into a platform-styled image. Not yet implemented.", handler=cFrame),
|
||||
#SafeNamespace(names=["repeat"], summary="I had this planned but I don't remember what this should have done. Not yet implemented.", handler=cRepeat),
|
||||
|
0
ModWinDog/Dumper/Dumper.yaml
Normal file → Executable file
0
ModWinDog/Dumper/Dumper.yaml
Normal file → Executable file
30
ModWinDog/Echo/Echo.py
Normal file → Executable file
30
ModWinDog/Echo/Echo.py
Normal file → Executable file
@@ -4,22 +4,20 @@
|
||||
# ==================================== #
|
||||
|
||||
def cEcho(context:EventContext, data:InputMessageData) -> None:
|
||||
text = ObjGet(data, "command.body")
|
||||
if text:
|
||||
prefix = "🗣️ "
|
||||
#prefix = f"[🗣️]({context.linker(data).message}) "
|
||||
if len(data.Tokens) == 2:
|
||||
nonascii = True
|
||||
for char in data.Tokens[1]:
|
||||
if ord(char) < 256:
|
||||
nonascii = False
|
||||
break
|
||||
if nonascii:
|
||||
# text is not ascii, probably an emoji (altough not necessarily), so just pass as is (useful for Telegram emojis)
|
||||
prefix = ''
|
||||
SendMessage(context, OutputMessageData(text=(prefix + text)))
|
||||
else:
|
||||
SendMessage(context, OutputMessageData(text_html=context.endpoint.get_string('empty')))
|
||||
if not (text := ObjGet(data, "command.body")):
|
||||
return SendMessage(context, OutputMessageData(text_html=context.endpoint.get_string("empty", data.user.settings.language)))
|
||||
prefix = f'<a href="{data.message_url}">🗣️</a> '
|
||||
#prefix = f"[🗣️]({context.linker(data).message}) "
|
||||
if len(data.command.tokens) == 2:
|
||||
nonascii = True
|
||||
for char in data.command.tokens[1]:
|
||||
if ord(char) < 256:
|
||||
nonascii = False
|
||||
break
|
||||
if nonascii:
|
||||
# text is not ascii, probably an emoji (altough not necessarily), so just pass as is (useful for Telegram emojis)
|
||||
prefix = ''
|
||||
SendMessage(context, OutputMessageData(text_html=(prefix + html_escape(text))))
|
||||
|
||||
RegisterModule(name="Echo", endpoints=[
|
||||
SafeNamespace(names=["echo"], handler=cEcho),
|
||||
|
2
ModWinDog/Echo/Echo.yaml
Normal file → Executable file
2
ModWinDog/Echo/Echo.yaml
Normal file → Executable file
@@ -1,3 +1,5 @@
|
||||
summary:
|
||||
en: Tools for repeating messages.
|
||||
endpoints:
|
||||
echo:
|
||||
summary:
|
||||
|
4
ModWinDog/GPT/GPT.py
Normal file → Executable file
4
ModWinDog/GPT/GPT.py
Normal file → Executable file
@@ -8,12 +8,12 @@ from g4f.client import Client as G4FClient
|
||||
g4fClient = G4FClient()
|
||||
|
||||
def cGpt(context:EventContext, data:InputMessageData) -> None:
|
||||
if not data.command.body:
|
||||
if not (prompt := data.command.body):
|
||||
return SendMessage(context, {"Text": "You must type some text."})
|
||||
output = None
|
||||
while not output or output.startswith("sorry, 您的ip已由于触发防滥用检测而被封禁,本服务网址是"): # quick fix for a strange ratelimit message
|
||||
output = ""
|
||||
for completion in g4fClient.chat.completions.create(model="gpt-3.5-turbo", messages=[{"role": "user", "content": data.command.body}], stream=True):
|
||||
for completion in g4fClient.chat.completions.create(model="gpt-3.5-turbo", messages=[{"role": "user", "content": prompt}], stream=True):
|
||||
output += (completion.choices[0].delta.content or "")
|
||||
return SendMessage(context, {"TextPlain": f"[🤖️ GPT]\n\n{output}"})
|
||||
|
||||
|
0
ModWinDog/GPT/requirements.txt
Normal file → Executable file
0
ModWinDog/GPT/requirements.txt
Normal file → Executable file
@@ -11,13 +11,10 @@ def cHash(context:EventContext, data:InputMessageData):
|
||||
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)})
|
||||
hashed = hashlib.new(algorithm, text_input.encode()).hexdigest()
|
||||
return SendMessage(context, {
|
||||
"TextPlain": hashed,
|
||||
"TextMarkdown": MarkdownCode(hashed, True),
|
||||
})
|
||||
return SendMessage(context, OutputMessageData(text_plain=hashed, text_html=f"<pre>{hashed}</pre>"))
|
||||
|
||||
RegisterModule(name="Hashing", group="Geek", summary="Functions for hashing of textual content.", endpoints=[
|
||||
SafeNamespace(names=["hash"], summary="Responds with the hash-sum of a message received.", handler=cHash, arguments={
|
||||
RegisterModule(name="Hashing", group="Geek", endpoints=[
|
||||
SafeNamespace(names=["hash"], handler=cHash, arguments={
|
||||
"algorithm": True,
|
||||
}),
|
||||
])
|
||||
|
21
ModWinDog/Hashing/Hashing.yaml
Normal file → Executable file
21
ModWinDog/Hashing/Hashing.yaml
Normal file → Executable file
@@ -1,14 +1,15 @@
|
||||
summary:
|
||||
en: Functions for calculating hashes of content.
|
||||
it: Funzioni per calcolare hash di contenuti.
|
||||
hash:
|
||||
summary:
|
||||
en: Responds with the hash-sum of the received message.
|
||||
arguments:
|
||||
algorithm:
|
||||
en: Algorithm
|
||||
it: Algoritmo
|
||||
body:
|
||||
en: Text to hash
|
||||
it: Testo da hashare
|
||||
endpoints:
|
||||
hash:
|
||||
summary:
|
||||
en: Responds with the hash-sum of the received message.
|
||||
arguments:
|
||||
algorithm:
|
||||
en: Algorithm
|
||||
it: Algoritmo
|
||||
body:
|
||||
en: Text to hash
|
||||
it: Testo da hashare
|
||||
|
||||
|
@@ -5,17 +5,18 @@
|
||||
|
||||
# TODO: implement /help <commandname> feature
|
||||
def cHelp(context:EventContext, data:InputMessageData) -> None:
|
||||
moduleList = ''
|
||||
module_list = ''
|
||||
language = data.user.settings.language
|
||||
for module in Modules:
|
||||
summary = Modules[module].summary
|
||||
summary = Modules[module].get_string("summary", language)#summary
|
||||
endpoints = Modules[module].endpoints
|
||||
moduleList += (f"\n\n{module}" + (f": {summary}" if summary else ''))
|
||||
module_list += (f"\n\n{module}" + (f": {summary}" if summary else ''))
|
||||
for endpoint in endpoints:
|
||||
summary = endpoint.summary
|
||||
moduleList += (f"\n* /{', /'.join(endpoint.names)}" + (f": {summary}" if summary else ''))
|
||||
SendMessage(context, {"Text": f"[ Available Modules ]{moduleList}"})
|
||||
summary = Modules[module].get_string(f"endpoints.{endpoint.names[0]}.summary", language)
|
||||
module_list += (f"\n* /{', /'.join(endpoint.names)}" + (f": {summary}" if summary else ''))
|
||||
SendMessage(context, OutputMessageData(text=module_list))
|
||||
|
||||
RegisterModule(name="Help", group="Basic", endpoints=[
|
||||
SafeNamespace(names=["help"], summary="Provides help for the bot. For now, it just lists the commands.", handler=cHelp),
|
||||
SafeNamespace(names=["help"], handler=cHelp),
|
||||
])
|
||||
|
||||
|
5
ModWinDog/Help/Help.yaml
Normal file
5
ModWinDog/Help/Help.yaml
Normal file
@@ -0,0 +1,5 @@
|
||||
endpoints:
|
||||
help:
|
||||
summary:
|
||||
en: Provides help for the bot. For now, it just lists the commands.
|
||||
|
@@ -10,19 +10,18 @@ MicrosoftBingSettings = {}
|
||||
""" # end windog config # """
|
||||
|
||||
from urlextract import URLExtract
|
||||
from urllib import parse as UrlParse
|
||||
from urllib.request import urlopen, Request
|
||||
|
||||
def HttpReq(url:str, method:str|None=None, *, body:bytes=None, headers:dict[str, str]={"User-Agent": WebUserAgent}):
|
||||
return urlopen(Request(url, method=method, data=body, headers=headers))
|
||||
|
||||
def cEmbedded(context:EventContext, data:InputMessageData) -> None:
|
||||
if len(data.Tokens) >= 2:
|
||||
if len(data.command.tokens) >= 2:
|
||||
# Find links in command body
|
||||
Text = (data.TextMarkdown + ' ' + data.TextPlain)
|
||||
elif data.Quoted and data.Quoted.Text:
|
||||
Text = (data.text_markdown + ' ' + data.text_plain)
|
||||
elif data.quoted and data.quoted.text_auto:
|
||||
# Find links in quoted message
|
||||
Text = (data.Quoted.TextMarkdown + ' ' + data.Quoted.TextPlain)
|
||||
Text = (data.quoted.text_markdown + ' ' + data.quoted.text_plain)
|
||||
else:
|
||||
# TODO Error message
|
||||
return
|
||||
@@ -41,38 +40,37 @@ def cEmbedded(context:EventContext, data:InputMessageData) -> None:
|
||||
url = "https://hlb0.octt.eu.org/cors-main.php/https://" + url
|
||||
proto = ''
|
||||
else:
|
||||
if urlDomain == "instagram.com":
|
||||
if urlDomain in ("instagram.com", "www.instagram.com"):
|
||||
urlDomain = "ddinstagram.com"
|
||||
elif urlDomain in ("twitter.com", "x.com"):
|
||||
urlDomain = "fxtwitter.com"
|
||||
elif urlDomain == "vm.tiktok.com":
|
||||
urlDomain = "vm.vxtiktok.com"
|
||||
url = urlDomain + url[len(urlDomain):]
|
||||
url = (urlDomain + '/' + '/'.join(url.split('/')[1:]))
|
||||
SendMessage(context, {"TextPlain": f"{{{proto}{url}}}"})
|
||||
# else TODO error message?
|
||||
|
||||
def cWeb(context:EventContext, data:InputMessageData) -> None:
|
||||
if data.Body:
|
||||
try:
|
||||
QueryUrl = UrlParse.quote(data.Body)
|
||||
Req = HttpReq(f'https://html.duckduckgo.com/html?q={QueryUrl}')
|
||||
Caption = f'🦆🔎 "{data.Body}": https://duckduckgo.com/?q={QueryUrl}\n\n'
|
||||
Index = 0
|
||||
for Line in Req.read().decode().replace('\t', ' ').splitlines():
|
||||
if ' class="result__a" ' in Line and ' href="//duckduckgo.com/l/?uddg=' in Line:
|
||||
Index += 1
|
||||
Link = UrlParse.unquote(Line.split(' href="//duckduckgo.com/l/?uddg=')[1].split('&rut=')[0])
|
||||
Title = Line.strip().split('</a>')[0].strip().split('</span>')[-1].strip().split('>')
|
||||
if len(Title) > 1:
|
||||
Title = HtmlUnescape(Title[1].strip())
|
||||
Caption += f'[{Index}] {Title} : {{{Link}}}\n\n'
|
||||
else:
|
||||
continue
|
||||
SendMessage(context, {"TextPlain": f'{Caption}...'})
|
||||
except Exception:
|
||||
raise
|
||||
else:
|
||||
pass
|
||||
if not (query := data.command.body):
|
||||
return # TODO show message
|
||||
try:
|
||||
QueryUrl = urlparse.quote(query)
|
||||
Req = HttpReq(f'https://html.duckduckgo.com/html?q={QueryUrl}')
|
||||
Caption = f'🦆🔎 "{query}": https://duckduckgo.com/?q={QueryUrl}\n\n'
|
||||
Index = 0
|
||||
for Line in Req.read().decode().replace('\t', ' ').splitlines():
|
||||
if ' class="result__a" ' in Line and ' href="//duckduckgo.com/l/?uddg=' in Line:
|
||||
Index += 1
|
||||
Link = urlparse.unquote(Line.split(' href="//duckduckgo.com/l/?uddg=')[1].split('&rut=')[0])
|
||||
Title = Line.strip().split('</a>')[0].strip().split('</span>')[-1].strip().split('>')
|
||||
if len(Title) > 1:
|
||||
Title = html_unescape(Title[1].strip())
|
||||
Caption += f'[{Index}] {Title} : {{{Link}}}\n\n'
|
||||
else:
|
||||
continue
|
||||
SendMessage(context, {"TextPlain": f'{Caption}...'})
|
||||
except Exception:
|
||||
raise
|
||||
|
||||
def cImages(context:EventContext, data:InputMessageData) -> None:
|
||||
pass
|
||||
@@ -82,57 +80,57 @@ def cNews(context:EventContext, data:InputMessageData) -> None:
|
||||
|
||||
def cTranslate(context:EventContext, data:InputMessageData) -> None:
|
||||
language_to = data.command.arguments["language_to"]
|
||||
text_input = (data.command.body or (data.Quoted and data.Quoted.Body))
|
||||
text_input = (data.command.body or (data.quoted and data.quoted.text_plain))
|
||||
if not (text_input and language_to):
|
||||
return SendMessage(context, {"TextPlain": f"Usage: /translate <to language> <text>"})
|
||||
try:
|
||||
# TODO: Use many different public Lingva instances in rotation to avoid overloading a specific one
|
||||
result = json.loads(HttpReq(f'https://lingva.ml/api/v1/auto/{language_to}/{UrlParse.quote(text_input)}').read())
|
||||
result = json.loads(HttpReq(f'https://lingva.ml/api/v1/auto/{language_to}/{urlparse.quote(text_input)}').read())
|
||||
SendMessage(context, {"TextPlain": f"[{result['info']['detectedSource']} (auto) -> {language_to}]\n\n{result['translation']}"})
|
||||
except Exception:
|
||||
raise
|
||||
|
||||
# unsplash source appears to be deprecated! <https://old.reddit.com/r/unsplash/comments/s13x4h/what_happened_to_sourceunsplashcom/l65epl8/>
|
||||
def cUnsplash(context:EventContext, data:InputMessageData) -> None:
|
||||
try:
|
||||
Req = HttpReq(f'https://source.unsplash.com/random/?{UrlParse.quote(data.Body)}')
|
||||
ImgUrl = Req.geturl().split('?')[0]
|
||||
SendMessage(context, {
|
||||
"TextPlain": f'{{{ImgUrl}}}',
|
||||
"TextMarkdown": MarkdownCode(ImgUrl, True),
|
||||
"Media": Req.read(),
|
||||
})
|
||||
except Exception:
|
||||
raise
|
||||
#def cUnsplash(context:EventContext, data:InputMessageData) -> None:
|
||||
# try:
|
||||
# Req = HttpReq(f'https://source.unsplash.com/random/?{urlparse.quote(data.command.body)}')
|
||||
# ImgUrl = Req.geturl().split('?')[0]
|
||||
# SendMessage(context, {
|
||||
# "TextPlain": f'{{{ImgUrl}}}',
|
||||
# "TextMarkdown": MarkdownCode(ImgUrl, True),
|
||||
# "Media": Req.read(),
|
||||
# })
|
||||
# except Exception:
|
||||
# raise
|
||||
|
||||
def cSafebooru(context:EventContext, data:InputMessageData) -> None:
|
||||
ApiUrl = 'https://safebooru.org/index.php?page=dapi&s=post&q=index&limit=100&tags='
|
||||
try:
|
||||
if data.Body:
|
||||
img_id, img_url = None, None
|
||||
if (query := data.command.body):
|
||||
for i in range(7): # retry a bunch of times if we can't find a really random result
|
||||
ImgUrls = HttpReq(f'{ApiUrl}md5:{RandHexStr(3)}%20{UrlParse.quote(data.Body)}').read().decode().split(' file_url="')[1:]
|
||||
ImgUrls = HttpReq(f'{ApiUrl}md5:{RandHexStr(3)}%20{urlparse.quote(query)}').read().decode().split(' file_url="')[1:]
|
||||
if ImgUrls:
|
||||
break
|
||||
if not ImgUrls: # literal search
|
||||
ImgUrls = HttpReq(f'{ApiUrl}{UrlParse.quote(data.Body)}').read().decode().split(' file_url="')[1:]
|
||||
ImgUrls = HttpReq(f'{ApiUrl}{urlparse.quote(query)}').read().decode().split(' file_url="')[1:]
|
||||
if not ImgUrls:
|
||||
return SendMessage(context, {"Text": "Error: Could not get any result from Safebooru."})
|
||||
ImgXml = choice(ImgUrls)
|
||||
ImgUrl = ImgXml.split('"')[0]
|
||||
ImgId = ImgXml.split(' id="')[1].split('"')[0]
|
||||
img_url = ImgXml.split('"')[0]
|
||||
img_id = ImgXml.split(' id="')[1].split('"')[0]
|
||||
else:
|
||||
HtmlReq = HttpReq(HttpReq('https://safebooru.org/index.php?page=post&s=random').geturl())
|
||||
for Line in HtmlReq.read().decode().replace('\t', ' ').splitlines():
|
||||
if '<img ' in Line and ' id="image" ' in Line and ' src="':
|
||||
ImgUrl = Line.split(' src="')[1].split('"')[0]
|
||||
ImgId = ImgUrl.split('?')[-1]
|
||||
img_url = Line.split(' src="')[1].split('"')[0]
|
||||
img_id = img_url.split('?')[-1]
|
||||
break
|
||||
if ImgUrl:
|
||||
SendMessage(context, {
|
||||
"TextPlain": f'[{ImgId}]\n{{{ImgUrl}}}',
|
||||
"TextMarkdown": (f'\\[`{ImgId}`\\]\n' + MarkdownCode(ImgUrl, True)),
|
||||
"media": {"url": ImgUrl}, #, "bytes": HttpReq(ImgUrl).read()},
|
||||
})
|
||||
if img_url:
|
||||
SendMessage(context, OutputMessageData(
|
||||
text_plain=f"[{img_id}]\n{{{img_url}}}",
|
||||
text_html=f"[<code>{img_id}</code>]\n<pre>{img_url}</pre>",
|
||||
media={"url": img_url}))
|
||||
else:
|
||||
pass
|
||||
except Exception as error:
|
||||
|
14
ModWinDog/Multifun/Multifun.py
Normal file → Executable file
14
ModWinDog/Multifun/Multifun.py
Normal file → Executable file
@@ -4,19 +4,19 @@
|
||||
# ==================================== #
|
||||
|
||||
def mMultifun(context:EventContext, data:InputMessageData) -> None:
|
||||
cmdkey = data.Name
|
||||
cmdkey = data.command.name
|
||||
replyToId = None
|
||||
if data.Quoted:
|
||||
replyFromUid = data.Quoted.User.Id
|
||||
if data.quoted:
|
||||
replyFromUid = data.quoted.user.id
|
||||
# TODO work on all platforms for the bot id
|
||||
if replyFromUid.split(':')[1] == TelegramToken.split(':')[0] and 'bot' in Locale.__(cmdkey):
|
||||
Text = choice(Locale.__(f'{cmdkey}.bot'))
|
||||
elif replyFromUid == data.User.Id and 'self' in Locale.__(cmdkey):
|
||||
Text = choice(Locale.__(f'{cmdkey}.self')).format(data.User.Name)
|
||||
elif replyFromUid == data.user.id and 'self' in Locale.__(cmdkey):
|
||||
Text = choice(Locale.__(f'{cmdkey}.self')).format(data.user.name)
|
||||
else:
|
||||
if 'others' in Locale.__(cmdkey):
|
||||
Text = choice(Locale.__(f'{cmdkey}.others')).format(data.User.Name, data.Quoted.User.Name)
|
||||
replyToId = data.Quoted.messageId
|
||||
Text = choice(Locale.__(f'{cmdkey}.others')).format(data.user.name, data.quoted.user.name)
|
||||
replyToId = data.quoted.message_id
|
||||
else:
|
||||
if 'empty' in Locale.__(cmdkey):
|
||||
Text = choice(Locale.__(f'{cmdkey}.empty'))
|
||||
|
4
ModWinDog/Percenter/Percenter.py
Normal file → Executable file
4
ModWinDog/Percenter/Percenter.py
Normal file → Executable file
@@ -4,8 +4,8 @@
|
||||
# ==================================== #
|
||||
|
||||
def mPercenter(context:EventContext, data:InputMessageData) -> None:
|
||||
SendMessage(context, {"Text": choice(Locale.__(f'{data.Name}.{"done" if data.Body else "empty"}')).format(
|
||||
Cmd=data.Tokens[0], Percent=RandPercent(), Thing=data.Body)})
|
||||
SendMessage(context, {"Text": choice(Locale.__(f'{data.command.name}.{"done" if data.command.body else "empty"}')).format(
|
||||
Cmd=data.command.tokens[0], Percent=RandPercent(), Thing=data.command.body)})
|
||||
|
||||
RegisterModule(name="Percenter", endpoints=[
|
||||
SafeNamespace(names=["wish", "level"], summary="Provides fun trough percentage-based toys.", handler=mPercenter),
|
||||
|
@@ -36,8 +36,7 @@ def closeSelenium(index:int, driver:Driver) -> None:
|
||||
|
||||
def cDalleSelenium(context:EventContext, data:InputMessageData) -> None:
|
||||
warning_text = "has been blocked by Microsoft because it violates their content policy. Further attempts might lead to a ban on your profile. Please review the Code of Conduct for Image Creator in this picture or at https://www.bing.com/new/termsofuseimagecreator#content-policy."
|
||||
prompt = data.command.body
|
||||
if not prompt:
|
||||
if not (prompt := data.command.body):
|
||||
return SendMessage(context, {"Text": "Please tell me what to generate."})
|
||||
driver_index, driver = None, None
|
||||
try:
|
||||
@@ -74,11 +73,10 @@ def cDalleSelenium(context:EventContext, data:InputMessageData) -> None:
|
||||
img_url = img_url.get_attribute("src").split('?')[0]
|
||||
img_array.append({"url": img_url}) #, "bytes": HttpReq(img_url).read()})
|
||||
page_url = driver.current_url.split('?')[0]
|
||||
SendMessage(context, {
|
||||
"TextPlain": f'"{prompt}"\n{{{page_url}}}',
|
||||
"TextMarkdown": (f'"_{CharEscape(prompt, "MARKDOWN")}_"\n' + MarkdownCode(page_url, True)),
|
||||
"media": img_array,
|
||||
})
|
||||
SendMessage(context, OutputMessageData(
|
||||
text_plain=f'"{prompt}"\n{{{page_url}}}',
|
||||
text_html=f'"<i>{html_escape(prompt)}</i>"\n<pre>{page_url}</pre>',
|
||||
media=img_array))
|
||||
return closeSelenium(driver_index, driver)
|
||||
raise Exception("VM timed out.")
|
||||
except Exception as error:
|
||||
@@ -87,8 +85,7 @@ def cDalleSelenium(context:EventContext, data:InputMessageData) -> None:
|
||||
closeSelenium(driver_index, driver)
|
||||
|
||||
def cCraiyonSelenium(context:EventContext, data:InputMessageData) -> None:
|
||||
prompt = data.command.body
|
||||
if not prompt:
|
||||
if not (prompt := data.command.body):
|
||||
return SendMessage(context, {"Text": "Please tell me what to generate."})
|
||||
driver_index, driver = None, None
|
||||
try:
|
||||
|
@@ -25,7 +25,7 @@ def luaAttributeFilter(obj, attr_name, is_setting):
|
||||
# TODO make print behave the same as normal Lua, and expose a function for printing without newlines
|
||||
def cLua(context:EventContext, data:InputMessageData) -> None:
|
||||
# TODO update quoted api getting
|
||||
scriptText = (data.command.body or (data.Quoted and data.Quoted.Body))
|
||||
scriptText = (data.command.body or (data.quoted and data.quoted.text_plain))
|
||||
if not scriptText:
|
||||
return SendMessage(context, {"Text": "You must provide some Lua code to execute."})
|
||||
luaRuntime = NewLuaRuntime(max_memory=LuaMemoryLimit, register_eval=False, register_builtins=False, attribute_filter=luaAttributeFilter)
|
||||
|
14
ModWinDog/Start/Start.py
Normal file
14
ModWinDog/Start/Start.py
Normal file
@@ -0,0 +1,14 @@
|
||||
# ==================================== #
|
||||
# WinDog multi-purpose chatbot #
|
||||
# Licensed under AGPLv3 by OctoSpacc #
|
||||
# ==================================== #
|
||||
|
||||
def cStart(context:EventContext, data:InputMessageData) -> None:
|
||||
SendMessage(context, OutputMessageData(
|
||||
text_html=context.endpoint.get_string(
|
||||
"start", data.user.settings.language).format(data.user.name)))
|
||||
|
||||
RegisterModule(name="Start", endpoints=[
|
||||
SafeNamespace(names=["start"], handler=cStart),
|
||||
])
|
||||
|
16
ModWinDog/Start/Start.yaml
Normal file
16
ModWinDog/Start/Start.yaml
Normal file
@@ -0,0 +1,16 @@
|
||||
summary:
|
||||
en: Things related to starting the bot, on supported platforms.
|
||||
endpoints:
|
||||
start:
|
||||
summary:
|
||||
en: Salutes the user, hinting that the bot is working and providing basic quick help.
|
||||
start:
|
||||
en: |
|
||||
<b>Hi</b> {0}<b>!</b>
|
||||
|
||||
Use /help to read a list of available commands.
|
||||
it: |
|
||||
<b>Ciao</b> {0}<b>!</b>
|
||||
|
||||
Usa /help per leggere la lista dei comandi.
|
||||
|
24
ModWinDog/System/System.py
Normal file
24
ModWinDog/System/System.py
Normal file
@@ -0,0 +1,24 @@
|
||||
# ==================================== #
|
||||
# WinDog multi-purpose chatbot #
|
||||
# Licensed under AGPLv3 by OctoSpacc #
|
||||
# ==================================== #
|
||||
|
||||
import subprocess
|
||||
from re import compile as re_compile
|
||||
|
||||
def cExec(context:EventContext, data:InputMessageData) -> None:
|
||||
if not (len(data.command.tokens) >= 2 and data.command.tokens[1].lower() in ExecAllowed):
|
||||
return SendMessage(context, {"Text": choice(Locale.__('eval'))})
|
||||
command = data.command.tokens[1].lower()
|
||||
output = subprocess.run(
|
||||
("sh", "-c", f"export PATH=$PATH:/usr/games; {command}"),
|
||||
stdout=subprocess.PIPE, stderr=subprocess.STDOUT).stdout.decode()
|
||||
# <https://stackoverflow.com/a/14693789>
|
||||
text = (re_compile(r"\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])").sub('', output))
|
||||
SendMessage(context, OutputMessageData(
|
||||
text_plain=text, text_html=f"<pre>{html_escape(text)}</pre>"))
|
||||
|
||||
RegisterModule(name="System", endpoints=[
|
||||
SafeNamespace(names=["exec"], handler=cExec),
|
||||
])
|
||||
|
5
ModWinDog/System/System.yaml
Normal file
5
ModWinDog/System/System.yaml
Normal file
@@ -0,0 +1,5 @@
|
||||
endpoints:
|
||||
exec:
|
||||
summary:
|
||||
en: Execute a system command from the allowed ones and return stdout+stderr.
|
||||
|
Reference in New Issue
Block a user