diff --git a/Locale/en.json b/Locale/en.json index bd870f0..126b399 100644 --- a/Locale/en.json +++ b/Locale/en.json @@ -30,7 +30,7 @@ }, "level": { "empty": [ - "Check what's your level of something.\n\n*Usage*: {Cmd} ." + "Check what's your level of something.\n\n*Usage*: {Cmd} <Thing>." ], "done": [ "_Your level of *{Thing}* is... *{Percent}%*._" diff --git a/Locale/it.json b/Locale/it.json index b103947..4bf0660 100644 --- a/Locale/it.json +++ b/Locale/it.json @@ -20,7 +20,7 @@ }, "level": { "empty": [ - "Controlla il tuo livello di qualcosa.\n\n*Uso*: {Cmd} ." + "Controlla il tuo livello di qualcosa.\n\n*Uso*: {Cmd} <Cosa>." ], "done": [ "_Il tuo livello di *{Thing}* รจ... *{Percent}%*._" diff --git a/ModWinDog/Mods.py b/ModWinDog/Mods.py index 5e011ab..8d77783 100644 --- a/ModWinDog/Mods.py +++ b/ModWinDog/Mods.py @@ -3,16 +3,12 @@ # Licensed under AGPLv3 by OctoSpacc # # ================================== # -def percenter(update:Update, context:CallbackContext) -> None: - Cmd = HandleCmd(update) - if not Cmd: return - if len(Cmd.Tokens) >= 2: - Text = choice(Locale.__(f'{Cmd.Name}.done')) +def percenter(Context, Data=None) -> None: + if Data.Body: + Text = choice(Locale.__(f'{Data.Name}.done')) else: - Text = choice(Locale.__(f'{Cmd.Name}.empty')) - update.message.reply_markdown_v2( - CharEscape(Text, '.!<>').format(Cmd=Cmd.Tokens[0], Percent=RandPercent(), Thing=Cmd.Body), - reply_to_message_id=update.message.message_id) + Text = choice(Locale.__(f'{Data.Name}.empty')) + SendMsg(Context, {"Text": Text.format(Cmd=Data.Tokens[0], Percent=RandPercent(), Thing=Data.Body)}) def multifun(update:Update, context:CallbackContext) -> None: Cmd = HandleCmd(update) @@ -38,7 +34,7 @@ def multifun(update:Update, context:CallbackContext) -> None: update.message.reply_markdown_v2(Text, reply_to_message_id=ReplyToMsg) def cStart(Context, Data=None) -> None: - SendMsg(Context, {"Text": "Hi stupid :3"}) + SendMsg(Context, {"Text": choice(Locale.__('start')).format('stupid')}) #def cStart(update:Update, context:CallbackContext) -> None: # Cmd = HandleCmd(update) @@ -67,34 +63,15 @@ def cConfig(update:Update, context:CallbackContext) -> None: # ... language: en, it, ... # ... userdata: import, export, delete +def cPing(Context, Data=None) -> None: + SendMsg(Context, {"Text": "*Pong!*"}) + def cEcho(Context, Data=None) -> None: if Data.Body: SendMsg(Context, {"Text": Data.Body}) else: SendMsg(Context, {"Text": choice(Locale.__('echo.empty'))}) -def cEcho2(update:Update, context:CallbackContext) -> None: - Cmd = HandleCmd(update) - if not Cmd: return - Msg = update.message.text - if len(Msg.split(' ')) >= 2: - Text = Msg[len(Msg.split(' ')[0])+1:] - update.message.reply_text( - Text, - reply_to_message_id=update.message.message_id) - else: - Text = CharEscape(choice(Locale.__('echo.empty')), '.!') - update.message.reply_markdown_v2( - Text, - reply_to_message_id=update.message.message_id) - -def cPing(update:Update, context:CallbackContext) -> None: - Cmd = HandleCmd(update) - if not Cmd: return - update.message.reply_markdown_v2( - '*Pong\!*', - reply_to_message_id=update.message.message_id) - #def cTime(update:Update, context:CallbackContext) -> None: # update.message.reply_markdown_v2( # CharEscape(choice(Locale.__('time')).format(time.ctime().replace(' ', ' ')), 'MARKDOWN_SPEECH'), diff --git a/WinDog.py b/WinDog.py index 7ed269d..3c1cc8e 100755 --- a/WinDog.py +++ b/WinDog.py @@ -12,12 +12,17 @@ from types import SimpleNamespace #from traceback import format_exc as TraceText import mastodon, telegram from bs4 import BeautifulSoup +from html import unescape as HtmlUnescape +from markdown import markdown from telegram import Update, ForceReply, Bot from telegram.utils.helpers import escape_markdown from telegram.ext import Updater, CommandHandler, MessageHandler, Filters, CallbackContext from urllib import parse as UrlParse from urllib.request import urlopen, Request +# +MdEscapes = '\\`*_{}[]()<>#+-.!' + Db = {"Chats": {}} Locale = {"Fallback": {}} @@ -30,7 +35,26 @@ for Dir in ('Lib', 'Mod'): Endpoints = { "start": cStart, + #"help": cHelp, + #"config": cConfig, + #"source": cSource, + "ping": cPing, "echo": cEcho, + "wish": percenter, + "level": percenter, + #"hug": multifun, + #"pat": multifun, + #"poke": multifun, + #"cuddle": multifun, + #"floor": multifun, + #"hands": multifun, + #"sessocto": multifun, + #"hash": cHash, + #"eval": cEval, + #"exec": cExec, + #"web": cWeb, + #"unsplash": cUnsplash, + #"safebooru": cSafebooru, } def SetupLocale() -> None: @@ -86,9 +110,19 @@ def CharEscape(String:str, Escape:str='') -> str: String = String.replace(c, '\\'+c) return String -def MarkdownCode(Text:str, Block:bool): +def InferMdEscape(Raw:str, Plain:str) -> str: + Chs = '' + for Ch in MdEscapes: + if Ch in Raw and Ch in Plain: + Chs += Ch + return Chs + +def MarkdownCode(Text:str, Block:bool) -> str: return '```\n' + CharEscape(Text.strip(), 'MARKDOWN') + '\n```' +def MdToTxt(Md:str) -> str: + return BeautifulSoup(markdown(Md), 'html.parser').get_text(' ') + def CmdAllowed(update) -> bool: if not TGRestrict: return True @@ -114,9 +148,14 @@ def ParseCmd(Msg) -> dict: "Name": Name, "Body": Name.join(Msg.split(Name)[1:]).strip(), "Tokens": GetRawTokens(Msg), + "User": {"Name": "", "Tag": "", "Id": ""}, + "Tagged": {}, }) def filters(update:Update, context:CallbackContext=None) -> None: + Cmd = ParseCmd(update.message.text) + if Cmd.Tokens[0][0] in CmdPrefixes and Cmd.Name in Endpoints: + Endpoints[Cmd.Name](update, Cmd) if Debug and Dumper: Text = update.message.text Text = (Text.replace('\n', '\\n') if Text else '') @@ -146,9 +185,9 @@ def setfilter(update:Update, context:CallbackContext) -> None: def RandPercent() -> int: Num = randint(0,100) if Num == 100: - Num = str(Num) + '\.00' + Num = f'{Num}.00' else: - Num = str(Num) + '\.' + str(randint(0,9)) + str(randint(0,9)) + Num = f'{Num}.{randint(0,9)}{randint(0,9)}' return Num def RandHexStr(Len:int) -> str: @@ -177,15 +216,18 @@ def SendMsg(Context, Data): Manager = Context['Manager'] if 'Manager' in Context else None else: [Event, Manager] = [Context, Context] + TextPlain = MdToTxt(Data['Text']) if isinstance(Manager, mastodon.Mastodon): Manager.status_post( - (Data['Text'] + '\n\n@' + Event['account']['acct']), + (TextPlain + '\n\n@' + Event['account']['acct']), in_reply_to_id=Event['status']['id'], visibility=('direct' if Event['status']['visibility'] == 'direct' else 'unlisted') ) elif isinstance(Manager, telegram.Update): Event.message.reply_markdown_v2( - Data['Text'], + CharEscape(HtmlUnescape(Data['Text']), InferMdEscape(HtmlUnescape(Data['Text']), TextPlain)), + #Event.message.reply_text( + #TextPlain, reply_to_message_id=Event.message.message_id ) @@ -198,12 +240,10 @@ def Main() -> None: updater = Updater(TGToken) dispatcher = updater.dispatcher - dispatcher.add_handler(CommandHandler('start', cStart)) + #dispatcher.add_handler(CommandHandler('start', cStart)) dispatcher.add_handler(CommandHandler('config', cConfig)) dispatcher.add_handler(CommandHandler('help', cHelp)) dispatcher.add_handler(CommandHandler('source', cSource)) - dispatcher.add_handler(CommandHandler('echo', cEcho2)) - dispatcher.add_handler(CommandHandler('ping', cPing)) #dispatcher.add_handler(CommandHandler('time', cTime)) dispatcher.add_handler(CommandHandler('hash', cHash)) dispatcher.add_handler(CommandHandler('eval', cEval)) @@ -212,31 +252,28 @@ def Main() -> None: dispatcher.add_handler(CommandHandler('unsplash', cUnsplash)) dispatcher.add_handler(CommandHandler('safebooru', cSafebooru)) - for Cmd in ('wish', 'level'): - dispatcher.add_handler(CommandHandler(Cmd, percenter)) for Cmd in ('hug', 'pat', 'poke', 'cuddle', 'floor', 'hands', 'sessocto'): dispatcher.add_handler(CommandHandler(Cmd, multifun)) #dispatcher.add_handler(CommandHandler('setfilter', setfilter)) - dispatcher.add_handler(MessageHandler(Filters.text & ~Filters.command, filters)) + dispatcher.add_handler(MessageHandler(Filters.text | Filters.command, filters)) print('Starting WinDog...') updater.start_polling() - #if MastodonUrl and MastodonToken: - Mastodon = mastodon.Mastodon(api_base_url=MastodonUrl, access_token=MastodonToken) - class mmyListener(mastodon.StreamListener): - def on_notification(self, Event): - if Event['type'] == 'mention': - Msg = BeautifulSoup(Event['status']['content'], 'html.parser').get_text(' ').strip().replace('\t', ' ') - if not Msg.split('@')[0]: - Msg = ' '.join('@'.join(Msg.split('@')[1:]).strip().split(' ')[1:]).strip() - if Msg[0] in '.!/': - Cmd = ParseCmd(Msg) - if Cmd.Name in Endpoints: - Endpoints[Cmd.Name]({"Event": Event, "Manager": Mastodon}, Cmd) - - Mastodon.stream_user(mmyListener()) + if MastodonUrl and MastodonToken: + Mastodon = mastodon.Mastodon(api_base_url=MastodonUrl, access_token=MastodonToken) + class MastodonListener(mastodon.StreamListener): + def on_notification(self, Event): + if Event['type'] == 'mention': + Msg = BeautifulSoup(Event['status']['content'], 'html.parser').get_text(' ').strip().replace('\t', ' ') + if not Msg.split('@')[0]: + Msg = ' '.join('@'.join(Msg.split('@')[1:]).strip().split(' ')[1:]).strip() + if Msg[0] in CmdPrefixes: + Cmd = ParseCmd(Msg) + if Cmd.Name in Endpoints: + Endpoints[Cmd.Name]({"Event": Event, "Manager": Mastodon}, Cmd) + Mastodon.stream_user(MastodonListener()) while True: time.sleep(9**9) diff --git a/requirements.txt b/requirements.txt index 4f2b8c4..6e53a85 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,9 +1,13 @@ -# Some bot modules +# Program core +# ... + +# Required by some bot modules urllib3 # Mastodon support Mastodon.py beautifulsoup4 +Markdown # Telegram support python-telegram-bot