mirror of
https://gitlab.com/octospacc/WinDog.git
synced 2025-02-12 09:30:37 +01:00
210 lines
5.9 KiB
Python
Executable File
210 lines
5.9 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
# ================================== #
|
|
# WinDog multi-purpose chatbot #
|
|
# Licensed under AGPLv3 by OctoSpacc #
|
|
# ================================== #
|
|
|
|
import json, hashlib, re, time, subprocess
|
|
from os import listdir
|
|
from os.path import isfile
|
|
from random import choice, randint
|
|
from types import SimpleNamespace
|
|
#from traceback import format_exc as TraceText
|
|
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
|
|
|
|
Db = {"Chats": {}}
|
|
Locale = {"Fallback": {}}
|
|
|
|
for Dir in ('Lib', 'Mod'):
|
|
for File in listdir(f'./{Dir}WinDog'):
|
|
File = f'./{Dir}WinDog/{File}'
|
|
if isfile(File):
|
|
with open(File, 'r') as File:
|
|
exec(File.read())
|
|
|
|
def SetupLocale() -> 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:
|
|
print(f'Cannot load {Lang} locale, exiting.')
|
|
raise
|
|
exit(1)
|
|
for Key in Locale[DefaultLang]:
|
|
Locale['Fallback'][Key] = Locale[DefaultLang][Key]
|
|
for Lang in Locale:
|
|
for Key in Locale[Lang]:
|
|
if not Key in Locale['Fallback']:
|
|
Locale['Fallback'][Key] = Locale[Lang][Key]
|
|
def __(Key:str, Lang:str=DefaultLang):
|
|
Set = None
|
|
Key = Key.split('.')
|
|
try:
|
|
Set = Locale.Locale[Lang]
|
|
for El in Key:
|
|
Set = Set[El]
|
|
except Exception:
|
|
Set = Locale.Locale['Fallback']
|
|
for El in Key:
|
|
Set = Set[El]
|
|
return Set
|
|
Locale['__'] = __
|
|
Locale['Locale'] = Locale
|
|
Locale = SimpleNamespace(**Locale)
|
|
|
|
def SetupDb() -> None:
|
|
global Db
|
|
try:
|
|
with open('Database.json', 'r') as File:
|
|
Db = json.load(File)
|
|
except Exception:
|
|
pass
|
|
|
|
def CharEscape(String:str, Escape:str='') -> str:
|
|
if Escape == 'MARKDOWN':
|
|
return escape_markdown(String, version=2)
|
|
else:
|
|
if Escape == 'MARKDOWN_SPEECH':
|
|
Escape = '+-_.!()[]{}<>'
|
|
elif Escape == 'MARKDOWN_SPEECH_FORMAT':
|
|
Escape = '+-_.!()[]<>'
|
|
for c in Escape:
|
|
String = String.replace(c, '\\'+c)
|
|
return String
|
|
|
|
def MarkdownCode(Text:str, Block:bool):
|
|
return '```\n' + CharEscape(Text.strip(), 'MARKDOWN') + '\n```'
|
|
|
|
def CmdAllowed(update) -> bool:
|
|
if not TGRestrict:
|
|
return True
|
|
else:
|
|
if TGRestrict.lower() == 'whitelist':
|
|
if update.message.chat.id in TGWhitelist:
|
|
return True
|
|
return False
|
|
|
|
def HandleCmd(update):
|
|
filters(update)
|
|
if CmdAllowed(update):
|
|
return ParseCmd(update.message.text)
|
|
else:
|
|
return False
|
|
|
|
def GetRawTokens(Text:str) -> list:
|
|
return Text.strip().replace('\t', ' ').replace(' ', ' ').replace(' ', ' ').split(' ')
|
|
|
|
def ParseCmd(Msg) -> dict:
|
|
Name = Msg.lower().split(' ')[0][1:].split('@')[0]
|
|
return SimpleNamespace(**{
|
|
"Name": Name,
|
|
"Body": Name.join(Msg.split(Name)[1:]).strip(),
|
|
"Tokens": GetRawTokens(Msg),
|
|
})
|
|
|
|
def filters(update:Update, context:CallbackContext=None) -> None:
|
|
if Debug and Dumper:
|
|
Text = update.message.text.replace('\n', '\\n')
|
|
with open('Dump.txt', 'a') as File:
|
|
File.write(f'[{time.ctime()}] [{int(time.time())}] [{update.message.chat.id}] [{update.message.message_id}] [{update.message.from_user.id}] {Text}\n')
|
|
'''
|
|
if CmdAllowed(update):
|
|
ChatID = update.message.chat.id
|
|
if ChatID in Private['Chats'] and 'Filters' in Private['Chats'][ChatID]:
|
|
for f in Private['Chats'][ChatID]['Filters']:
|
|
if f in update.message.text:
|
|
update.message.reply_text(
|
|
Private['Chats'][ChatID]['Filters'][f],
|
|
reply_to_message_id=update.message.message_id)
|
|
'''
|
|
|
|
def setfilter(update:Update, context:CallbackContext) -> None:
|
|
pass
|
|
'''
|
|
if CmdAllowed(update):
|
|
ChatID = update.message.chat.id
|
|
if ChatID not in Private['Chats'] or 'Filters' not in Private['Chats'][ChatID]:
|
|
Private['Chats'][ChatID] = {'Filters':{}}
|
|
Private['Chats'][ChatID]['Filters'][update.message.text] = {'Text':0}
|
|
'''
|
|
|
|
def RandPercent() -> int:
|
|
Num = randint(0,100)
|
|
if Num == 100:
|
|
Num = str(Num) + '\.00'
|
|
else:
|
|
Num = str(Num) + '\.' + str(randint(0,9)) + str(randint(0,9))
|
|
return Num
|
|
|
|
def RandHexStr(Len:int) -> str:
|
|
Hex = ''
|
|
for Char in range(Len):
|
|
Hex += choice('0123456789abcdef')
|
|
return Hex
|
|
|
|
#def CmdArgs(Msg:str, Cfg:tuple=None):
|
|
# Args = []
|
|
# Msg = Msg.strip().replace('\t', ' ')
|
|
# if Cfg:
|
|
# for i in Cfg:
|
|
# Args += [Msg.replace(' ', ' ').replace(' ', ' ').split(' ')[:i]]
|
|
# Msg = Msg
|
|
# else:
|
|
# return Msg.replace(' ', ' ').replace(' ', ' ').split(' ')
|
|
|
|
def HttpGet(Url:str):
|
|
return urlopen(Request(Url, headers={"User-Agent": WebUserAgent}))
|
|
|
|
#def SendMsg(Data, context):
|
|
# pass
|
|
|
|
def Main() -> None:
|
|
SetupDb()
|
|
SetupLocale()
|
|
|
|
#Private['Chats'].update({update.message.chat.id:{}})
|
|
|
|
updater = Updater(TGToken)
|
|
dispatcher = updater.dispatcher
|
|
|
|
dispatcher.add_handler(CommandHandler('start', cStart))
|
|
dispatcher.add_handler(CommandHandler('config', cConfig))
|
|
dispatcher.add_handler(CommandHandler('help', cHelp))
|
|
dispatcher.add_handler(CommandHandler('echo', cEcho))
|
|
dispatcher.add_handler(CommandHandler('ping', cPing))
|
|
#dispatcher.add_handler(CommandHandler('time', cTime))
|
|
dispatcher.add_handler(CommandHandler('hash', cHash))
|
|
dispatcher.add_handler(CommandHandler('eval', cEval))
|
|
dispatcher.add_handler(CommandHandler('exec', cExec))
|
|
dispatcher.add_handler(CommandHandler('web', cWeb))
|
|
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))
|
|
|
|
print('Starting WinDog...')
|
|
updater.start_polling()
|
|
updater.idle()
|
|
|
|
if __name__ == '__main__':
|
|
try:
|
|
from Config import *
|
|
except Exception:
|
|
pass
|
|
|
|
Main()
|
|
print('Closing WinDog...')
|