stop_words.py 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. import asyncio
  2. import datetime
  3. import sqlite3
  4. from aiogram import Router, types, F
  5. from aiogram.fsm.context import FSMContext
  6. from aiogram.utils.markdown import hpre, hbold
  7. import async_db
  8. import config
  9. from loader import db, bot, scheduler, logger
  10. from keyboards import menu_keys
  11. from keyboards.callbacks_data import MenuCategory
  12. from utils import User, StopWordsStates
  13. router = Router()
  14. router.message.filter(F.chat.type == "private")
  15. router.callback_query.filter(
  16. # MenuCategory.filter(F.category == "stop_Words")
  17. )
  18. async def parse_words_from_message(m: types.Message):
  19. lines = m.text.split('\n')
  20. return lines
  21. async def collect_words(m: types.Message):
  22. lines = m.text.split('\n')
  23. words = []
  24. # если одна строка и после команды что-то написанно
  25. if len(lines) == 1 and len(lines[0].split()) > 1:
  26. # склеиваем слова после команды и добавляем в общий список
  27. word = ' '.join([i.strip() for i in lines[0].split()[1::]])
  28. words.append(word)
  29. # Если строк больше
  30. elif len(lines) > 1:
  31. # В первой строчке не только команда
  32. if len(lines[0].split()) > 1:
  33. word = ' '.join([i.strip() for i in lines[0].split()[1::]])
  34. words.append(word)
  35. for line in lines[1::]:
  36. words.append(line.strip())
  37. return words
  38. @router.message(commands='stop_add')
  39. async def add_world(m: types.Message, context: dict):
  40. words = await collect_words(m)
  41. processed_words = []
  42. for w in words:
  43. try:
  44. db.add_word(m.from_user.id, w)
  45. processed_words.append(f"✅ {w} - добавленно в список стоп слов")
  46. await asyncio.sleep(1)
  47. except sqlite3.IntegrityError as e:
  48. if 'UNIQUE constraint failed' in str(e):
  49. processed_words.append(f'❌ {w} - Уже есть в списке')
  50. continue
  51. words_success = "\n".join(processed_words)
  52. text = f'{hpre(words_success)}'
  53. await m.reply(text)
  54. context['users'] = db.get_all_clients()
  55. @router.message(commands='stop_del')
  56. async def stop_delete(m: types.Message, context: dict):
  57. words = await collect_words(m)
  58. processed_words = []
  59. for w in words:
  60. try:
  61. db.delete_word(m.from_user.id, w)
  62. processed_words.append(f"✅ {w} - удалено из списка стоп слов")
  63. await asyncio.sleep(1)
  64. except Exception as e:
  65. logger.error(e)
  66. processed_words.append(f'❌ {w} - Ошибка')
  67. continue
  68. words_success = "\n".join(processed_words)
  69. text = f'{hpre(words_success)}'
  70. to_delete = await m.reply(text)
  71. context['users'] = db.get_all_clients()
  72. # context['stop_words'] = [word[1] for word in db.select_default_word()]
  73. @router.message(commands='default_list')
  74. async def list_default(m: types.Message, context: dict, user_id=None):
  75. words = db.select_default_word()
  76. messages = []
  77. temp_text = ''
  78. for i in words:
  79. temp_text += f"{i}\n"
  80. if len(temp_text) > 4000:
  81. messages.append(temp_text)
  82. temp_text = ''
  83. if i is words[-1]:
  84. messages.append(temp_text)
  85. for list_words in messages:
  86. text = f'Список слов, удаляющихся по умолчанию: \n{hpre(list_words)}'
  87. if len(messages) > 1 and list_words not in messages[0]:
  88. text = hpre(list_words)
  89. await m.answer(text)
  90. @router.message(commands='stop_list')
  91. async def list_stop_worlds(m: types.Message, context: dict, user_id=None):
  92. if not user_id:
  93. user_id = m.from_user.id
  94. # await m.delete()
  95. stop_words = []
  96. users = context["users"]
  97. for c in users:
  98. if c.client_id == user_id:
  99. stop_words = c.stop_words
  100. break
  101. # drop to messages
  102. messages = []
  103. temp_text = ''
  104. for i in stop_words:
  105. temp_text += f"{i}\n"
  106. if len(temp_text) > 4000:
  107. messages.append(temp_text)
  108. temp_text = ''
  109. if i is stop_words[-1]:
  110. messages.append(temp_text)
  111. for list_words in messages:
  112. no_words = 'Сюда пока что ничего не добавили((\nНажми на кнопку ниже чтобы добавить нужные тебе слова ' \
  113. 'или напиши <code>/stop_add </code>[слово] - чтобы добавить слово в фильтр\n' \
  114. 'Также есть список слов сообщения с которыми удаляются по умолчанию. посмотреть их можно по команде ' \
  115. '/default_list'
  116. text = f'Список всех стоп слов: \n{hpre(list_words)}' if len(stop_words) > 0 else no_words
  117. if len(messages) > 1 and list_words not in messages[0]:
  118. text = hpre(list_words)
  119. await m.answer(text)
  120. @router.callback_query(
  121. MenuCategory.filter(F.category == 'stop_words'),
  122. MenuCategory.filter(F.action == 'list'),
  123. )
  124. async def list_worlds(call: types.CallbackQuery, callback_data: MenuCategory, context: dict):
  125. await list_stop_worlds(call.message, context, call.from_user.id)
  126. @router.callback_query(
  127. MenuCategory.filter(F.category == 'stop_words'),
  128. MenuCategory.filter(F.action.in_({'add', 'delete'})),
  129. )
  130. async def add_del_words(call: types.CallbackQuery, callback_data: MenuCategory, context: dict, state: FSMContext):
  131. users = context["users"]
  132. words = []
  133. for user in users:
  134. if call.from_user.id == user.client_id:
  135. words = user.stop_words
  136. words_list = '\n'.join(words)
  137. if callback_data.action == 'add':
  138. await state.set_state(StopWordsStates.add)
  139. await call.message.edit_text(
  140. f"Твой список:\n{hpre(words_list[:3900])}\n\nЕсли список не полный нажми /stop_list\n\n"
  141. f"Напиши мне что хочешь добавить. Можно добавить или удалить сразу нескольслко стоп слов."
  142. "Для этого разделяй их по строкам")
  143. await call.message.edit_reply_markup(menu_keys.back(2, 'stop_words'))
  144. elif callback_data.action == 'delete':
  145. await state.set_state(StopWordsStates.delete)
  146. await call.message.edit_text(
  147. f"Твой список:\n{hpre(words_list[:3900])}\n\nЕсли список не полный нажми /stop_list\n\n"
  148. f"Напиши мне что хочешь удалить. Можно добавить или удалить сразу нескольслко стоп слов."
  149. "Для этого разделяй их по строкам")
  150. await call.message.edit_reply_markup(menu_keys.back(2, 'stop_words'))
  151. await state.update_data(call=call)
  152. scheduler.add_job(state.clear, trigger='date',
  153. run_date=datetime.datetime.now() + datetime.timedelta(minutes=1))
  154. async def delete_mess(m: types.Message):
  155. await m.delete()
  156. @router.message(StopWordsStates.add)
  157. async def stop_words_add(m: types.Message, context: FSMContext, state: FSMContext):
  158. data = await state.get_data()
  159. call = data['call']
  160. words = m.text.split('\n')
  161. for word in words:
  162. db.add_word(m.from_user.id, word)
  163. context['users'] = db.get_all_clients()
  164. mess = await m.answer(f"Добавил: {hbold(m.text)}")
  165. await m.delete()
  166. await add_del_words(call, MenuCategory(level=2, category='stop_words', action='add'), context, state)
  167. scheduler.add_job(delete_mess, args=(mess,), trigger='date',
  168. run_date=datetime.datetime.now() + datetime.timedelta(seconds=10))
  169. @router.message(StopWordsStates.delete)
  170. async def stop_words_dell(m: types.Message, context: FSMContext, state: FSMContext):
  171. data = await state.get_data()
  172. call = data['call']
  173. words = m.text.split('\n')
  174. for word in words:
  175. db.delete_word(m.from_user.id, word)
  176. context['users'] = db.get_all_clients()
  177. mess = await m.answer(f"Удалил: {hbold(m.text)}")
  178. await m.delete()
  179. await add_del_words(call, MenuCategory(level=2, category='stop_words', action='add'), context, state)
  180. scheduler.add_job(delete_mess, args=(mess,), trigger='date',
  181. run_date=datetime.datetime.now() + datetime.timedelta(seconds=10))
  182. @router.callback_query(
  183. MenuCategory.filter(F.category == 'stop_words'),
  184. )
  185. async def show_menu(call: types.CallbackQuery, callback_data: MenuCategory, context: dict, state: FSMContext):
  186. # TODO: drop stop words in parts of 4000 letters
  187. current_level = callback_data.level
  188. if callback_data.action == 'back':
  189. if current_level == 2:
  190. await state.clear()
  191. current_level -= 1
  192. user_id = call.from_user.id
  193. users = context["users"]
  194. stop_words = []
  195. for c in users:
  196. if c.client_id == user_id:
  197. stop_words = c.stop_words
  198. break
  199. stop_words = '\n'.join(stop_words)
  200. # print(len(stop_words))
  201. if len(stop_words) > 4000:
  202. stop_words = f'{stop_words[:4000]}\n' \
  203. f'Ой! у вас очень много слов и они не помещаются в одно сообщение. ' \
  204. f'Нажми /stop_list чтобы увидеть весь список'
  205. levels = {
  206. 0: menu_keys.admin_menu() if call.from_user.id in config.ADMIN_ID else menu_keys.client_menu(),
  207. 1: menu_keys.action(2, 'stop_words'),
  208. 2: menu_keys.back(3, 'stop_words')
  209. }
  210. texts = {
  211. 0: "Вот чем вы можете управлять:",
  212. 1: f"Вот ваши слова:\n<code>{stop_words}</code>\n\nДоступны такие действия: \n",
  213. 2: "Напиши слова/фразы, которые хочешь добавить. Можно добавить или удалить сразу нескольслко стоп слов."
  214. "Для этого разделяй их по строкам"
  215. }
  216. await call.message.edit_text(texts[current_level])
  217. await call.message.edit_reply_markup(levels[current_level])