aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor <50257429+igorechek06@users.noreply.github.com>2021-08-28 21:10:16 +0900
committerIgor <50257429+igorechek06@users.noreply.github.com>2021-08-28 21:10:16 +0900
commita8582c60e3bed5b93c989e2963d40130771cf11d (patch)
tree747f2cfe1a8a8f003cba81d92ebe3822b4adc419
parent2efa35c42be7ac554e3519b8673f7cad8c966e64 (diff)
downloadkarpov_ai_bot-a8582c60e3bed5b93c989e2963d40130771cf11d.tar.gz
karpov_ai_bot-a8582c60e3bed5b93c989e2963d40130771cf11d.zip
0.0.1
-rw-r--r--.gitignore6
-rw-r--r--FunnyPineappleBot.sample.service18
-rw-r--r--README.md2
-rw-r--r--dependencies2
-rw-r--r--handlers/__init__.py3
-rw-r--r--handlers/ananas_only.py10
-rw-r--r--handlers/generate.py15
-rw-r--r--handlers/on_message.py19
-rw-r--r--main.py17
-rw-r--r--setup.py232
-rw-r--r--shared/__init__.py0
-rw-r--r--shared/commands.py7
-rw-r--r--shared/config.sample.py3
-rw-r--r--shared/instances.py5
-rw-r--r--utils/filters.py155
15 files changed, 493 insertions, 1 deletions
diff --git a/.gitignore b/.gitignore
index b6e4761..5e0f237 100644
--- a/.gitignore
+++ b/.gitignore
@@ -127,3 +127,9 @@ dmypy.json
127 127
128# Pyre type checker 128# Pyre type checker
129.pyre/ 129.pyre/
130
131.idea
132.vscode
133
134FunnyPineappleBot.service
135config.py \ No newline at end of file
diff --git a/FunnyPineappleBot.sample.service b/FunnyPineappleBot.sample.service
new file mode 100644
index 0000000..210b267
--- /dev/null
+++ b/FunnyPineappleBot.sample.service
@@ -0,0 +1,18 @@
1[Unit]
2Description=Telegram bot from FunnyPineappleChat
3After=syslog.target
4After=network.target
5
6[Service]
7Type=simple
8User={username}
9WorkingDirectory={path}
10ExecStart={py_path} main.py -m
11KillMode=control-group
12KillSignal=15
13SendSIGKILL={send_kill}
14RestartSec=5
15Restart=always
16
17[Install]
18WantedBy=multi-user.target \ No newline at end of file
diff --git a/README.md b/README.md
index dccb00d..4514c6a 100644
--- a/README.md
+++ b/README.md
@@ -1 +1 @@
# FunnyPineappleBot \ No newline at end of file # [FunnyPineappleBot](https://t.me/FunnyPineappleBot) \ No newline at end of file
diff --git a/dependencies b/dependencies
new file mode 100644
index 0000000..888ef8a
--- /dev/null
+++ b/dependencies
@@ -0,0 +1,2 @@
1aiogram
2mc.py
diff --git a/handlers/__init__.py b/handlers/__init__.py
new file mode 100644
index 0000000..bf57f77
--- /dev/null
+++ b/handlers/__init__.py
@@ -0,0 +1,3 @@
1from . import ananas_only
2from . import on_message
3from . import generate
diff --git a/handlers/ananas_only.py b/handlers/ananas_only.py
new file mode 100644
index 0000000..7426593
--- /dev/null
+++ b/handlers/ananas_only.py
@@ -0,0 +1,10 @@
1from shared.instances import dp
2from aiogram import types as t
3from utils import filters as f
4
5
6@dp.my_chat_member_handler(f.user.add_member)
7async def pososi(upd: t.ChatMemberUpdated):
8 if upd.chat.id not in (-1001444484622, -1001197098429):
9 await upd.bot.send_message(upd.chat.id, 'https://www.youtube.com/watch?v=xdDhmagsXrc')
10 await upd.chat.leave()
diff --git a/handlers/generate.py b/handlers/generate.py
new file mode 100644
index 0000000..3902f07
--- /dev/null
+++ b/handlers/generate.py
@@ -0,0 +1,15 @@
1import mc
2from shared.instances import dp
3from aiogram import types as t
4from utils import filters as f
5
6
7@dp.message_handler(f.message.chance(10), f.message.is_chat)
8async def срать_сообщение_с_шансом(msg: t.Message):
9 await сгенерировать_хуету(msg)
10
11
12@dp.message_handler(f.message.is_chat, commands=['gen'])
13async def сгенерировать_хуету(msg: t.Message):
14 samples = mc.util.load_txt_samples('samples.txt', separator='§')
15 await msg.answer(mc.StringGenerator(samples=samples).generate_string())
diff --git a/handlers/on_message.py b/handlers/on_message.py
new file mode 100644
index 0000000..b9b5499
--- /dev/null
+++ b/handlers/on_message.py
@@ -0,0 +1,19 @@
1from shared.instances import dp
2from aiogram import types as t
3from utils import filters as f
4
5
6async def sosalka(msg: t.Message):
7 '''сосет сообщения'''
8 text = msg.text or msg.caption
9 if text.startswith('/'):
10 return False
11 with open('samples.txt', 'a+') as file:
12 file.write(text.replace('§', '').lower() + '§')
13 return False
14
15
16@dp.message_handler(f.message.is_chat, f.message.has_text, sosalka, content_types=[t.ContentType.ANY])
17async def НАХУЯ_ПРАВДА_Я_НЕ_ЗНАЮ_ЗАЧЕМ_ЭТА_ФУНКЦИЯ_НУЖНА():
18 print('NIGGER NIGGER NIGGER NIGGER NIGGER NIGGER NIGGER NIGGER NIGGER NIGGER NIGGER NIGGER NIGGER NIGGER NIGGER NIGGER NIGGER NIGGER NIGGER NIGGER NIGGER NIGGER NIGGER NIGGER NIGGER NIGGER NIGGER NIGGER NIGGER NIGGER NIGGER NIGGER NIGGER NIGGER NIGGER NIGGER NIGGER NIGGER NIGGER NIGGER NIGGER NIGGER NIGGER NIGGER NIGGER NIGGER NIGGER NIGGER NIGGER NIGGER NIGGER NIGGER NIGGER NIGGER NIGGER ')
19 return 'я могу сюда любую хуйню написать, все равно в фильтре фолз =)))))))))))))))))00'
diff --git a/main.py b/main.py
new file mode 100644
index 0000000..d9dce7e
--- /dev/null
+++ b/main.py
@@ -0,0 +1,17 @@
1from aiogram import executor, types as t, Dispatcher
2from shared.instances import dp, bot
3import logging
4
5logging.basicConfig(level=logging.INFO)
6
7
8async def on_start(dp: Dispatcher):
9 from shared.commands import commands
10 for scope, cmd in commands.items():
11 await bot.set_my_commands(cmd, scope)
12
13if __name__ == '__main__':
14 import handlers
15 executor.start_polling(
16 dp, allowed_updates=t.AllowedUpdates.all(), on_startup=on_start
17 )
diff --git a/setup.py b/setup.py
new file mode 100644
index 0000000..b59e23f
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,232 @@
1import os
2import platform
3import shutil
4import sys
5import traceback
6import typing as p
7
8term = shutil.get_terminal_size()
9sep = "=" * term.columns
10
11venv = False
12default = 1
13
14if os.name == "nt":
15 print(f"Setup not supported on {platform.system()}")
16 exit()
17
18
19def _opt_selector(options: p.Dict[str, p.Any], default: p.Optional[int] = None, pmt: str = "") -> p.Tuple[int, p.Any]:
20 _options = {}
21 print("Choose variant")
22 print(sep)
23
24 num = 1
25 for opt in options:
26 if options[opt] is None:
27 print()
28 continue
29
30 d = "*" if default == num else " "
31
32 print(f" {d}{num} - {opt}")
33 _options[num] = options[opt]
34 num += 1
35 print(sep)
36
37 while True:
38 opt = input(f"{pmt}-> ")
39 if opt.isdigit():
40 opt = int(opt)
41 if opt in _options:
42 return opt, _options[opt]
43 if opt == "" and default is not None:
44 return default, _options[default]
45
46 print("Incorrect answer")
47 pmt = ""
48
49
50def _yes(default: bool = True) -> bool:
51 while True:
52 if default:
53 it = "[Y|n]"
54 else:
55 it = "[y|N]"
56
57 i = input(f"{it} -> ")
58 if i.lower() in ["y", "n"]:
59 return i.lower() == "y"
60 if i == "":
61 return default
62
63 print("Incorrect answer")
64
65
66def _input(prompt: str, default: str = None, required: bool = True) -> str:
67 if default:
68 print(f"Default {default}")
69 while True:
70 result = input(f"{prompt} -> ")
71 if not result:
72 if default:
73 result = default
74 break
75 elif required:
76 print("Parameter required")
77 else:
78 break
79
80 return result
81
82
83def _cmd(cmd: str, show_cmd: bool = True) -> bool:
84 if show_cmd:
85 input(f"Press enter for execute {cmd}")
86 result = os.system(cmd)
87 return True if result == 0 else False
88
89
90def _clear():
91 print()
92 print('\033c', end="")
93
94
95def _enter():
96 input("Press enter, to continue ...")
97
98
99def systemd_unit_generator():
100 while True:
101 username = _input("Your username", os.environ["USER"])
102 path = _input("Path to root of project", os.path.dirname(os.path.abspath(__file__)))
103 py_path = _input("Path to python 3.9", sys.executable)
104
105 print("Send kill (if SIGTERM Timeout)")
106 send_kill = "off"
107 if _yes(True):
108 send_kill = "on"
109
110 with open("FunnyPineappleBot.sample.service", "r") as file:
111 sample = file.read().format(username=username, path=path, py_path=py_path, send_kill=send_kill)
112
113 _clear()
114 print(
115 f"{sep}",
116 f"{sample}",
117 f"{sep}",
118 f"Your username - {username}",
119 f"Path to root of project - {path}",
120 f"Path to python 3.9 - {py_path}",
121 f"Send kill - {send_kill}",
122 f"{sep}",
123 "",
124 "All correct ?",
125 sep="\n"
126 )
127 if _yes(False):
128 with open("FunnyPineappleBot.service", "w") as file:
129 file.write(sample)
130 _clear()
131
132 print("Link unit from /etc/systemd/system/ ?")
133 if _yes():
134 _cmd("sudo mv ToolKit.service /etc/systemd/system/")
135 _cmd("sudo ln /etc/systemd/system/ToolKit.service ./ -s")
136 break
137 else:
138 _clear()
139 print(sep)
140 _enter()
141 return True
142
143
144def config_generator():
145 try:
146 import config
147 except ImportError:
148 config = object()
149 while True:
150 main_token = _input("Main bot token", getattr(config, "main_token", None))
151 test_token = _input("Test bot token", getattr(config, "test_token", None))
152
153 with open("shared/config.sample.py", "r") as file:
154 sample = file.read().format(main_token=main_token, test_token=test_token)
155
156 print(
157 f"{sep}",
158 f"{sample}",
159 f"{sep}",
160 "All correct ?",
161 sep="\n"
162 )
163
164 if _yes(False):
165 with open("shared/config.py", "w") as file:
166 file.write(sample)
167 break
168 else:
169 _clear()
170 return True
171
172
173def install_dependencies():
174 with open("dependencies", "r") as file:
175 dependencies = file.read()
176 print(
177 "Install this ?",
178 f"{sep}",
179 f"{dependencies}",
180 f"{sep}",
181 sep="\n"
182 )
183 _cmd("pip install -U -r dependencies", False)
184 print(f"{sep}\nSuccessfully installed")
185 _enter()
186 return True
187
188
189if __name__ == '__main__':
190 opts = {
191 "Setup systemd unit": systemd_unit_generator,
192 "Setup config.py": config_generator,
193 "Install or Update dependencies": install_dependencies,
194 "Exit": exit,
195 }
196 exit_index = list(opts.keys()).index("Exit") + 1
197 default = 1
198 pmt = ""
199
200 _clear()
201 while True:
202 if default >= exit_index:
203 default = exit_index
204 term = shutil.get_terminal_size()
205 sep = "=" * term.columns
206 try:
207 _clear()
208 num, opt = _opt_selector(opts, default, pmt)
209 _clear()
210 res = opt()
211 _clear()
212
213 if num != default:
214 default = num + 1
215 elif res is True:
216 default += 1
217
218 if res is not True:
219 pmt = f"{res!r} "
220 if num == default:
221 default = num + 1
222 else:
223 pmt = ""
224
225 except KeyboardInterrupt:
226 break
227 except Exception as e:
228 pmt = f"An error has occurred ({e.__class__.__name__}:{e.args[0]})"
229 trc = traceback.format_exc()
230 print(trc)
231 _enter()
232 _clear()
diff --git a/shared/__init__.py b/shared/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/shared/__init__.py
diff --git a/shared/commands.py b/shared/commands.py
new file mode 100644
index 0000000..ffed9c3
--- /dev/null
+++ b/shared/commands.py
@@ -0,0 +1,7 @@
1from aiogram.types import BotCommand as cmd, BotCommandScopeAllGroupChats as group
2
3commands = {
4 group(): [
5 cmd('gen', 'жидко пукнуть')
6 ]
7}
diff --git a/shared/config.sample.py b/shared/config.sample.py
new file mode 100644
index 0000000..f4a3f09
--- /dev/null
+++ b/shared/config.sample.py
@@ -0,0 +1,3 @@
1TOKEN = ""
2test_token = "{test_token}"
3main_token = "{main_token}"
diff --git a/shared/instances.py b/shared/instances.py
new file mode 100644
index 0000000..7eb883c
--- /dev/null
+++ b/shared/instances.py
@@ -0,0 +1,5 @@
1from aiogram import Bot, Dispatcher
2from .config import TOKEN
3
4bot = Bot(token=TOKEN)
5dp = Dispatcher(bot)
diff --git a/utils/filters.py b/utils/filters.py
new file mode 100644
index 0000000..b6ddec5
--- /dev/null
+++ b/utils/filters.py
@@ -0,0 +1,155 @@
1import re
2import typing as p
3from random import random
4from aiogram import types as t, filters as f, Bot
5
6from shared.instances import bot
7# from libs.classes import Errors as e
8# from libs.objects import Database
9# from libs.system import regex as r
10
11objType = p.Union[t.Message, t.CallbackQuery, t.ChatMemberUpdated]
12
13
14class _helper:
15 @staticmethod
16 def get_user_and_chat(obj: objType):
17 if isinstance(obj, t.Message):
18 chat = obj.chat
19 user = obj.from_user
20 elif isinstance(obj, t.CallbackQuery):
21 chat = obj.message.chat
22 user = obj.from_user
23 elif isinstance(obj, t.ChatMemberUpdated):
24 chat = obj.chat
25 user = obj.from_user
26 else:
27 raise TypeError()
28
29 return user, chat
30
31 @staticmethod
32 def has_permission(admin: t.ChatMember, permission: str):
33 if t.ChatMemberStatus.is_chat_creator(admin.status):
34 return True
35 elif t.ChatMemberStatus.is_chat_admin(admin.status):
36 return getattr(admin, permission)
37 else:
38 return False
39
40
41class AdminFilter(f.BoundFilter):
42 def __init__(self, user_id: int = None):
43 self._user_id = user_id
44
45 async def check(self, obj: objType):
46 user, chat = _helper.get_user_and_chat(obj)
47
48 admin = await chat.get_member(self._user_id or user.id)
49 if t.ChatMemberStatus.is_chat_admin(admin.status):
50 return True
51 else:
52 return False
53
54
55class AliasFilter(f.BoundFilter):
56 def __init__(self):
57 pass
58
59 async def check(self, msg: objType) -> bool:
60 if not isinstance(msg, t.Message):
61 raise TypeError()
62 if await message.is_private.check(msg):
63 return False
64 chat = Database.get_chat(msg.chat.id)
65
66 if msg.sticker:
67 aliases = list(chat.settings.sticker_alias.keys())
68 text = msg.sticker.file_unique_id
69 elif msg.text:
70 aliases = list(chat.settings.text_alias.keys())
71 text = msg.text
72
73 for alias in aliases:
74 pattern = re.compile(r.alias(alias), re.IGNORECASE)
75 if pattern.match(text):
76 return True
77
78 return False
79
80
81class message:
82 is_chat = f.ChatTypeFilter((t.ChatType.GROUP, t.ChatType.SUPERGROUP))
83 is_private = f.ChatTypeFilter(t.ChatType.PRIVATE)
84 is_reply = f.IsReplyFilter(True)
85 is_alias = AliasFilter()
86
87 @staticmethod
88 def chance(percent: int):
89 def filter(msg: t.Message):
90 return random() <= (percent / 100)
91 return filter
92
93 @staticmethod
94 def has_text(msg: t.Message):
95 if msg.text or msg.caption:
96 return True
97
98
99class bot:
100 is_admin = AdminFilter(bot.id)
101
102 @staticmethod
103 def has_permission(permissions: p.List[str]):
104 permissions = permissions
105
106 async def filter(obj: objType):
107 bot = Bot.get_current()
108 user, chat = _helper.get_user_and_chat(obj)
109 admin = await chat.get_member(bot.id)
110 if not _helper.has_permission(admin, permissions):
111 raise e.BotHasNotPermission()
112 return True
113
114 return filter
115
116
117class user:
118 is_admin = AdminFilter()
119
120 @staticmethod
121 def has_permission(permissions: p.List[str]):
122 permissions = permissions
123
124 async def filter(obj: objType):
125 user, chat = _helper.get_user_and_chat(obj)
126 admin = await chat.get_member(user.id)
127 if not _helper.has_permission(admin, permissions):
128 raise e.HasNotPermission()
129 return True
130
131 return filter
132
133 @staticmethod
134 def add_member(upd: t.ChatMemberUpdated):
135 old = upd.old_chat_member
136 new = upd.new_chat_member
137 return not t.ChatMemberStatus.is_chat_member(old.status) and t.ChatMemberStatus.is_chat_member(new.status)
138
139 @staticmethod
140 def removed_member(upd: t.ChatMemberUpdated):
141 old = upd.old_chat_member
142 new = upd.new_chat_member
143 return t.ChatMemberStatus.is_chat_member(old.status) and not t.ChatMemberStatus.is_chat_member(new.status)
144
145 @staticmethod
146 def promote_admin(upd: t.ChatMemberUpdated):
147 old = upd.old_chat_member
148 new = upd.new_chat_member
149 return not t.ChatMemberStatus.is_chat_admin(old.status) and t.ChatMemberStatus.is_chat_admin(new.status)
150
151 @staticmethod
152 def restrict_admin(upd: t.ChatMemberUpdated):
153 old = upd.old_chat_member
154 new = upd.new_chat_member
155 return t.ChatMemberStatus.is_chat_admin(old.status) and not t.ChatMemberStatus.is_chat_admin(new.status)