рд▓рд╛рдкрддрд╛ рд╣реЛрдиреЗ рдХреА рдЬрд╛рдирдХрд╛рд░реА рдХреЗ рд▓рд┐рдП рд╕рд╣рдкрд╛рдард┐рдпреЛрдВ рд╕реЗ рд▓рдЧрд╛рддрд╛рд░ рдкреВрдЫрдиреЗ рдореЗрдВ рд╢рд░реНрдо рдорд╣рд╕реВрд╕ рдХрд░рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдПрдХ рд╕рд░рд▓ рдХрд╣рд╛рдиреА рдФрд░ рдореИрдВрдиреЗ рдЕрдкрдиреЗ рдЬреАрд╡рди рдХреЛ рдереЛрдбрд╝рд╛ рдЖрд╕рд╛рди рдмрдирд╛рдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ред

рдореЗрд░рд╛ рдорд╛рдирдирд╛ тАЛтАЛрд╣реИ рдХрд┐ рдореЗрд░реЗ рдХрдИ рд╕рд╛рдереА рдЙрд╕ рд╕реНрдерд┐рддрд┐ рд╕реЗ рдкрд░рд┐рдЪрд┐рдд рд╣реИрдВ рдЬрдм рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рдЪреИрдЯ рд░реВрдо рдореЗрдВ, рдЬрд╣рд╛рдВ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдЬрд╛рдирдХрд╛рд░реА рдХрд╛рдлреА рдмрд╛рд░ рдЪрдордХрддреА рд╣реИ, рд▓рдЧрднрдЧ 30 рд╕рдХреНрд░рд┐рдп рд╡рд╛рд░реНрддрд╛рдХрд╛рд░ рд╣реИрдВ рдЬреЛ рдЕрдкрдиреЗ рд╕рдВрджреЗрд╢реЛрдВ рдХреЗ рд╕рд╛рде VKontakte рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЛ рд▓рдЧрд╛рддрд╛рд░ рд▓реЛрдб рдХрд░рддреЗ рд╣реИрдВред рдРрд╕реА рд╢рд░реНрддреЛрдВ рдХреЗ рддрд╣рдд, рдпрд╣ рд╕рдВрднрд╛рд╡рдирд╛ рдирд╣реАрдВ рд╣реИ рдХрд┐ рд╣рд░ рдХреЛрдИ рдЗрд╕ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдЬрд╛рдирдХрд╛рд░реА рдХреЛ рджреЗрдЦреЗрдЧрд╛ред рдореЗрд░реЗ рд╕рд╛рде рднреА рдРрд╕рд╛ рд╣реЛрддрд╛ рд╣реИред рдПрдХ рд╕рд╛рд▓ рдкрд╣рд▓реЗ рдЗрд╕ рдЧрд▓рддрдлрд╣рдореА рдХреЛ рдареАрдХ рдХрд░рдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред
рдЬреЛ рд▓реЛрдЧ рдмреЙрдЯ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдЧрд▓реЗ рд▓реЗрдЦ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрддрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рдирд╣реАрдВ рд╣реИрдВ, рдореИрдВ рдмрд┐рд▓реНрд▓реА рдХреЗ рдиреАрдЪреЗ рдкреВрдЫрддрд╛ рд╣реВрдВред
рдЪреВрдВрдХрд┐ рдореИрдВ рдкреНрд░рдердо рд╢реНрд░реЗрдгреА рдХрд╛ рдЫрд╛рддреНрд░ рд╣реВрдВ, рдЗрд╕рд▓рд┐рдП рдЙрджрд╛рд╣рд░рдг рдЗрд╕ рд╡рд┐рд╖рдп рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рд╣реЛрдВрдЧреЗред
рдЗрд╕рд▓рд┐рдП, рдПрдХ рдХрд╛рд░реНрдп рд╣реИ: рдореБрдЦрд┐рдпрд╛ рд╕реЗ рдЫрд╛рддреНрд░реЛрдВ рдХреЗ рд▓рд┐рдП рдЬрд╛рдирдХрд╛рд░реА рдХреЗ рд╣рд╕реНрддрд╛рдВрддрд░рдг рдХреЛ рдореБрдЦрд┐рдпрд╛ рдФрд░ рдЫрд╛рддреНрд░реЛрдВ рджреЛрдиреЛрдВ рдХреЗ рд▓рд┐рдП рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдмрдирд╛рдирд╛ред Vkontakte рдХреА рдЕрдкреЗрдХреНрд╖рд╛рдХреГрдд рдирдИ рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж (рдЕрд░реНрдерд╛рддреН, рд╕рдореБрджрд╛рдпреЛрдВ рд╕реЗ рд╡реНрдпрдХреНрддрд┐рдЧрдд рд╕рдВрджреЗрд╢), рдирд┐рд░реНрдгрдп рдиреЗ рддреБрд░рдВрдд рдореЗрд░реА рдЖрдВрдЦ рдХреЛ рдкрдХрдбрд╝ рд▓рд┐рдпрд╛ред рдПрдХ рд╕рдореВрд╣ рдореЗрдВ рдмреИрдареЗ рдПрдХ рдмреЙрдЯ рдХреЛ рдмрдбрд╝реЗ (рдмрдбрд╝реЛрдВ, рдпрджрд┐ рдзрд╛рд░рд╛ рдкрд░ рдХрдИ рд╕рдореВрд╣ рд╣реИрдВ) рд╕реЗ рд╕рдВрджреЗрд╢ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП рдФрд░ рдЙрдиреНрд╣реЗрдВ рдЗрдЪреНрдЫреБрдХ рдкрд╛рд░реНрдЯрд┐рдпреЛрдВ (рдЫрд╛рддреНрд░реЛрдВ) рдХреЛ рднреЗрдЬрдирд╛ рдЪрд╛рд╣рд┐рдПред
рдХрд╛рд░реНрдп рдирд┐рд░реНрдзрд╛рд░рд┐рдд рд╣реИ, рдЖрдЧреЗ рдмрдврд╝реЗрдВред
рд╣рдореЗрдВ рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА:
- vk_api vk api рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд▓рд╛рдЗрдмреНрд░реЗрд░реА
- рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП peewee orm
- рдФрд░ рдЕрдЬрдЧрд░ рдореЗрдВ рдирд┐рд░реНрдорд┐рдд рдореЙрдбреНрдпреВрд▓
рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдкрдврд╝рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рдореИрдВ "рдСрдмреНрдЬрд░реНрд╡рд░" ( рд╣реИрдмрд░ , рд╡рд┐рдХреА ) рдФрд░ " рдлреЗрд╕рдбреЗ " ( рд╣реИрдмрд░ , рд╡рд┐рдХреА ) рдкреИрдЯрд░реНрди рдХреА рдпрд╛рдж рдХреЛ рддрд╛рдЬрд╝рд╛ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рд╕реНрддрд╛рд╡ рдХрд░рддрд╛ рд╣реВрдВред
рднрд╛рдЧ 1. "рдЖрдкрд╕реЗ рдорд┐рд▓рдХрд░ рдЕрдЪреНрдЫрд╛ рд▓рдЧрд╛, рдХреЙрдорд░реЗрдб рдмреЙрдЯред"
рдкрд╣рд▓реЗ рдЖрдкрдХреЛ рдЦреБрдж рдХреЛ рд╕рдореБрджрд╛рдп рдХреЗ рд░реВрдк рдореЗрдВ рд╕рдордЭрдиреЗ рдХреЗ рд▓рд┐рдП рд╣рдорд╛рд░реЗ рдмреЙрдЯ рдХреЛ рд╕рд┐рдЦрд╛рдирд╛ рд╣реЛрдЧрд╛ред рдЧреНрд░реБрдк рдирд╛рдордХ рдПрдХ рдХреНрд▓рд╛рд╕ рдмрдирд╛рдПрдВред рддрд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ, рдЗрд╕реЗ рд╕рддреНрд░ рдСрдмреНрдЬреЗрдХреНрдЯ рдФрд░ рдбреЗрдЯрд╛рдмреЗрд╕ рдкреНрд░рддрд┐рдирд┐рдзрд┐ рдСрдмреНрдЬреЗрдХреНрдЯ (рдкреНрд░реЙрдХреНрд╕реА) рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рдиреЗ рджреЗрдВред
class Group(BaseCommunicateVK): def __init__(self, vksession, storage): super().__init__(vksession) self.storage = storage
BaseCommunicateVK? рд╡рд╣рд╛рдБ рдХреНрдпрд╛ рд╣реИ?рдЗрд╕ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЛ рдПрдХ рдЕрд▓рдЧ рд╡рд░реНрдЧ рдореЗрдВ рд░рдЦрдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рдЗрд╕ рддрдереНрдп рд╕реЗ рд╕рдордЭрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ рдХрд┐ рднрд╡рд┐рд╖реНрдп рдореЗрдВ, рд╢рд╛рдпрдж, рдЖрдк рдореЗрдВ рд╕реЗ рдХреБрдЫ рдмреЛрдЯ рдХреЛ рдХреБрдЫ рдЕрдиреНрдп Vkontakte рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЗ рд╕рд╛рде рдкреВрд░рдХ рдХрд░рдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рд▓реЗрдВрдЧреЗред
рдЦреИрд░, рд╕рдореБрджрд╛рдп рдХреЗ рдЕрдореВрд░реНрдд рдЙрддрд╛рд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗред
class BaseCommunicateVK: longpoll = None def __init__(self, vksession): self.session = vksession self.api = vksession.get_api() if BaseCommunicateVK.longpoll is None: BaseCommunicateVK.longpoll = VkLongPoll(self.session) def get_api(self): return self.api def get_longpoll(self): return self.longpoll def method(self, func, args): return self.api.method(func, args) @staticmethod def create_session(token=None, login=None, password=None, api_v='5.85'): try: if token: session = vk_api.VkApi(token=token, api_version=api_v) elif login and password: session = vk_api.VkApi(login, password, api_version=api_v) else: raise vk_api.AuthError("Define login and password or token.") return session except vk_api.ApiError as error: logging.info(error) def get_last_message(self, user_id): return self.api.messages.getHistory( peer_id=user_id, count=1)["items"][0] @staticmethod def get_attachments(last_message): if not last_message or "attachments" not in last_message: return "" attachments = last_message["attachments"] attach_strings = [] for attach in attachments: attach_type = attach["type"] attach_info = attach[attach_type] attach_id = attach_info["id"] attach_owner_id = attach_info["owner_id"] if "access_key" in attach_info: access_key = attach_info["access_key"] attach_string = "{}{}_{}_{}".format(attach_type, attach_owner_id, attach_id, access_key) else: attach_string = "{}{}_{}".format(attach_type, attach_owner_id, attach_id) attach_strings.append(attach_string) return ",".join(attach_strings) @staticmethod def get_forwards(attachments, last_message): if not attachments or "fwd_count" not in attachments: return "" if len(last_message["fwd_messages"]) == int(attachments["fwd_count"]): return last_message["id"] def send(self, user_id, message, attachments=None, **kwargs): send_to = int(user_id) if "last_message" in kwargs: last_message = kwargs["last_message"] else: last_message = None p_attachments = self.get_attachments(last_message) p_forward = self.get_forwards(attachments, last_message) if message or p_attachments or p_forward: self.api.messages.send( user_id=send_to, message=message, attachment=p_attachments, forward_messages=p_forward) if destroy: accept_msg_id = self.api.messages \ .getHistory(peer_id=user_id, count=1) \ .get('items')[0].get('id') self.delete(accept_msg_id, destroy_type=destroy_type) def delete(self, msg_id, destroy_type=1): self.api.messages.delete(message_id=msg_id, delete_for_all=destroy_type)
рд╕рдореБрджрд╛рдп рдХреЗ рд╕рджрд╕реНрдпреЛрдВ рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд┐рдзрд┐ рдмрдирд╛рдПрдВред рддреБрд░рдВрдд рдЙрдиреНрд╣реЗрдВ рдкреНрд░рд╢рд╛рд╕рдХреЛрдВ рдФрд░ рдкреНрд░рддрд┐рднрд╛рдЧрд┐рдпреЛрдВ рдореЗрдВ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░реЗрдВ рдФрд░ рдЙрдиреНрд╣реЗрдВ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рд╕рд╣реЗрдЬреЗрдВред
- рд╕рдореВрд╣ рдЖрдзрд╛рд░ рд╡рд░реНрдЧ (BaseCommunicateVK) рдмрдирд╛рддреЗ рд╕рдордп self.api рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ
def update_members(self): fields = 'domain, sex' admins = self.api.groups.getMembers(group_id=self.group_id, fields=fields, filter='managers') self.save_members(self._configure_users(admins)) members = self.api.groups.getMembers(group_id=self.group_id, fields=fields) self.save_members(self._configure_users(members)) return self def save_members(self, members): self.storage.update(members) @staticmethod def _configure_users(items, exclude=None): if exclude is None: exclude = [] users = [] for user in items.get('items'): if user.get('id') not in exclude: member = User() member.configure(**user) users.append(member) return users
рдпрд╣ рд╡рд░реНрдЧ рдкреНрд░рд╛рдкреНрддрдХрд░реНрддрд╛рдУрдВ рдХреЛ рд╕рдВрджреЗрд╢ рднреЗрдЬрдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП, рдЗрд╕рд▓рд┐рдП рд╕реНрдЯреВрдбрд┐рдпреЛ рдореЗрдВ рдЕрдЧрд▓реА рд╡рд┐рдзрд┐ред рдорд╛рдкрджрдВрдбреЛрдВ рдореЗрдВ: рдореЗрд▓рд┐рдВрдЧ рд╕реВрдЪреА, рд╕рдВрджреЗрд╢ рдкрд╛рда рдФрд░ рдЕрдиреБрдкреНрд░рдпреЛрдЧред рдпрд╣ рдкреВрд░реА рдмрд╛рдд рдПрдХ рдЕрд▓рдЧ рдзрд╛рдЧреЗ рдореЗрдВ рд╢реБрд░реВ рд╣реЛрддреА рд╣реИ рддрд╛рдХрд┐ рдмреЙрдЯ рдЕрдиреНрдп рдкреНрд░рддрд┐рднрд╛рдЧрд┐рдпреЛрдВ рд╕реЗ рд╕рдВрджреЗрд╢ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХреЗред
рд╕рдВрджреЗрд╢ рддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдореЛрдб рдореЗрдВ рдкреНрд░рд╛рдкреНрдд рд╣реЛрддреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рд╕рдХреНрд░рд┐рдп рдЧреНрд░рд╛рд╣рдХреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рд╡реГрджреНрдзрд┐ рдХреЗ рд╕рд╛рде, рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХреА рдЧрддрд┐ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдХрдо рд╣реЛ рдЬрд╛рдПрдЧреАред
def broadcast(self, uids, message, attachments=None, **kwargs): report = BroadcastReport() def send_all(): users_ids = uids if not isinstance(users_ids, list): users_ids = list(users_ids) report.should_be_sent = len(users_ids) for user_id in users_ids: try: self.send(user_id, message, attachments, **kwargs) if message or attachments: report.sent += 1 except vk_api.VkApiError as error: report.errors.append('vk.com/id{}: {}'.format(user_id, error)) except ValueError: continue for uid in self.get_member_ids(admins=True, moders=True): self.send(uid, str(report)) broadcast_thread = Thread(target=send_all) broadcast_thread.start() broadcast_thread.join()
рдмреНрд░реЙрдбрдХрд╛рд╕реНрдЯрдкреЛрд░реНрдЯ - рд░рд┐рдкреЛрд░реНрдЯ рд╡рд░реНрдЧ class BroadcastReport: def __init__(self): self.should_be_sent = 0 self.sent = 0 self.errors = [] def __str__(self): res = "# #" res += "\n: {} ".format(self.should_be_sent) res += "\n: {} ".format(self.sent) if self.errors: res += "\n:" for i in self.errors: res += "\n- {}".format(i) return res
рдЗрд╕ рдкрд░, рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ, рд╕рдореВрд╣ рдХрд╛ рдЕрдореВрд░реНрддрддрд╛ рдЦрддреНрдо рд╣реЛ рдЧрдпрд╛ рд╣реИред рд╣рдо рд╕рдореБрджрд╛рдп рдХреЗ рд╕рднреА рд╕рджрд╕реНрдпреЛрдВ рдХреЗ рд╕рд╛рде рдорд┐рд▓реЗ, рдЕрдм рд╣рдореЗрдВ рдпрд╣ рдЬрд╛рдирдиреЗ рдХреА рдЬрд░реВрд░рдд рд╣реИ рдХрд┐ рдЙрдиреНрд╣реЗрдВ рдХреИрд╕реЗ рд╕рдордЭрд╛ рдЬрд╛рдПред
рднрд╛рдЧ 2. "Psh ... рд╕реНрд╡рд╛рдЧрдд .."
рдмреЙрдЯ рдХреЛ рд╣рдорд╛рд░реЗ рд╕рдореБрджрд╛рдп рдХреЗ рд╕рджрд╕реНрдпреЛрдВ рдХреЗ рд╕рднреА рд╕рдВрджреЗрд╢ рд╕реБрдирдиреЗ рджреЗрдВред
рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдПрдХ рд╡рд░реНрдЧ рдЪреИрдЯрд╣реИрдВрдбрд▓рд░ рдмрдирд╛рдПрдВ, рдЬреЛ рдпрд╣ рдХрд░реЗрдЧрд╛
рдорд╛рдкрджрдВрдбреЛрдВ рдореЗрдВ:
- group_manager рдЙрд╕ рд╕рд╛рдореБрджрд╛рдпрд┐рдХ рд╡рд░реНрдЧ рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рд╣реИ рдЬрд┐рд╕реЗ рд╣рдордиреЗ рдЕрднреА рд▓рд┐рдЦрд╛ рд╣реИ
- command_observer рдЬреБрдбрд╝реЗ рд╣реБрдП рдХрдорд╛рдВрдб рдХреЛ рдкрд╣рдЪрд╛рдирддрд╛ рд╣реИ (рд▓реЗрдХрд┐рди рддреАрд╕рд░реЗ рднрд╛рдЧ рдореЗрдВ рдЙрд╕ рдкрд░ рдФрд░ рдЕрдзрд┐рдХ)
class ChatHandler(Handler): def __init__(self, group_manager, command_observer): super().__init__() self.longpoll = group_manager.get_longpoll() self.group = group_manager self.api = group_manager.get_api() self.command_observer = command_observer
рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рд╣рдо рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рд╕реЗ рд╕рдВрджреЗрд╢ рд╕реБрдирддреЗ рд╣реИрдВ рдФрд░ рдХрдорд╛рдВрдб рдХреЛ рдкрд╣рдЪрд╛рдирддреЗ рд╣реИрдВред
def listen(self): try: for event in self.longpoll.listen(): if event.user_id and event.type == VkEventType.MESSAGE_NEW and event.to_me: self.group.api.messages.markAsRead(peer_id=event.user_id) self.handle(event.user_id, event.text, event.attachments, message_id=event.message_id) except ConnectionError: logging.error("I HAVE BEEN DOWNED AT {}".format(datetime.datetime.today())) self.longpoll.update_longpoll_server() def handle(self, user_id, message, attachments, **kwargs): member = self.group.get_member(user_id) self.group.update_members() self.command_observer.execute(member, message, attachments, self.group, **kwargs) def run(self): self.listen()
рднрд╛рдЧ 3. "рдЖрдкрдиреЗ рдореЗрд░реЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреНрдпрд╛ рд▓рд┐рдЦрд╛ рд╣реИ ..?"
рдХрдорд╛рдВрдб рдорд╛рдиреНрдпрддрд╛ рдХреЛ рдСрдмреНрдЬрд░реНрд╡рд░ рдкреИрдЯрд░реНрди рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдПрдХ рдЕрд▓рдЧ рд╕рдмрд╕рд┐рд╕реНрдЯрдо рджреНрд╡рд╛рд░рд╛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рдзреНрдпрд╛рди рджреЗрдВ:
class CommandObserver(AbstractObserver): def execute(self, member, message, attachments, group, **kwargs): for command in self.commands: for trigger in command.triggers: body = command.get_body(trigger, message) if body is not None: group.api.messages.setActivity(user_id=member.id, type="typing") if command.system: kwargs.update({"trigger": trigger, "commands": self.commands}) else: kwargs.update({"trigger": trigger}) return command.proceed(member, body, attachments, group, **kwargs)
AbstractObserverрдлрд┐рд░ рд╕реЗ, рднрд╡рд┐рд╖реНрдп рдХреЗ рд╡рд┐рд╕реНрддрд╛рд░ рдХреЗ рд▓рд┐рдП рдкреНрд░рддрд┐рдкрд╛рджрди рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
class AbstractObserver(metaclass=ABCMeta): def __init__(self): self.commands = [] def add(self, *args): for arg in args: self.commands.append(arg) @abstractmethod def execute(self, *args, **kwargs): pass
рд▓реЗрдХрд┐рди рдпрд╣ рдкреНрд░реЗрдХреНрд╖рдХ рдХреНрдпрд╛ рдкрд╣рдЪрд╛рди рдкрд╛рдПрдЧрд╛?
рддреЛ рд╣рдореЗрдВ рд╕рдмрд╕реЗ рджрд┐рд▓рдЪрд╕реНрдк рд╣рд┐рд╕реНрд╕рд╛ рдорд┐рд▓рд╛ - рдЯреАрдоред
рдкреНрд░рддреНрдпреЗрдХ рдЯреАрдо рдПрдХ рд╕реНрд╡рддрдВрддреНрд░ рд╡рд░реНрдЧ рд╣реИ, рдЬреЛ рдмреЗрд╕ рдХрдорд╛рдВрдб рдХреНрд▓рд╛рд╕ рдХрд╛ рд╡рдВрд╢рдЬ рд╣реИред
рдпрджрд┐ рдХрдорд╛рдВрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЗ рд╕рдВрджреЗрд╢ рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ рдкрд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдХрдорд╛рдВрдб рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдХрдорд╛рдВрдб рдХреАрд╡рд░реНрдб рдХрдорд╛рдВрдб рдХреНрд▓рд╛рд╕ рдХреЗ рдЯреНрд░рд┐рдЧрд░реНрд╕ рд╡реЗрд░рд┐рдПрдмрд▓ рдореЗрдВ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ (рд╕реНрдЯреНрд░рд┐рдВрдЧ рдпрд╛ рд╕реНрдЯреНрд░рд┐рдВрдЧреНрд╕ рдХреА рд╕реВрдЪреА)
class Command(metaclass=ABCMeta): def __init__(self): self.triggers = [] self.description = "Empty description." self.system = False self.privilege = False self.activate_times = [] self.activate_days = set() self.autostart_func = self.proceed def proceed(self, member, message, attachments, group, **kwargs): raise NotImplementedError() @staticmethod def get_body(kw, message): if not isinstance(kw, list): kw = [kw, ] for i in kw: reg = '^ *(\\{}) *'.format(i) if re.search(reg, message): return re.sub(reg, '', message).strip(' ')
рдЬреИрд╕рд╛ рдХрд┐ рдХрд╛рд░реНрдпрд╡рд╛рд╣реА () рд╡рд┐рдзрд┐ рдХреЗ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рд╕реЗ рджреЗрдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдкреНрд░рддреНрдпреЗрдХ рдХрдорд╛рдВрдб рдХреЛ рд╕рдореВрд╣ рдХреЗ рд╕рджрд╕реНрдп рдХреЗ рдЙрджрд╛рд╣рд░рдг, рдЙрд╕рдХреЗ рд╕рдВрджреЗрд╢ (рдмрд┐рдирд╛ рдХреАрд╡рд░реНрдб), рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдФрд░ рд╕рдореВрд╣ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдВрдХ рдХрд╛ рд▓рд┐рдВрдХ рдкреНрд░рд╛рдкреНрдд рд╣реЛрддрд╛ рд╣реИред рдпрд╣реА рд╣реИ, рдПрдХ рд╕рдореВрд╣ рдХреЗ рд╕рджрд╕реНрдп рдХреЗ рд╕рд╛рде рд╕рднреА рдмрд╛рддрдЪреАрдд рдЯреАрдо рдХреЗ рд╕рд╛рде рдЯрд┐рдХреА рд╣реБрдИ рд╣реИред рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рд╕рдмрд╕реЗ рд╕рд╣реА рд╕рдорд╛рдзрд╛рди рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдЗрд╕ рддрд░рд╣ рд╕реЗ рдЕрдзрд┐рдХ рдЕрдиреНрддрд░рдХреНрд░рд┐рдпрд╛рд╢реАрд▓рддрд╛ рдХреЗ рд▓рд┐рдП рдПрдХ рд╢реЗрд▓ (рд╢реЗрд▓) рдмрдирд╛рдирд╛ рд╕рдВрднрд╡ рд╣реИред
(рд╕рдЪ рдореЗрдВ, рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдпрд╛ рддреЛ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдЬреЛрдбрд╝рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА, рдХреНрдпреЛрдВрдХрд┐ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рд╕рд┐рдВрдХреНрд░реЛрдирд╕ рд╣реИ, рдпрд╛ рдкреНрд░рддреНрдпреЗрдХ рдкреНрд░рд╛рдкреНрдд рд╕рдВрджреЗрд╢ рдХреЛ рдПрдХ рдирдП рдзрд╛рдЧреЗ рдореЗрдВ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП, рдЬреЛ рд╕рднреА рд▓рд╛рднрджрд╛рдпрдХ рдирд╣реАрдВ рд╣реИ)
рдЖрджреЗрд╢реЛрдВ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рдЙрджрд╛рд╣рд░рдг:
BroadcastCommand class BroadcastCommand(Command): def __init__(self): super().__init__() self.triggers = ['.mb'] self.privilege = True self.description = " ." def proceed(self, member, message, attachments, group, **kwargs): if member.id not in group.get_member_ids(admins=True, editors=True): group.send(member.id, "You cannot do this ^_^") return True last_message = group.get_last_message(member.id) group.broadcast(group.get_member_ids(), message, attachments, last_message=last_message, **kwargs) return True
HelpCommand class HelpCommand(Command): def __init__(self): super().__init__() self.commands = [] self.triggers = ['.h', '.help'] self.system = True self.description = " ." def proceed(self, member, message, attachments, group, **kwargs): commands = kwargs["commands"] help = " :\n\n" admins = group.get_member_ids(admins=True, moders=True) i = 0 for command in commands: if command.privilege and member.id not in admins: continue help += "{}) {}\n\n".format(i + 1, command.name()) i += 1 group.send(member.id, help) return True
рднрд╛рдЧ 4. "рд╣рдо рдПрдХ рдмрдбрд╝реА рдЯреАрдо рд╣реИрдВред"
рдЕрдм рдЗрди рд╕рднреА рдореЙрдбреНрдпреВрд▓ рдФрд░ рд╣реИрдВрдбрд▓рд░ рдХреЛ рд╕рдВрдпреБрдХреНрдд рдФрд░ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред
рдПрдХ рдФрд░ рд╡рд░реНрдЧ рдХреГрдкрдпрд╛!
рдПрдХ рдореБрдЦреМрдЯрд╛ рдмрдирд╛рдПрдБ рдЬреЛ рд╣рдорд╛рд░реЗ рдмреЙрдЯ рдХреЛ рдЕрдиреБрдХреВрд▓рд┐рдд рдХрд░реЗрдЧрд╛ред
class VKManage: def __init__(self, token=None, login=None, password=None): self.session = BaseCommunicateVK.create_session(token, login, password, api_version) self.storage = DBProxy(DatabaseORM) self.group = Group(self.session, self.storage).setup().update_members() self.chat = ChatHandler(self.group, CommandObserver.get_observer()) def start(self): self.chat.run() def get_command(self, command_name): return { " ": BroadcastCommand(), " ": AdminBroadcastCommand(), "": HelpCommand(), " ": SkippedLectionsCommand(), "": TopicTimetableCommand().setup_account(self.bot.api), }.get(command_name) def connect_command(self, command_name): command = self.get_command(str(command_name).lower()) if command: self.chat.command_observer.add(command) return self def connect_commands(self, command_names): for i in command_names.split(','): self.connect_command(i.strip()) return self
рдЖрдЦрд┐рд░реА рдЪрд░рдг рд▓реЙрдиреНрдЪ рд╣реИред рд╣рдореЗрд╢рд╛ рд╕рдмрд╕реЗ рдЧрдВрджрд╛, рдХреНрдпреЛрдВрдХрд┐ рдХрд┐рд╕реА рддрд░рд╣ рдХрд╛ рдЖрд╢реНрдЪрд░реНрдп рд╕рд╛рдордиреЗ рдЖ рд╕рдХрддрд╛ рд╣реИред рдЗрд╕ рдмрд╛рд░ рдирд╣реАрдВред
- ConfigParser рдХреЛ core.settings.ConfigParser рд╕реЗ рдЖрдпрд╛рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдпрд╣ рд╕рд┐рд░реНрдл рд╡рд┐рдиреНрдпрд╛рд╕ рдкрдврд╝рддрд╛ рд╣реИред
project_path рдХреЛ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рд░реВрдЯ рдореЗрдВ рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рдореЙрдбреНрдпреВрд▓ рд╕реЗ рдЖрдпрд╛рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
if __name__ == '__main__': config = ConfigParser(project_path) VKManage(token=config['token'], login=config['login'], password=config['password'])\ .connect_commands(", , , ")\ .start()
рд╡рд╣ рд╕рдм рдорд╛рд▓реВрдо рд╣реЛрддрд╛ рд╣реИред
рдлрд┐рд▓рд╣рд╛рд▓, рдЗрд╕ рдХрд╛рд░реНрдпрдХреНрд░рдо рд╕реЗ рдХрдо рд╕реЗ рдХрдо рддреАрди рд╕рдореВрд╣реЛрдВ рдХреЛ рдлрд╛рдпрджрд╛ рд╣реБрдЖ рд╣реИ рдФрд░ рдореБрдЭреЗ рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рдЖрдк рднреА рдЗрд╕реЗ рд▓рд╛рдПрдВрдЧреЗред
рдЖрдк рдЗрд╕реЗ рд╣рд░реЛрдХреВ рдкрд░ рдореБрдлреНрдд рдореЗрдВ рддреИрдирд╛рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдпрд╣ рдПрдХ рдФрд░ рдХрд╣рд╛рдиреА рд╣реИред
рд╕рдВрджрд░реНрдн: