diff --git a/anon.py b/anon.py index b9e0276..092cb46 100644 --- a/anon.py +++ b/anon.py @@ -1,156 +1,36 @@ import telebot import os import json +from icecream import ic -########### Работа с БД ########## +########### Функции ############## +from func import * +########### Работа с БД ########## from db import * raw_db = read_db() -######### Загрузка БД ############ - -# raw_db = { -# "Anon": {"id": 2045634, pkey: "fuD2d", channel: "AnotherUser", avatar: "♿️", blocks: [5375652, 436432], keys: {AnotherUser: "dDH73s"}}, -# "2045634": "Anon" -# } -# Первая строка - информация о пользователе (айди, канал, блокнутые пользователи) -# Вторая строчка - для отправки сообщения и блокировки -# keys - ключи , pkey - личный ключ - -def is_num(str): - try: - int(str) - return True - except: - return False - -# Класс пользователя -class user_: - def __init__(self, id, pkey, channel = None, avatar = "♿️", blocks = [], keys = {}): - self.id = id - self.channel = channel - self.avatar = avatar - self.blocks = blocks - self.pkey = pkey - self.keys = keys - -# Загружаем в формат -# db = { -# "Anon": user.*, -# "2045634": "Anon" -# } - - -# Загружаем -def load(): - raw_db = read_db() - db = {} - for i in raw_db: - if is_num(i) == True: - db[i] = raw_db[i] - elif "token" == i: - db["token"] = raw_db["token"] - else: - id, pkey, channel, avatar, blocks, keys = raw_db[i]["id"], raw_db[i]["pkey"], raw_db[i]["channel"], raw_db[i]["avatar"], raw_db[i]["blocks"], raw_db[i]["keys"], - user = user_(id, pkey, channel, avatar, blocks, keys) - db[i] = user - - return db - -db = load() - -# Сохраняем -def save(db): - raw_db = {} - for i in db: - if is_num(i) == True: - raw_db[i] = db[i] - elif "token" == i: - raw_db["token"] = db["token"] - else: - raw_db[i] = {"id": db[i].id, "pkey": db[i].pkey, "channel": db[i].channel, "avatar": db[i].avatar, "blocks": db[i].blocks, "keys": db[i].keys} - write_db(raw_db) +###### Класс пользователя ######## +from user import * +# user.id = 123 +# user.pkey = "fd35s" +# user.channel = "anotheruser" +# user.avatar = "♿️" +# user.blocks = [124235] +# user.keys = {"anotheruser": "re543"} ####### Работа с хэшем ########### - from hash import hash from random import randint ##### Инициализация токена ####### - bot = telebot.TeleBot(raw_db['token']) ########## Ловим ошибки ########## +from catch_err import * -import logging -import traceback -from io import StringIO # For catch log to variable - -# Basic init -global log_stream -log_stream = StringIO() -logging.basicConfig(stream=log_stream) - -def catch_error(message, err_type = None): - try: - if not err_type: - global log_stream - - logging.error(traceback.format_exc()) # Log error - err = log_stream.getvalue() # Error to variable - - bot.reply_to(message, "Critical error:\n\n" + telebot.formatting.hcode(err), parse_mode='HTML') - - log_stream.truncate(0) # Clear - log_stream.seek(0) # Clear - except: - pass - -#### Небольшие функции #### - -def is_auth(message): - try: - db = load() - if str(message.chat.id) in db: - return True - else: - bot.reply_to(message,"Извините, но Вы не авторизованы.\n\n/reg ник") - return False - except: - catch_error(message) - -# Регулярные выражения -from re import search, match, sub, compile - -def nick_ok(message, nick): - if len(nick) > 30: - bot.reply_to(message,"Слишком длинный ник, попробуйте короче.") - return False - if is_num(nick): - bot.reply_to(message,"Ник должен содержать хоть 1 букву, попробуйте ещё раз.") - return False - - en = True - ru = True - # Если только английский - regex = compile('[^a-zA-Z0-9]') - check = regex.sub('', nick) - if check != nick: - en = False - # Если только русский - regex = compile('[^а-яА-ЯЁё0-9]') - check = regex.sub('', nick) - if check != nick: - ru = False - - if en == False and ru == False: - bot.reply_to(message,"Нельзя смешивать алфавиты и ставить спец.-символы, попробуйте ещё раз") - return False - - return True - -############## MAIN +############## MAIN ############## @bot.message_handler(commands=['start', 'help']) def start(message): @@ -173,7 +53,7 @@ def reg(message): if len(message.text.split()) == 2: nick = message.text.split()[1] # Проверка ника - if not nick_ok(message, nick): + if not nick_ok(bot, message, nick): return 0 if nick in db: bot.reply_to(message, "Данный пользователь уже зарегистрирован.") @@ -189,12 +69,12 @@ def reg(message): else: bot.reply_to(message, "Вы ввели не 2 аргумента, нужно: /reg ЛюбойНикнейм") except: - catch_error(message) + catch_error(bot, message) @bot.message_handler(commands=['b']) def b(message): try: - if is_auth(message): + if is_auth(bot, message): db = load() nick = db[str(message.chat.id)] user = db[nick] @@ -212,12 +92,12 @@ def b(message): else: bot.reply_to(message, "Данного пользователя не существует.") except: - catch_error(message) + catch_error(bot, message) @bot.message_handler(commands=['u']) def u(message): try: - if is_auth(message): + if is_auth(bot, message): db = load() nick = db[str(message.chat.id)] user = db[nick] @@ -232,12 +112,12 @@ def u(message): save(db) bot.reply_to(message, f"Была снята блокировка с пользователя {telebot.formatting.hcode(block)}",parse_mode="HTML") except: - catch_error(message) + catch_error(bot, message) @bot.message_handler(commands=['nick']) def nick(message): try: - if is_auth(message): + if is_auth(bot, message): db = load() new_nick = message.text.split()[1] # Проверка ника @@ -257,12 +137,12 @@ def nick(message): else: bot.reply_to(message,"Данный ник уже занят") except: - catch_error(message) + catch_error(bot, message) @bot.message_handler(commands=['av']) def av(message): try: - if is_auth(message): + if is_auth(bot, message): db = load() if not len(message.text.split()) > 1: bot.reply_to(message,"Укажите аватарку") @@ -276,10 +156,9 @@ def av(message): save(db) bot.reply_to(message,"Новая аватарка успешно установлена") except: - catch_error(message) - + catch_error(bot, message) -############# WORK WITH KEY ######## +######### Работа с ключом ######## @bot.message_handler(commands=['key']) def key(message): @@ -294,7 +173,7 @@ def key(message): else: bot.reply_to(message,"/key ник") except: - catch_error(message) + catch_error(bot, message) @bot.message_handler(commands=['ver']) def ver(message): @@ -316,12 +195,12 @@ def ver(message): else: bot.reply_to(message,"/ver ник ключ") except: - catch_error(message) + catch_error(bot, message) @bot.message_handler(commands=['key_res']) def key_res(message): try: - if is_auth(message): + if is_auth(bot, message): db = load() key = hash(randint(74287, 5747962)) @@ -336,50 +215,15 @@ def key_res(message): Старый ключ: {telebot.formatting.hcode(old_key)} Новый ключ: {telebot.formatting.hcode(key)}""",parse_mode="HTML") except: - catch_error(message) - -# Проверяем совпадение ключей при отправке сообщений -def key_valid(message, channel): - try: - db = load() - our_nick = db[str(message.chat.id)] - user = db[our_nick] - # Добавляем ключ если его нету в нашей БД - if channel not in user.keys: - user.keys[channel] = db[channel].pkey - save(db) - - db = load() - our_key = user.keys[channel] - print(channel) - dest_key = db[channel].pkey - - if our_key == dest_key: - print("Valid: ", channel) - return True - else: - print("Not valid: ", channel) - use.keys[channel] = dest_key - save(db) - - bot.reply_to(message, f"""⚠️ Публичные ключи не совпадают ⚠️ -Ожидаемый ключ: {telebot.formatting.hcode(our_key)} - -Отправка сообщения отклонена. -Если вы уверены - повторите отправку. -""", parse_mode="HTML") - return False - except: - catch_error(message) - -#################################### + catch_error(bot, message) +################################## @bot.message_handler(commands=['me']) def me(message): try: - if is_auth(message): + if is_auth(bot, message): db = load() nick = db[str(message.chat.id)] user = db[nick] @@ -393,9 +237,10 @@ def me(message): Ваша аватарка: {telebot.formatting.hcode(user.avatar)} Ваш публичный ключ: {telebot.formatting.hcode(user.pkey)}""",parse_mode="HTML") except: - catch_error(message) + catch_error(bot, message) +###### Передача сообщений ######## @bot.message_handler(func=lambda message: True, content_types=['photo','text', 'document', 'voice', 'video']) def catch_all_messages(message): @@ -408,7 +253,7 @@ def catch_all_messages(message): channel = message.text[1:] if channel in db: # Проверяем ключи - if not key_valid(message, channel): + if not key_valid(bot, message, channel): return 0 user.channel = channel @@ -419,7 +264,7 @@ def catch_all_messages(message): elif user.channel != None: channel = user.channel # Проверяем ключи - if not key_valid(message, channel): + if not key_valid(bot, message, channel): return 0 db = load() @@ -457,20 +302,23 @@ def catch_all_messages(message): bot.send_message(db[channel].id, f"{telebot.formatting.hcode(':'+nick) + avatar}\n" + message.text, parse_mode="HTML") except: - catch_error(message) + catch_error(bot, message) bot.reply_to(message, "Сообщение не было доставлено.\nВероятно пользователь заблокировал бота.") else: bot.reply_to(message, "Увы, но вас заблокировал данный пользователь.") else: bot.reply_to(message, f"У вас не указан чат.\nЧтобы подключится к чату напишите: {telebot.formatting.hcode(':Никнейм')} ", parse_mode="HTML") except: - catch_error(message) + catch_error(bot, message) #### POLLING #### -mode = 1 -# Normal - 0, debug - 1 +from sys import argv +if len(argv) > 1: + mode = "debug" +else: + mode = "normal" -if mode == 0: +if mode == "normal": while True: try: bot.polling() @@ -478,5 +326,6 @@ if mode == 0: exit() except: pass -elif mode == 1: +elif mode == "debug": + ic("Started debug...") bot.polling() diff --git a/catch_err.py b/catch_err.py new file mode 100644 index 0000000..77d12bf --- /dev/null +++ b/catch_err.py @@ -0,0 +1,26 @@ +import logging +import traceback +from io import StringIO # Для перевода лога в переменную + +import telebot + +# Базовая инициализация +global log_stream +log_stream = StringIO() +logging.basicConfig(stream=log_stream) + +def catch_error(bot, message, err_type = None): + try: + if not err_type: + global log_stream + + logging.error(traceback.format_exc()) # Логирование ошибок + err = log_stream.getvalue() # Ошибка -> переменная + + bot.reply_to(message, "Critical error:\n\n" + telebot.formatting.hcode(err), parse_mode='HTML') + + # Очистка логов + log_stream.truncate(0) + log_stream.seek(0) + except: + pass diff --git a/db.py b/db.py index 05cc81c..77891a6 100644 --- a/db.py +++ b/db.py @@ -1,6 +1,7 @@ import os import json +# Создаём БД, если её нету if not os.path.exists('db.json'): db = {"token": "None"} js = json.dumps(db, indent=2) @@ -11,12 +12,57 @@ if not os.path.exists('db.json'): exit() +# raw_db = { +# "Anon": {"id": 2045634, pkey: "fuD2d", channel: "AnotherUser", avatar: "♿️", blocks: [5375652, 436432], keys: {AnotherUser: "dDH73s"}}, +# "2045634": "Anon" +# } def read_db(file = 'db.json'): with open(file, "r", encoding="utf-8") as openfile: - db = json.load(openfile) - return db + raw_db = json.load(openfile) + return raw_db -def write_db(db, file = 'db.json'): - js = json.dumps(db, indent=2, ensure_ascii=False) +def write_db(raw_db, file = 'db.json'): + js = json.dumps(raw_db, indent=2, ensure_ascii=False) with open(file, "w", encoding="utf-8") as outfile: outfile.write(js) + + + +from user import * +# db = { +# "Anon": user.*, +# "2045634": "Anon" +# } + +def is_num(str): + try: + int(str) + return True + except: + return False + +def load(): + raw_db = read_db() + db = {} + for i in raw_db: + if is_num(i) == True: + db[i] = raw_db[i] + elif "token" == i: + db["token"] = raw_db["token"] + else: + id, pkey, channel, avatar, blocks, keys = raw_db[i]["id"], raw_db[i]["pkey"], raw_db[i]["channel"], raw_db[i]["avatar"], raw_db[i]["blocks"], raw_db[i]["keys"], + user = user_(id, pkey, channel, avatar, blocks, keys) + db[i] = user + + return db + +def save(db): + raw_db = {} + for i in db: + if is_num(i) == True: + raw_db[i] = db[i] + elif "token" == i: + raw_db["token"] = db["token"] + else: + raw_db[i] = {"id": db[i].id, "pkey": db[i].pkey, "channel": db[i].channel, "avatar": db[i].avatar, "blocks": db[i].blocks, "keys": db[i].keys} + write_db(raw_db) diff --git a/func.py b/func.py new file mode 100644 index 0000000..b82c5b1 --- /dev/null +++ b/func.py @@ -0,0 +1,81 @@ +#### Ловим ошибки #### +from catch_err import * +######### БД ######### +from db import * +###################### + +# -> True/False +def is_auth(bot, message): + try: + db = load() + if str(message.chat.id) in db: + return True + else: + bot.reply_to(message,"Извините, но Вы не авторизованы.\n\n/reg ник") + return False + except: + catch_error(bot, message) + + +# Регулярные выражения +from re import sub, compile +# -> True/False +def nick_ok(bot, message, nick): + if len(nick) > 30: + bot.reply_to(message,"Слишком длинный ник, попробуйте короче.") + return False + if is_num(nick): + bot.reply_to(message,"Ник должен содержать хоть 1 букву, попробуйте ещё раз.") + return False + + en = True + ru = True + # Если только английский + regex = compile('[^a-zA-Z0-9]') + check = regex.sub('', nick) + if check != nick: + en = False + # Если только русский + regex = compile('[^а-яА-ЯЁё0-9]') + check = regex.sub('', nick) + if check != nick: + ru = False + + if en == False and ru == False: + bot.reply_to(message,"Нельзя смешивать алфавиты и ставить спец.-символы, попробуйте ещё раз") + return False + + return True + + +# Проверяем совпадение ключей при отправке сообщений +# -> True/False +def key_valid(bot, message, channel): + try: + db = load() + our_nick = db[str(message.chat.id)] + user = db[our_nick] + # Добавляем ключ если его нету в нашей БД + if channel not in user.keys: + user.keys[channel] = db[channel].pkey + save(db) + return True + + our_key = user.keys[channel] + dest_key = db[channel].pkey + + if our_key == dest_key: + return True + else: + use.keys[channel] = dest_key + save(db) + + bot.reply_to(message, f"""⚠️ Публичные ключи не совпадают ⚠️ +Ожидаемый ключ: {telebot.formatting.hcode(our_key)} + +Отправка сообщения отклонена. +Если вы уверены - повторите отправку. +""", parse_mode="HTML") + return False + except: + catch_error(bot, message) diff --git a/user.py b/user.py new file mode 100644 index 0000000..e42fa78 --- /dev/null +++ b/user.py @@ -0,0 +1,8 @@ +class user_: + def __init__(self, id, pkey, channel = None, avatar = "♿️", blocks = [], keys = {}): + self.id = id + self.channel = channel + self.avatar = avatar + self.blocks = blocks + self.pkey = pkey + self.keys = keys