From a425d3ba0e0da105b64a04d4bb6781cb48c0b16b Mon Sep 17 00:00:00 2001 From: Egor Deev <67710823+IGlek@users.noreply.github.com> Date: Tue, 22 Nov 2022 14:22:09 +0300 Subject: [PATCH] v. 2.1 --- code/base.py | 26 +++ code/bot.py | 422 +++++++++++++++++++++++++++++++++++++++++++++++++ code/script.py | 172 ++++++++++++++++++++ code/sql.py | 389 +++++++++++++++++++++++++++++++++++++++++++++ db/base.db | Bin 0 -> 28672 bytes db/groups.db | 0 db/month.db | 0 db/users.db | Bin 0 -> 81920 bytes 8 files changed, 1009 insertions(+) create mode 100644 code/base.py create mode 100644 code/bot.py create mode 100644 code/script.py create mode 100644 code/sql.py create mode 100644 db/base.db create mode 100644 db/groups.db create mode 100644 db/month.db create mode 100644 db/users.db diff --git a/code/base.py b/code/base.py new file mode 100644 index 0000000..2ade2d6 --- /dev/null +++ b/code/base.py @@ -0,0 +1,26 @@ +# ДАННЫЕ БОТА +TOKEN = "" # @chat_abobot +DEBAG = "-*********" # Технический чат + +TEX_GROUP = "-*********" + +# ОБРАЩЕНИЯ К ПОЛЬЗОВАТЕЛЯМ +KILL_LIST = ["побить", "отмудохать", "избить", "уебать", "отметелить"] +TMOK_LIST = ["поцеловать", "чмокнуть", "соснуть", "лайкнуть"] +QUAT_LIST = [['дай', 'дайте'], ['ахуенный', 'ахуеный', 'охуеный', 'охуенный', 'блять', 'сука'], ['совет', 'совета']] + +# ФРАЗЫ ИВЕНТ ДРАКИ +VAR_WIN = ["опустив его ниже плинтуса!", "поставив его на место!"] +VAR_LOSE = ["Кунг - Фу!", "магии!", "резинового члена!", "банды цапель!"] + +# ПЕРЕВОДЧИК СЛОВ +ERR = ['q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', + "'", 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', '`'] +ERR_ = ['Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', + '"', 'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<', '>', '?', '~'] +TRU = ['й', 'ц', 'у', 'к', 'е', 'н', 'г', 'ш', 'щ', 'з', 'х', 'ъ', 'ф', 'ы', 'в', 'а', 'п', 'р', 'о', 'л', 'д', 'ж', + 'э', 'я', 'ч', 'с', 'м', 'и', 'т', 'ь', 'б', 'ю', '.'] +TRU_ = ['Й', 'Ц', 'У', 'К', 'Е', 'Н', 'Г', 'Ш', 'Щ', 'З', 'Х', 'Ъ', 'Ф', 'Ы', 'В', 'А', 'П', 'Р', 'О', 'Л', 'Д', 'Ж', + 'Э', 'Я', 'Ч', 'С', 'М', 'И', 'Т', 'Ь', 'Б', 'Ю', ','] + +ALB = ['а', 'у', 'о', 'ы', 'и', 'э', 'я', 'ю', 'ё', 'е', 'А', 'У', 'О', 'Ы', 'И', 'Э', 'Я', 'Ю', 'Ё', 'Е'] diff --git a/code/bot.py b/code/bot.py new file mode 100644 index 0000000..5125fc3 --- /dev/null +++ b/code/bot.py @@ -0,0 +1,422 @@ +import logging, random, pymorphy2, requests +import asyncio, base, re, os, enchant, sql + +from gtts import gTTS +from script import checker, translator, notice, lang_form, revers, upd_stat +from aiogram import Bot, Dispatcher, executor, types +from datetime import datetime as dt +# from filters import Admin + +# log level +logging.basicConfig(level=logging.INFO) + +# bot init +bot = Bot(token=base.TOKEN) +dp = Dispatcher(bot) +morph = pymorphy2.MorphAnalyzer() +engl_dict = enchant.Dict("en_US") + +# инициализируем соединение с БД +db = sql.Base('../db/base.db') +du = sql.User('../db/users.db') +dg = sql.Group('../db/groups.db') +dm = sql.Month('../db/month.db') + +# инициализируем фильтры +# dp.filters_factory.bind(Admin) + + +@dp.message_handler(content_types=["new_chat_members"]) +async def notification(message: types.Message): + if not du.group_exists(message.chat.id): + du.add_group(message.chat.id) + + group_id = du.get_group_id(message.chat.id) + db.add_group(group_id) + dg.created_group(group_id) + + await bot.send_message(message.chat.id, f'Привет группа {message.chat.title}!\n\nВсе функции вы можете ' + f'узнать по команде /help! Для того, чтобы ' + f'уведомления по имени и команда /all нормально функционировали, ' + f'необходимо чтобы каждый участник группы написал хотя бы одно ' + f'сообщение в чат! Также для того, чтобы системные сообщения удалялись ' + f'автоматически, необходимо боту выдать права администратора!', + types.ParseMode.HTML) + else: + try: + await message.delete() + except Exception: + return + + +# ОБНОВЛЕНИЕ АЙДИ ГРУППЫ +@dp.message_handler(content_types=['migrate_to_chat_id', 'migrate_from_chat_id']) +async def chat_reload(message: types.Message): + if du.group_exists(message.migrate_from_chat_id): + du.update_group_id(du.get_group_id(message.migrate_from_chat_id), message.migrate_to_chat_id) + + +# КОМАНДЫ +@dp.message_handler(commands=['start', 'help']) +async def helps(message: types.Message): + if message.chat.id > 0: + user_id = message.from_user.id + if not du.user_exists(user_id): + du.add_user(user_id) + else: + group_id, user_id = message.chat.id, message.from_user.id + if not du.user_exists(user_id): + du.add_user(user_id) + if not du.group_exists(group_id): + du.add_group(group_id) + upd_stat(user_id, group_id, 3, message.from_user.first_name, True) + + buttons = [types.InlineKeyboardButton(text="КОМАНДЫ", callback_data="com"), + types.InlineKeyboardButton(text="ИВЕНТЫ", callback_data="even"), + types.InlineKeyboardButton(text="АВТОР", callback_data="auth"), + types.InlineKeyboardButton(text="ФУНКЦИИ", callback_data="fun")] + + keyboard = types.InlineKeyboardMarkup(row_width=2) + keyboard.add(*buttons) + + try: + await bot.send_voice(chat_id=message.chat.id, voice=open('../data/tts.ogg', 'rb'), + caption='*-* Этот АБОБОТ поможет вам приятно провести время в чате с различными командами, ' + 'ивентами и удобными функциями, которые облегчают использование чата)\n\n' + '*-* Также прошу если вам понравился бот, оставить отзыв о его использовании на ' + 'команду /report)', parse_mode=types.ParseMode.MARKDOWN, reply_markup=keyboard) + except Exception: + await bot.send_message(chat_id=message.chat.id, + text='*-* Этот АБОБОТ поможет вам приятно провести время в чате с различными командами, ' + 'ивентами и удобными функциями, которые облегчают использование чата)\n\n' + '*-* Также прошу если вам понравился бот, оставить отзыв о его использовании на ' + 'команду /report)', parse_mode=types.ParseMode.MARKDOWN, reply_markup=keyboard) + + +# ИЛАЙН КЛАВИАТУРА HELP +@dp.callback_query_handler(text="auth") +async def author(call: types.CallbackQuery): + await call.message.answer(text='*| АВТОР |*\n\n*>>* Этот бот, как бы это не печально звучало, но одна из лучших' + ' моих работ и если кого-нибудь у меня получится действительно достойный продукт,' + ' вы сможете о нём узнать в моём телеграм канале *@itsproger*', parse_mode=types.ParseMode.MARKDOWN) + + +@dp.callback_query_handler(text="fun") +async def function(call: types.CallbackQuery): + await call.message.answer(text='*| ФУНКЦИИ |*\n\n*1.* Возможность перевода случайно написанного текста на ' + 'транслите\n*2.* Ведение обширной статистики сообщений\n*3.* Упоминание участника ' + 'при написании его имени в чате\n*4.* Автоматическое удаление системных сообщений', + parse_mode=types.ParseMode.MARKDOWN) + + +@dp.callback_query_handler(text="com") +async def commands(call: types.CallbackQuery): + await call.message.answer(text='| КОМАНДЫ |\n\n/all - упомянуть всех в чате\n/help - полный список функций\n' + '/stat_group - полная статистика группы\n/stat_user - полная статистика ' + 'отправителя\n/edit и /back_edit - первая команда даёт возможность ' + 'сменить имя для упоминаний на любое слово, а вторая для возврата динамического ' + 'имени\n/start_bot и /stop_bot - возможность отключения текстовых ивентов', + parse_mode=types.ParseMode.HTML) + + +@dp.callback_query_handler(text="even") +async def events(call: types.CallbackQuery): + await call.message.answer(text='*| ИВЕНТЫ |*\n\n*"Чмокнуть"* - сделать кому-нибудь приятно\n*"Отмудохать"* - ' + 'выместить злость на кого-нибудь\n*"Число от ... до ..."* - случайное значение из ' + 'диапозона\n*"Подраться с ..."* - повод кого-нибудь побить\n*"Переведи (..) - ..."* ' + '- перевод слова на керпичный язык\n*"Дай блять совет!"* - даёт рандомный охуенный ' + 'совет\n*"Переверни - ..."* - переворачивает слова в предложении\n*"Озвучь - ..."* ' + '- озвучивает написанный текст', + parse_mode=types.ParseMode.MARKDOWN) + + +# ОСТАЛЬНЫЕ КОМАНДЫ +@dp.message_handler(commands=['all'], commands_prefix='@/') +async def every(message: types.Message): + if message.chat.id < 0: + upd_stat(message.from_user.id, message.chat.id, 3, message.from_user.first_name, True) + try: + await message.reply(notice(du.get_user_id(message.from_user.id), True, du.get_group_id(message.chat.id), message.from_user.id), + types.ParseMode.HTML) + except Exception as e: + # print(repr(e)) + await message.reply('В группе состоит менее 3х человек, из-за чего команда не работает!') + else: + await message.reply('Эта команда предназначена для вызова в чате!') + + +@dp.message_handler(commands=['stat_group']) +async def stat_group(message: types.Message): + if message.chat.id < 0: + upd_stat(message.from_user.id, message.chat.id, 3, message.from_user.first_name, True) + group_id = du.get_group_id(message.chat.id) + + group = db.stat_group(group_id) + month = db.month_stat_group(group_id) + + await message.answer(text=f'*| СТАТИСТИКА ГРУППЫ |*\n\n' + f'*>>* В целом сообщений *[ {message.message_id} ]*\n\n' + f'*- За всё время* / *За месяц -*\n' + f'*>>* Сообщений в базе *[ {group[0]} / {month[0]} ]*\n\n' + f'*>* Ответов *- [ {group[1]} / {month[1]} ]*\n' + f'*>* Команд *- [ {group[2]} / {month[2]} ]*\n' + f'*>* Ссылок *- [ {group[3]} / {month[3]} ]*\n' + f'*>* Стикеров *- [ {group[5]} / {month[5]} ]*\n' + f'*>* Медиа файлов *- [ {group[4]} / {month[4] } ]*\n' + f'*>* Голос/Кружочки *- [ {group[6]} / {month[6]} ]*', + parse_mode=types.ParseMode.MARKDOWN) + + +@dp.message_handler(commands=['stat_user']) +async def stat_user(message: types.Message): + if message.chat.id < 0: + upd_stat(message.from_user.id, message.chat.id, 3, message.from_user.first_name, True) + user_id, group_id = du.get_user_id(message.from_user.id), du.get_group_id(message.chat.id) + + group = dg.stat_user(user_id, group_id) + month = dm.stat_user(user_id, group_id) + + namer = "".join(re.sub(r'[^\w\s]', '', message.from_user.first_name).split()) + name = morph.parse(namer)[0].inflect({"gent"}) + + if name is None: name = namer + else: name = name.word + + await message.answer(text=f'*| СТАТИСТИКА {name.upper()} |*\n\n' + f'*- За всё время* / *За месяц -*\n' + f'*>>* Сообщений в базе *[ {group[0]} / {month[0]} ]*\n\n' + f'*>* Ответов *- [ {group[1]} / {month[1]} ]*\n' + f'*>* Команд *- [ {group[2]} / {month[2]} ]*\n' + f'*>* Ссылок *- [ {group[3]} / {month[3]} ]*\n' + f'*>* Стикеров *- [ {group[5]} / {month[5]} ]*\n' + f'*>* Медиа файлов *- [ {group[4]} / {month[4]} ]*\n' + f'*>* Голос/Кружочки *- [ {group[6]} / {month[6]} ]*', + parse_mode=types.ParseMode.MARKDOWN) + + +@dp.message_handler(commands=['edit']) +async def update(message: types.Message): + if message.chat.id < 0: + upd_stat(message.from_user.id, message.chat.id, 3, message.from_user.first_name, True) + user_id, group_id = du.get_user_id(message.from_user.id), du.get_group_id(message.chat.id) + + text_edit = re.sub(r'[^\w\s]', '', message.text.lower()).split() + if len(text_edit) == 2: + name = morph.parse(text_edit[1])[0] + + if name is None: name = text_edit[1] + else: name = name.normal_form + + if name not in list(map(lambda x: x[0], dg.all_names(group_id))): + if not db.edit_user_exists(user_id): + db.add_edit_user(user_id) + + dg.update_name(user_id, group_id, name) + await message.reply(f'{name.title()}, ваше имя было успешно изменено)') + else: + await message.reply(f'{message.from_user.first_name.lower().title()}, такое имя уже присутствует в чате!') + else: + await message.reply('Вы не правильно ввели имя! Имя должно быть ' + 'из одного слова и идти сразу после команды!') + + +@dp.message_handler(commands=['back_edit']) +async def update_return(message: types.Message): + if message.chat.id < 0: + upd_stat(message.from_user.id, message.chat.id, 3, message.from_user.first_name, True) + user_id, group_id = du.get_user_id(message.from_user.id), du.get_group_id(message.chat.id) + name = re.sub(r'[^\w\s]', '', message.from_user.first_name.lower()) + + if db.edit_user_exists(user_id): + db.del_edit_user(user_id) + dg.update_name(user_id, group_id, name) + + await message.reply(f'{name.title()}, вы успешно вернулись к динамическому изменению имени)') + else: + await message.reply(f'{name.title()}, вы не устанавливали постоянное имя!') + + +@dp.message_handler(commands=['start_bot']) +async def opening(message: types.Message): + if message.chat.id < 0: + upd_stat(message.from_user.id, message.chat.id, 3, message.from_user.first_name, True) + + group_id = du.get_group_id(message.chat.id) + if db.check_status(group_id): + await message.answer("У вас уже включены текстовые ивенты!") + else: + db.update_status(group_id) + await message.answer("Текстовые ивенты включены!") + + +@dp.message_handler(commands=['stop_bot']) +async def closing(message: types.Message): + if message.chat.id < 0: + upd_stat(message.from_user.id, message.chat.id, 3, message.from_user.first_name, True) + + group_id = du.get_group_id(message.chat.id) + if db.check_status(group_id): + db.update_status(group_id) + await message.answer("Текстовые ивенты отключены!") + else: + await message.answer("У вас уже отключены текстовые ивенты!") + + +# УДАЛЕНИЕ ПОЛЬЗОВАТЕЛЕЙ АВТОМАТИЧЕСКИ +@dp.message_handler(content_types=["left_chat_member"]) +async def delete(message: types.Message): + if du.user_exists(message.left_chat_member.id): + user_id, group_id = du.get_user_id(message.left_chat_member.id), du.get_group_id(message.chat.id) + + dg.del_user(group_id, user_id) + if db.group_exists_month(group_id): + if dm.user_exists(user_id, group_id): dm.del_user(group_id, user_id) + + try: await message.delete() + except Exception: return + + +# УДАЛЕНИЕ ТЕХ. СООБЩЕНИЙ +@dp.message_handler(content_types=["new_chat_title", "new_chat_photo", "pinned_message", "voice_chat_ended", + "voice_chat_participants_invited"]) +async def chat_events(message: types.Message): + try: await message.delete() + except Exception: return + + +# СТАТИСТИКА +@dp.message_handler(content_types=['location', 'contact', 'video', 'photo', 'audio', 'document']) +async def media(message: types.Message): + if message.chat.id < 0: upd_stat(message.from_user.id, message.chat.id, 5, message.from_user.first_name, True) + + +@dp.message_handler(content_types=['voice', 'video_note']) +async def voice(message: types.Message): + if message.chat.id < 0: upd_stat(message.from_user.id, message.chat.id, 7, message.from_user.first_name, True) + + +@dp.message_handler(content_types=['sticker']) +async def stick(message: types.Message): + if message.chat.id < 0: upd_stat(message.from_user.id, message.chat.id, 6, message.from_user.first_name, True) + + +# ТЕКСТОВЫЕ ИВЕНТЫ +@dp.message_handler(content_types=['text']) +async def send_events(message: types.Message): + group_id, user_id, name = message.chat.id, message.from_user.id, message.from_user.first_name + + # ОБНОВЛЕНИЕ КОЛ-ВО + if message.chat.id < 0: + upd_stat(user_id, group_id, 1, name) # СООБЩЕНИЙ + if len(message.text) > 1 and message.text[0] == '/': upd_stat(user_id, group_id, 3, name) # КОМАНД + if 'reply_to_message' in message: upd_stat(user_id, group_id, 2, name) # ОТВЕТОВ НА СООБЩЕНИЯ + + # ПЕРЕМЕННЫЕ + low_mes = message.text.lower() # СООБЩЕНИЕ В НИЖНЕМ РЕГИСТРЕ + words = message.text.split() # СПИСОК СЛОВ В СООБЩЕНИИ + unsigned = re.sub(r'[^\w\s]', '', low_mes).split() # СПИСОК СЛОВ БЕЗ ПУНКТУАЦИИ + first_form = [morph.parse(i)[0].normal_form for i in unsigned] # СПИСОК СЛОВ В ПЕРВОЙ ФОРМЕ + if message.chat.id < 0: # СПИСОК ИМЕН В СООБЩЕНИИ (ТОЛЬКО В ГРУППЕ) + names = [_ for _ in first_form if _ in list(map(lambda x: x[0], dg.all_names(du.get_group_id(group_id))))] + + if len(words) >= 2: + # ПОЛЕЗНЫЕ ФУНКЦИИ + if len(words) == 5 and "число от" in low_mes: + await message.answer( + text=f"Число [ {random.randint(int(low_mes.split()[2]), int(low_mes.split()[4]))} ]", + parse_mode=types.ParseMode.HTML) + return + + if unsigned[0] == 'переведи': + if "переведи - " in low_mes: + await message.answer(lang_form([words[_] for _ in range(len(words)) if _ > 1])) + elif f"переведи ({unsigned[1]}) - " in low_mes: + if len(unsigned[1]) == 1: + await message.answer(lang_form([words[_] for _ in range(len(words)) if _ > 2], unsigned[1])) + return + + if unsigned[0] == 'переверни': + if "переверни - " in low_mes: + await message.answer(revers(message.text[12:], True)) + elif "переверни полностью - " in low_mes: + await message.answer(revers(message.text[22:], False)) + return + + if unsigned[0] == 'озвучь' and "озвучь - " in low_mes: + text_to_voice = message.text[9:] + tts = gTTS(text_to_voice, lang='ru') + tts.save('../data/voices/voice.ogg') + await bot.send_voice(chat_id=group_id, voice=open('../data/voices/voice.ogg', 'rb'), + caption=f"{text_to_voice}", parse_mode=types.ParseMode.HTML) + os.remove('../data/voices/voice.ogg') + return + + # РАНДОМ ИВЕНТЫ + if "подраться" == words[0].lower() and "с" == words[1].lower(): + text = " ".join([words[i] for i in range(len(words)) if i > 1]) + + if random.randint(0, 1) == 0: + await message.bot.send_photo(chat_id=group_id, + photo=open(f"../data/fight/({random.randint(1, 8)}).jpg", 'rb'), + caption=f"{message.from_user.first_name}, ты был унижен {text.title()}" + f", с помощью {base.VAR_LOSE[random.randint(0, 3)]}") + else: + await message.bot.send_photo(chat_id=group_id, + photo=open(f"../data/fight/({random.randint(1, 8)}).jpg", 'rb'), + caption=f"{message.from_user.first_name}, ты победил в драке " + f"с {text.title()}, {base.VAR_WIN[random.randint(0, 1)]}") + + # ИВЕНТ ВЗАИМОДЕЙСТВИЯ + for word in base.TMOK_LIST: + if word in low_mes: + lst = [words[i] for i in range(len(words)) if i != 0] + text = " ".join(lst) + + slv = morph.parse(words[0].lower())[0] + await message.bot.send_photo(chat_id=group_id, + photo=open(f"../data/tmok/({random.randint(1, 4)}).jpg", 'rb'), + caption=f"{message.from_user.first_name} " + f"{slv.inflect({'past', 'sing', 'indc'}).word} {text}") + + for word in base.KILL_LIST: + if word in low_mes: + lst = [words[i] for i in range(len(words)) if i != 0] + text = " ".join(lst) + + slv = morph.parse(words[0].lower())[0] + await message.bot.send_photo(chat_id=group_id, + photo=open(f"../data/kill/({random.randint(1, 6)}).jpg", 'rb'), + caption=f"{message.from_user.first_name} " + f"{slv.inflect({'past', 'sing', 'indc'}).word} {text}") + + if unsigned[0] in base.QUAT_LIST[0] and \ + unsigned[1] in base.QUAT_LIST[1] and unsigned[2] in base.QUAT_LIST[2]: + word = requests.get('http://fucking-great-advice.ru/api/random').json() + await message.reply(word["text"]) + return + + if message.chat.id < 0: + # ЛИСТ КОМАНДЫ + if names: + try: + await message.reply(notice(names, False, du.get_group_id(group_id), user_id), types.ParseMode.HTML) + except Exception as e: + return + """ + await bot.send_message(chat_id=base.TEX_GROUP, text=f"[ {str(dt.now())[:-10]} ] " + f"=> {repr(e)} (уведомления по именам)", + parse_mode=types.ParseMode.HTML) + """ + return + + # ПЕРЕВОДЧИК СЛОВ + if checker([i for i in low_mes], words, group_id, user_id, name.lower()) == len(low_mes) and \ + not any([engl_dict.check(i) for i in unsigned]): + await message.reply(f"[{message.from_user.first_name}](tg://user_id?id={user_id}) *>* {translator(words)}", + types.ParseMode.MARKDOWN) + return + + +if __name__ == '__main__': + loop = asyncio.get_event_loop() + executor.start_polling(dp, skip_updates=True) diff --git a/code/script.py b/code/script.py new file mode 100644 index 0000000..9bb2e7f --- /dev/null +++ b/code/script.py @@ -0,0 +1,172 @@ +from base import ERR, ERR_, TRU, TRU_, ALB +from string import digits, punctuation +import re, sql + +# инициализируем соединение с БД +db = sql.Base('../db/base.db') +du = sql.User('../db/users.db') +dg = sql.Group('../db/groups.db') +dm = sql.Month('../db/month.db') + + +def upd_stat(user_id, group_id, var_id, name, mes=False): + name = re.sub(r'[^\w\s]', '', name.lower()) + if not du.user_exists(user_id): + du.add_user(user_id) + user_id = du.get_user_id(user_id) + + if not du.group_exists(group_id): + du.add_group(group_id) + group_id = du.get_group_id(group_id) + + if not db.group_exists(group_id): + db.add_group(group_id) + dg.created_group(group_id) + + if not dg.user_exists(user_id, group_id): + dg.add_user(group_id, user_id, name) + + db.update_stat(group_id, var_id) + dg.update_stat(user_id, group_id, var_id) + + if not db.group_exists_month(group_id): + db.add_group_month(group_id) + dm.created_group(group_id) + dm.add_user(group_id, user_id) + else: + if not dm.user_exists(user_id, group_id): + dm.add_user(group_id, user_id) + + db.update_month_stat(group_id, var_id) + dm.update_stat(user_id, group_id, var_id) + + if mes: + db.update_month_stat(group_id, 1) + dg.update_stat(user_id, group_id, 1) + dm.update_stat(user_id, group_id, 1) + db.update_stat(group_id, 1) + + if not db.edit_user_exists(user_id): + dg.update_name(user_id, group_id, name) + + +def lang_form(text, smbl='г'): + for i in range(len(text)): + word = [str(j) + str(smbl) + str(j).lower() if j in ALB else str(j) for j in text[i]] + text[i] = ''.join(word) + return ' '.join(text) + + +def notice(name, all_users, group_id, author): + names = [i[0] for i in dg.all_names(group_id)] + ids = [du.get_first_user_id(i[0]) for i in dg.all_ids(group_id)] + + if all_users: + name = dg.user_name(name, group_id) + usr = [""+names[i].title()+"" for i in range(len(names)) + if names[i] != name.lower()] + usr.append(f'{usr[-2]} и {usr[-1]}') + del usr[-2], usr[-2] + return f'{", ".join(usr)} вас вызывает {name.title()}' + else: + no_copy = [] + for i in name: + if i not in no_copy: + no_copy.append(i) + + if len(no_copy) > 1: # ПЕРЕПИСАТЬ КОД ГАВНА КУСОК + usr = [""+_.title()+"" for _ in no_copy + if int(author) != ids[names.index(_)]] + usr.append(f'{usr[-2]} и {usr[-1]}') + del usr[-2], usr[-2] + return f"{', '.join(usr)} вас упомянули)" + else: + usr = ""+no_copy[0].title()+"" + return f"{usr}, тебя упомянули)" + + +def checker(signs, words, group_id, user_id, name): + if len([z for z in signs if (z in digits) or (z in punctuation)]) == len(signs) or signs[0] == '/': + return int('-1') + + if len(signs) > 4: + for x in range(3, len(signs)): + http = "".join([signs[x - 3], signs[x - 2], signs[x - 1], signs[x]]) + if 'http' in http: + upd_stat(user_id, group_id, 4, name) + return int('-1') + + count, raw = 0, 0 + for word in words: + for symbol in word: + raw += 1 + if (symbol in ERR) or (symbol in ERR_) or (symbol in digits): + count += 1 + return len(signs) - raw + count + + +def translator(words): + itg = [] + for word in words: + raw_word = [] + for symbol in word: + if symbol in ERR: + count = 0 + for _ in ERR: + if symbol == _: + raw_word.append(TRU[count]) + break + count += 1 + elif symbol in ERR_: + count = 0 + for _ in ERR_: + if symbol == _: + raw_word.append(TRU_[count]) + break + count += 1 + itg.append("".join(raw_word)) + return " ".join(itg) + + +def revers(message, var): + no_pct = re.sub(r'[^\w\s]', '', message) + + if var: + sml, pnc, pct, prf = [i for i in message] + [str(0)], [], [], False + for i in sml: + if i in punctuation or i == ' ': + pnc.append(i) + prf, flag = True if sml.index(i) == 0 else False, False + else: + flag = True + + if flag and len(pnc) > 0: + pct.append(''.join(pnc)) + pnc = [] + + wrd, rev, lst, txt = no_pct.split(), [], [], [] + for i in wrd: + word, up, itg = [i[-1 - l].lower() for l in range(len(i))], [], [] + + for _ in i: + up.append(True if _ in TRU_ else False) + for j in range(len(up)): + itg.append(word[j].upper() if up[j] else word[j]) + + rev.append(''.join(itg)) + + if prf: + for i in range(len(pct)): + txt = (txt + [pct[i]]) if (i + 1) == len(pct) and len(pct) > len(rev) else (txt + [pct[i], rev[i]]) + return ''.join(txt) + else: + for i in range(len(rev)): + if i > 0: + txt.append(pct[i - 1]) + txt.append(rev[i]) + if (i + 1) == len(rev) and len(pct) == len(rev): + txt.append(pct[i]) + return ''.join(txt) + else: + sml = [i for i in message] + return ''.join([sml[-1 - i] for i in range(len(sml))]) \ No newline at end of file diff --git a/code/sql.py b/code/sql.py new file mode 100644 index 0000000..f1c1d8f --- /dev/null +++ b/code/sql.py @@ -0,0 +1,389 @@ +import sqlite3 + + +class Base: + def __init__(self, database): + """Подключаемся к БД и сохраняем курсор соединения""" + self.connection = sqlite3.connect(database) + self.cursor = self.connection.cursor() + + # КОМАНДЫ + def add_group(self, group_id): + """Добавляем нового пользователя""" + with self.connection: + self.cursor.execute(f"INSERT INTO `work` (`group_id`) VALUES(?)", (group_id,)) + self.cursor.execute(f"INSERT INTO `stat` (`group_id`, `mes`, `rep`, `com`, `url`, `med`, `sti`, " + f"`voi`) VALUES(?,?,?,?,?,?,?,?)", (group_id, 0, 0, 0, 0, 0, 0, 0)) + return + + def group_exists(self, group_id): + """Проверяем, есть ли уже пользователь в базе""" + with self.connection: + result = self.cursor.execute(f'SELECT * FROM `work` WHERE `group_id` = ?', (group_id,)).fetchall() + return bool(len(result)) + + # ТАБЛИЦА STAT + def update_stat(self, group_id, var_id): + """Обновляем статистику""" + try: + with self.connection: + self.cursor.execute(f"SELECT * FROM `stat` WHERE `group_id` = ?", (group_id,)) + if var_id == 1: + return self.cursor.execute(f"UPDATE `stat` SET `mes` = ? WHERE `group_id` = ?", + ((self.cursor.fetchone()[1] + 1), group_id)) + elif var_id == 2: + return self.cursor.execute(f"UPDATE `stat` SET `rep` = ? WHERE `group_id` = ?", + ((self.cursor.fetchone()[2] + 1), group_id)) + elif var_id == 3: + return self.cursor.execute(f"UPDATE `stat` SET `com` = ? WHERE `group_id` = ?", + ((self.cursor.fetchone()[3] + 1), group_id)) + elif var_id == 4: + return self.cursor.execute(f"UPDATE `stat` SET `url` = ? WHERE `group_id` = ?", + ((self.cursor.fetchone()[4] + 1), group_id)) + elif var_id == 5: + return self.cursor.execute(f"UPDATE `stat` SET `med` = ? WHERE `group_id` = ?", + ((self.cursor.fetchone()[5] + 1), group_id)) + elif var_id == 6: + return self.cursor.execute(f"UPDATE `stat` SET `sti` = ? WHERE `group_id` = ?", + ((self.cursor.fetchone()[6] + 1), group_id)) + elif var_id == 7: + return self.cursor.execute(f"UPDATE `stat` SET `voi` = ? WHERE `group_id` = ?", + ((self.cursor.fetchone()[7] + 1), group_id)) + except Exception as e: + print(repr(e)) + + def stat_group(self, group_id): + """Получение данных пользователя""" + with self.connection: + self.cursor.execute(f"SELECT * FROM `stat` WHERE `group_id` = ?", (group_id,)) + data = self.cursor.fetchone() + return data[1:] + + # ТАБЛИЦА MONTH + def group_exists_month(self, group_id): + """Проверяем, есть ли уже пользователь в базе""" + with self.connection: + result = self.cursor.execute('SELECT * FROM `month` WHERE `group_id` = ?', (group_id,)).fetchall() + return bool(len(result)) + + def add_group_month(self, group_id): + """Добавляем нового пользователя""" + with self.connection: + return self.cursor.execute("INSERT INTO `month` (`group_id`, `mes`, `rep`, `com`, `url`, `med`, `sti`, " + "`voi`) VALUES(?,?,?,?,?,?,?,?)", (group_id, 0, 0, 0, 0, 0, 0, 0)) + + def update_month_stat(self, group_id, var_id): + """Обновляем статистику""" + try: + with self.connection: + self.cursor.execute(f"SELECT * FROM `month` WHERE `group_id` = ?", (group_id,)) + if var_id == 1: + return self.cursor.execute(f"UPDATE `month` SET `mes` = ? WHERE `group_id` = ?", + ((self.cursor.fetchone()[1] + 1), group_id)) + elif var_id == 2: + return self.cursor.execute(f"UPDATE `month` SET `rep` = ? WHERE `group_id` = ?", + ((self.cursor.fetchone()[2] + 1), group_id)) + elif var_id == 3: + return self.cursor.execute(f"UPDATE `month` SET `com` = ? WHERE `group_id` = ?", + ((self.cursor.fetchone()[3] + 1), group_id)) + elif var_id == 4: + return self.cursor.execute(f"UPDATE `month` SET `url` = ? WHERE `group_id` = ?", + ((self.cursor.fetchone()[4] + 1), group_id)) + elif var_id == 5: + return self.cursor.execute(f"UPDATE `month` SET `med` = ? WHERE `group_id` = ?", + ((self.cursor.fetchone()[5] + 1), group_id)) + elif var_id == 6: + return self.cursor.execute(f"UPDATE `month` SET `sti` = ? WHERE `group_id` = ?", + ((self.cursor.fetchone()[6] + 1), group_id)) + elif var_id == 7: + return self.cursor.execute(f"UPDATE `month` SET `voi` = ? WHERE `group_id` = ?", + ((self.cursor.fetchone()[7] + 1), group_id)) + except Exception as e: + print(repr(e)) + + def month_stat_group(self, group_id): + """Получение данных пользователя""" + with self.connection: + self.cursor.execute(f"SELECT * FROM `month` WHERE `group_id` = ?", (group_id,)) + data = self.cursor.fetchone() + return data[1:] + + # ТАБЛИЦА EDIT + def add_edit_user(self, user_id): + """Добавляем нового пользователя""" + with self.connection: + return self.cursor.execute("INSERT INTO `edit` (`user_id`) VALUES(?)", (user_id,)) + + def edit_user_exists(self, user_id): + """Проверяем, есть ли уже пользователь в базе""" + with self.connection: + result = self.cursor.execute('SELECT * FROM `edit` WHERE `user_id` = ?', (user_id,)).fetchall() + return bool(len(result)) + + def del_edit_user(self, user_id): + """Удаление пользователя""" + with self.connection: + return self.cursor.execute(f'DELETE FROM `edit` WHERE `user_id` = ?', (user_id,)) + + # ТАБЛИЦА WORK + def check_status(self, group_id): + """Получаем статус""" + with self.connection: + return self.cursor.execute(f'SELECT `state` FROM `work` WHERE `group_id` = ?', (group_id,)).fetchone()[0] + + def update_status(self, group_id): + """Обновляем статус""" + with self.connection: + state = self.cursor.execute(f'SELECT `state` FROM `work` WHERE `group_id` = ?', (group_id,)).fetchone()[0] + return self.cursor.execute(f"UPDATE `work` SET `state` = ? WHERE `group_id` = ?", (not state, group_id)) + + # ЗАКРЫТИЕ ВЫЗОВА + def close(self): + """Закрываем соединение с БД""" + self.connection.close() + + +class User: + def __init__(self, database): + """Подключаемся к БД и сохраняем курсор соединения""" + self.connection = sqlite3.connect(database) + self.cursor = self.connection.cursor() + + # СВЯЗКА ПОЛЬЗОВАТЕЛЯ + def user_exists(self, user_id): + """Проверяем, есть ли уже пользователь в базе""" + with self.connection: + result = self.cursor.execute(f'SELECT * FROM `users` WHERE `user_id` = ?', (user_id,)).fetchall() + return bool(len(result)) + + def add_user(self, user_id): + """Добавляем нового пользователя""" + with self.connection: + return self.cursor.execute(f"INSERT INTO `users` (`user_id`) VALUES(?)", (user_id,)) + + def get_user_id(self, user_id): + """Получаем короткое айди юзера""" + with self.connection: + return self.cursor.execute(f'SELECT `id` FROM `users` WHERE `user_id` = ?', (user_id,)).fetchone()[0] + + def get_first_user_id(self, user_id): + """Получаем длинное айди юзера""" + with self.connection: + return self.cursor.execute(f'SELECT `user_id` FROM `users` WHERE `id` = ?', (user_id,)).fetchone()[0] + + # СВЯЗКА ГРУППЫ + def group_exists(self, group_id): + """Проверяем, есть ли уже группа в базе""" + with self.connection: + result = self.cursor.execute('SELECT * FROM `groups` WHERE `group_id` = ?', (group_id,)).fetchall() + return bool(len(result)) + + def add_group(self, group_id): + """Добавляем новую группу в таблицу""" + with self.connection: + return self.cursor.execute("INSERT INTO `groups` (`group_id`) VALUES(?)", (group_id,)) + + def get_group_id(self, group_id): + """Получаем короткое айди юзера""" + with self.connection: + return self.cursor.execute(f'SELECT `id` FROM `groups` WHERE `group_id` = ?', (group_id,)).fetchone()[0] + + def get_first_group_id(self, group_id): + """Получаем длинное айди юзера""" + with self.connection: + return self.cursor.execute(f'SELECT `group_id` FROM `groups` WHERE `id` = ?', (group_id,)).fetchone()[0] + + def update_group_id(self, from_id, to_id): + """Заменяем на новый айди""" + with self.connection: + return self.cursor.execute("UPDATE `groups` SET `group_id` = ? WHERE `id` = ?", (to_id, from_id)) + + # ЗАКРЫТИЕ ВЫЗОВА + def close(self): + """Закрываем соединение с БД""" + self.connection.close() + + +class Group: + def __init__(self, database): + """Подключаемся к БД и сохраняем курсор соединения""" + self.connection = sqlite3.connect(database) + self.cursor = self.connection.cursor() + + # КОМАНДЫ + def created_group(self, group_id): + """Создаём новую таблицу""" + with self.connection: + return self.cursor.execute(f"""CREATE TABLE IF NOT EXISTS [{group_id}] ( + user_id INTEGER NOT NULL, + first_name STRING, + mes INTEGER, + rep INTEGER, + com INTEGER, + url INTEGER, + med INTEGER, + sti INTEGER, + voi INTEGER);""") + + def add_user(self, group_id, user_id, name): + """Добавляем нового пользователя""" + with self.connection: + return self.cursor.execute(f"INSERT INTO `{group_id}` (`user_id`, `first_name`, `mes`, `rep`, `com`, `url`, " + f"`med`, `sti`, `voi`) VALUES(?,?,?,?,?,?,?,?,?)", (user_id, name, 0, 0, 0, 0, 0, + 0, 0)) + + def all_names(self, group_id): + """Список имён""" + with self.connection: + return self.cursor.execute(f'SELECT `first_name` FROM `{group_id}`').fetchall() + + def all_ids(self, group_id): + """Список айди""" + with self.connection: + return self.cursor.execute(f'SELECT `user_id` FROM `{group_id}`').fetchall() + + def update_stat(self, user_id, group_id, var_id): + """Обновляем статистику""" + try: + with self.connection: + self.cursor.execute(f"SELECT * FROM `{group_id}` WHERE `user_id` = ?", (user_id,)) + if var_id == 1: + return self.cursor.execute(f"UPDATE `{group_id}` SET `mes` = ? WHERE `user_id` = ?", + ((self.cursor.fetchone()[2] + 1), user_id)) + elif var_id == 2: + return self.cursor.execute(f"UPDATE `{group_id}` SET `rep` = ? WHERE `user_id` = ?", + ((self.cursor.fetchone()[3] + 1), user_id)) + elif var_id == 3: + return self.cursor.execute(f"UPDATE `{group_id}` SET `com` = ? WHERE `user_id` = ?", + ((self.cursor.fetchone()[4] + 1), user_id)) + elif var_id == 4: + return self.cursor.execute(f"UPDATE `{group_id}` SET `url` = ? WHERE `user_id` = ?", + ((self.cursor.fetchone()[5] + 1), user_id)) + elif var_id == 5: + return self.cursor.execute(f"UPDATE `{group_id}` SET `med` = ? WHERE `user_id` = ?", + ((self.cursor.fetchone()[6] + 1), user_id)) + elif var_id == 6: + return self.cursor.execute(f"UPDATE `{group_id}` SET `sti` = ? WHERE `user_id` = ?", + ((self.cursor.fetchone()[7] + 1), user_id)) + elif var_id == 7: + return self.cursor.execute(f"UPDATE `{group_id}` SET `voi` = ? WHERE `user_id` = ?", + ((self.cursor.fetchone()[8] + 1), user_id)) + except Exception as e: + print(repr(e)) + + def user_exists(self, user_id, group_id): + """Проверяем, есть ли уже пользователь в базе""" + with self.connection: + result = self.cursor.execute(f'SELECT * FROM `{group_id}` WHERE `user_id` = ?', (user_id,)).fetchall() + return bool(len(result)) + + def update_name(self, user_id, group_id, name): + """Обновляем имя пользователя""" + with self.connection: + return self.cursor.execute(f"UPDATE `{group_id}` SET `first_name` = ? WHERE `user_id` = ?", (name, user_id)) + + def user_name(self, user_id, group_id): + """Получаем имя пользователя по айди""" + with self.connection: + return self.cursor.execute(f"SELECT `first_name` FROM `{group_id}` WHERE `user_id` = ?", (user_id,)).fetchone()[0] + + def stat_user(self, user_id, group_id): + """Получение данных пользователя""" + with self.connection: + self.cursor.execute(f"SELECT * FROM `{group_id}` WHERE `user_id` = ?", (user_id,)) + data = self.cursor.fetchone() + return data[2:] + + def del_user(self, group_id, user_id): + """Удаление пользователя""" + with self.connection: + return self.cursor.execute(f'DELETE FROM `{group_id}` WHERE `user_id` = ?', (user_id,)) + + # ЗАКРЫТИЕ ВЫЗОВА + def close(self): + """Закрываем соединение с БД""" + self.connection.close() + + +class Month: + def __init__(self, database): + """Подключаемся к БД и сохраняем курсор соединения""" + self.connection = sqlite3.connect(database) + self.cursor = self.connection.cursor() + + # КОМАНДЫ + def update_stat(self, user_id, group_id, var_id): + """Обновляем статистику""" + try: + with self.connection: + self.cursor.execute(f"SELECT * FROM `{group_id}` WHERE `user_id` = ?", (user_id,)) + if var_id == 1: + return self.cursor.execute(f"UPDATE `{group_id}` SET `mes` = ? WHERE `user_id` = ?", + ((self.cursor.fetchone()[1] + 1), user_id)) + elif var_id == 2: + return self.cursor.execute(f"UPDATE `{group_id}` SET `rep` = ? WHERE `user_id` = ?", + ((self.cursor.fetchone()[2] + 1), user_id)) + elif var_id == 3: + return self.cursor.execute(f"UPDATE `{group_id}` SET `com` = ? WHERE `user_id` = ?", + ((self.cursor.fetchone()[3] + 1), user_id)) + elif var_id == 4: + return self.cursor.execute(f"UPDATE `{group_id}` SET `url` = ? WHERE `user_id` = ?", + ((self.cursor.fetchone()[4] + 1), user_id)) + elif var_id == 5: + return self.cursor.execute(f"UPDATE `{group_id}` SET `med` = ? WHERE `user_id` = ?", + ((self.cursor.fetchone()[5] + 1), user_id)) + elif var_id == 6: + return self.cursor.execute(f"UPDATE `{group_id}` SET `sti` = ? WHERE `user_id` = ?", + ((self.cursor.fetchone()[6] + 1), user_id)) + elif var_id == 7: + return self.cursor.execute(f"UPDATE `{group_id}` SET `voi` = ? WHERE `user_id` = ?", + ((self.cursor.fetchone()[7] + 1), user_id)) + except Exception as e: + print(repr(e)) + + def created_group(self, group_id): + """Создаём новую таблицу""" + with self.connection: + return self.cursor.execute(f"""CREATE TABLE IF NOT EXISTS [{group_id}] ( + user_id INTEGER NOT NULL, + mes INTEGER, + rep INTEGER, + com INTEGER, + url INTEGER, + med INTEGER, + sti INTEGER, + voi INTEGER);""") + + def add_user(self, group_id, user_id): + """Добавляем нового пользователя""" + with self.connection: + return self.cursor.execute(f"INSERT INTO `{group_id}` (`user_id`, `mes`, `rep`, `com`, `url`, `med`, " + f"`sti`, `voi`) VALUES(?,?,?,?,?,?,?,?)", (user_id, 0, 0, 0, 0, 0, 0, 0)) + + def all_ids(self, group_id): + """Список айди""" + with self.connection: + return self.cursor.execute(f'SELECT `user_id` FROM `{group_id}`').fetchall() + + def user_exists(self, user_id, group_id): + """Проверяем, есть ли уже пользователь в базе""" + with self.connection: + result = self.cursor.execute(f'SELECT * FROM `{group_id}` WHERE `user_id` = ?', (user_id,)).fetchall() + return bool(len(result)) + + def stat_user(self, user_id, group_id): + """Получение данных пользователя""" + with self.connection: + self.cursor.execute(f"SELECT * FROM `{group_id}` WHERE `user_id` = ?", (user_id,)) + data = self.cursor.fetchone() + return data[1:] + + def del_user(self, group_id, user_id): + """Удаление пользователя""" + with self.connection: + return self.cursor.execute(f'DELETE FROM `{group_id}` WHERE `user_id` = ?', (user_id,)) + + # ЗАКРЫТИЕ ВЫЗОВА + def close(self): + """Закрываем соединение с БД""" + self.connection.close() diff --git a/db/base.db b/db/base.db new file mode 100644 index 0000000000000000000000000000000000000000..515e7aa11fb6f4931d779c3d556a90dae41934e9 GIT binary patch literal 28672 zcmeI4U1(fI6vt;~zwT^y@7>R=Tbtx+jO?1Ue%1;pnxx%E={9NFEo}&NvnJPMn`}1O zkBV57qzHO(qYIFvdLf%IWhls!pnnqI5eKW#j1R zb-(`xbNL3C5!d^DKl%Uk4NwCG1V8`;KmY_l00ck)1VG?FM_}2Ecw(^_U+JpkUY)lJ z#f8eOEu1IMrv@`AGc!1pPMNmKOw5#u)x~Un+I(dslNwH)H%CS@=E%i#y3Z_F<%YJ; zELn>ijj3W`qfsr*Z!`*4(^8*VuH-j*t`(b&8Jp+rB(bh1`mG{+|JNM`~6Ef^G%HvaMLtvDb14voo=fD_DIrGD#u7Qnww5yA2pRvbl;uzCjIJ?3NU7Tx|hSg{vbdA1V8`;KmY_l00ck) z1V8`;KmY{xoj@*}BAXLbFNKFljs@39o(YpU9V9VmkT{`}I4(#$qjvO1d?XTWB)YvM zIwgs?Mk1mD`i6P}$=#0w1ptcy0T2KI5C8!X009sH0T2KI5ZG4&`Zp}cHK|dFI;oKnoC~3G&H2$u z!QK(K``dkzG)gP{10P4Lv4_N$j!W#vs8QE*5jb?qb@kC6!7IFjYy^bloJ{IZeBwT= z-)H)LW0I{l+ztk59OoM6Jj7qjIDJEL{SW5!hiDMZOMhXnQ_zShyQyi$)51uxgrnw| z6km6~@q#Rfwu~{Ux6z>5FyG@2;iXZbfbEvj2c2iw_ns4-aZb}l7#5EC); zRM+R1*@y075z@6NE!~DivinWnTKmI%C0`5TGv;d`h`1Va376+Paog{B`8oD;y*H@f zNR3C>jYwED_W#D}?nlEsK0yEkKmY_l00ck)1V8`;KmY_l00j1jz?_VdAxlO`W~EB@ zAD1DL7o^JhKP%~#eKssr>i?irx&QrA?c|S1^$g%isWShQQlR3^ns zc9eRLA^n?MLi%@@e#e+#Up1I+7t;UM{@?Ulqx!S#y?Q)-BRKyEGiF&y`O^}6e;~Gh zoORVE40|YizBNt3r`PibY6%0g%xriUl6JJcC5Ugl#SG&vyV6X3pvG9ug_aZn;}%o9 z_j-wFl5dlSaJQLVuqm2v{H6{yaKJ|WKte#$p|S_4Z|z?3va{Ru{Gqt-*S_`IRLxX@ g`pozM0T2KI5C8!X009sH0T2KI5C8!XIKTw{0$0S-tpET3 literal 0 HcmV?d00001 diff --git a/db/groups.db b/db/groups.db new file mode 100644 index 0000000..e69de29 diff --git a/db/month.db b/db/month.db new file mode 100644 index 0000000..e69de29 diff --git a/db/users.db b/db/users.db new file mode 100644 index 0000000000000000000000000000000000000000..0e31838480763de099212758dd88ac7335f2ca4d GIT binary patch literal 81920 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 pF0ax5PYQtDqV%;lizy(