Exemple #1
0
 def _listen_long_poll(cls):
     long_poll = VkLongPoll(cls._sess)
     while True:
         try:
             yield from long_poll.listen()
         except Exception as e:
             logging.exception(e)
             long_poll.update_longpoll_server()
Exemple #2
0
class EventHandler:

    def __init__(self):
        super().__init__()
        self._longpoll = None
        self.admin_kw = '/mdr'
        self.members_kw = '/all'
        self._locked_users = []
        self._broadcast_queue = deque()
        self._dialogs_in_thread = []
        self._notifyer_thread = None

    def set_group(self, api):
        self._group = api
        self._set_longpoll(self._group.get_api())

    def _set_longpoll(self, group_api):
        self._longpoll = VkLongPoll(group_api)

    def set_command_observer(self, api):
        self._observer = api

    def set_command_checker(self, api):
        self._checker = api

    def lock_user(self, user_id):
        if user_id not in self._locked_users:
            self._locked_users.append(user_id)

    def unlock_user(self, user_id):
        self._locked_users.remove(user_id)

    def listen(self):
        self._notifyer_thread = Thread(target=self._checker.execute)
        self._notifyer_thread.start()
        try:
            for event in self._longpoll.listen():
                if event.user_id not in self._locked_users and event.type == VkEventType.MESSAGE_NEW and event.to_me:
                    self._group.get_api().method('messages.markAsRead', {'peer_id': event.user_id})
                    self.handle_event(event.user_id, event.text, event.attachments)
        except ConnectionError:
            import datetime
            print("I HAD BEEN DOWNED IN {}".format(datetime.datetime.today()))
            self._longpoll.update_longpoll_server()
            pass

    def handle_event(self, user_id, message, attachments):
        def search(kw):
            reg = '^/*{}'.format(kw)
            exist = re.search(reg, message)
            return exist

        def sub(kw):
            reg = '^/*{}'.format(kw)
            msg = re.sub(reg, '', message)
            return msg

        admins_ids = self._group.get_member_ids(admins=True)
        destination = []
        if user_id in admins_ids:
            destination = []
            if search(self.admin_kw):
                destination = admins_ids
                message = sub(self.admin_kw)
            elif search(self.members_kw):
                destination = self._group.get_member_ids()
                message = sub(self.members_kw)

        if destination:
            broadcast = Thread(target=self._group.broadcast, args=(destination, message, attachments))
            self._broadcast_queue.append(broadcast)

        else:
            member = self._group.get_member(user_id)
            # self.lock_user(member.id)
            response = self._observer.execute(member, message, unlock=self.unlock_user)
            if response:
                self._group.get_api().method('messages.setActivity', {
                    'user_id': user_id,
                    'type': 'typing'
                })
                self._group.send(user_id, response, attachments)
Exemple #3
0
def main(longpoll=None):
    try:
        """ Пример использования longpoll
            https://vk.com/dev/using_longpoll
            https://vk.com/dev/using_longpoll_2
        """

        #login, password = '', ''
        #vk_session = vk_api.VkApi(login, password)
        print("Запускаю новую сессию!")
        token = settings.vk_token
        vk_session = vk_api.VkApi(token = token)
        vk_user_session = vk_api.VkApi(token = settings.vk_user_token)
        vk_empty_session = vk_api.VkApi()

        try:
            vk_session.auth()
        except vk_api.AuthError as error_msg:
            print(error_msg)
            return
        if longpoll == None:
            longpoll = VkLongPoll(vk_session)
        else:
            longpoll.update_longpoll_server()

        for event in longpoll.listen():
            try:
                if event.type == VkEventType.MESSAGE_NEW:
                    print('Новое сообщение:')

                    if event.from_me:
                        print('От меня для: ', end='')
                    elif event.to_me:
                        print('Для меня от: ', end='')

                    if event.from_user:
                        print(event.user_id)
                        if int(event.user_id) == 57008075:
                            reg = r'(id)?(\d*)? ?([^$]+)'
                            parser=re.compile(reg)
                            answer = parser.sub(r'\2', str(event.text))
                            if answer != "":
                                answer = parser.sub(r'\2', str(event.text))
                                try:
                                    if parser.sub(r'\3', str(event.text)) != "":
                                        write_msg(int(answer), parser.sub(r'\3', str(event.text)), vk_session)
                                    else:
                                        write_msg(int(answer), u".", vk_session)
                                except Exception as e:
                                    print(e)
                                user_name = vk_empty_session.method('users.get', {'user_id':int(answer)})
                                write_msg(57008075, u'Сообщение отправлено пользователю [id' + str(answer) + u'|' + 
                                    str(user_name[0]["first_name"]) + " " + str(user_name[0]["last_name"]) + 
                                    ']', vk_session)
                                continue;
                    elif event.from_chat:
                        print(event.user_id, 'в беседе', event.chat_id)
                    elif event.from_group:
                        print('группы', event.group_id)
                    try:
                        print('Текст: ', event.text)
                    except Exception as e:
                        print(e)
                    print()
                    if not event.from_me:
                        user_name = vk_empty_session.method('users.get', {'user_id':int(event.user_id)})
                        write_msg(57008075, u'[id' + str(event.user_id) + u'|' + 
                            str(user_name[0]["first_name"]) + " " + 
                            str(user_name[0]["last_name"]) +'] написал: ' + 
                            str(event.text) + '\nОтветить: https://vk.com/gim90818758?sel=' + 
                            str(event.user_id) + "\nОтветить через чат: id" + str(event.user_id), vk_session, event.raw[1])
                        #write_msg(int(event.user_id), u'Ваше сообщение переслано администратору сообщества! ;-)\nОн ответит Вам в ближайшее время.\nВ группе тестируеться бот, просим прощение за неудобства.', vk_session)

                elif event.type == VkEventType.USER_TYPING:
                    print('Печатает ', end='')

                    if event.from_user:
                        print(event.user_id)
                    elif event.from_group:
                        print('администратор группы', event.group_id)

                elif event.type == VkEventType.USER_TYPING_IN_CHAT:
                    print('Печатает ', event.user_id, 'в беседе', event.chat_id)

                elif event.type == VkEventType.USER_ONLINE:
                    print('Пользователь', event.user_id, 'онлайн', event.platform)

                elif event.type == VkEventType.USER_OFFLINE:
                    print('Пользователь', event.user_id, 'оффлайн', event.offline_type)

                else:
                    print(event.type, event.raw[1:])
            except requests.exceptions.ReadTimeout as e:
                print(e)
                time.sleep(10)
            except requests.packages.urllib3.exceptions.ReadTimeoutError as e:
                print(e)
                longpoll.update_longpoll_server()
    except Exception as e:
        print(e)
        time.sleep(10)
        main(longpoll)
Exemple #4
0
def main(developing=False, longpoll=None):
    """Описание главного файла программы

    Этот файл планируеться как основной стартовый модуль бота, который
    будет манипулировать файлом динамических настроек бота. На этой
    стадии файл динамических настроек включает такие переменные: 
    users_token: тип данных dict - используеться для хранения
    временных токенов пользователей (планируеться использовать токены
    с временем жизни в 1 час), которые, в свою очередь, подтверждрают
    наличие у пользователя прав администратора.

    """
    if developing:
        print(
            "Я запущен в режиме разработчика. Делай со мной все что хочешь :-)"
        )
        print("Подключаем базу данных")
        db_connector = sqlite3.connect(settings.db_name)
        print("База данных успешно подключена")
        print("Инициализируем курсор")
        db_cursor = db_connector.cursor()
        print("Курсор готов")
        # Работа с базой данных
        user_command = 'найдите'
        db_cursor.execute(
            "SELECT * FROM command WHERE new_command='" + \
                user_command + "';"
        )
        # print(db_cursor.fetchall())
        db_result = db_cursor.fetchall()
        if db_result:
            print(db_result[0][0])
        else:
            db_cursor.execute("SELECT * FROM command")
            db_result = db_cursor.fetchall()
            max_ratio = ["item", "user_command", 0]
            for item in db_result:
                s = SequenceMatcher(lambda x: x == " ", item[1], user_command)
                if max_ratio[2] < s.ratio():
                    max_ratio[0] = (item[0], item[1])
                    max_ratio[1] = user_command
                    max_ratio[2] = s.ratio()
                print("Ratio: " + item[1] + " and " + user_command + \
                    ": " + str(s.ratio()))
            print("Max ratio: " + str(max_ratio[0]) + " and " + max_ratio[1] + \
                ": " + str(max_ratio[2]))
            if max_ratio[2] >= 0.7 and len(max_ratio[1]) > 3:
                db_cursor.execute("INSERT INTO command (standart_command," + \
                    " new_command) VALUES ('" + max_ratio[0][0] + "', '" + \
                    max_ratio[1] + "');"
                )
                db_connector.commit()
                print("Спасибо, я выучил кое-что новое ;-)")
        # print(db_cursor.fetchall()[0][0])
        #----------------------
        print("Отключаем базу данных")
        db_connector.close()
    try:
        dyn_sett_dict = {}  #Словарь динамических настроек
        commands = {}  #Словарь команд
        rexp_commands = {}  #Словарь регулярных команд
        interfaces = {}  #Словарь интерфейсов
        vk = vk_api.VkApi(token=settings.vk_token)
        dynamic_settings = DynamicSettings(
            dynamic_settings_filename=settings.dynamic_settings_file)
        if (dynamic_settings.file_created()):
            dyn_sett_dict = dynamic_settings.get()
        else:
            dyn_sett_dict = generate_standart_dynamic_setting()
            dynamic_settings.set(dyn_sett_dict)

        try:
            vk.auth()
        except vk_api.AuthError as error_msg:
            print(error_msg)
            return

        vk_service = vk_api.VkApi(token=settings.service_key)
        try:
            vk_service.auth()
        except vk_api.AuthError as error_msg:
            print(error_msg)
            return

        print('Подгружаем интерфейсы...')

        print('---------------------------')

        # Подгружаем плагины
        sys.path.insert(0, settings.path)
        for f in os.listdir(settings.path):
            fname, ext = os.path.splitext(f)
            if ext == '.py':
                mod = __import__(fname)
                interfaces[fname] = mod.Interface(vk, vk_service,
                                                  dynamic_settings)
        sys.path.pop(0)

        # Регистрируем ключевые слова интерфейсов
        for interface in interfaces.values():
            for key, value in interface.get_keys().items():
                commands[key] = value

        #print(commands)

        # Регистрируем регулярные слова интерфейсов
        for interface in interfaces.values():
            for key, value in interface.get_rexp().items():
                rexp_commands[key] = value

        #print(rexp_commands)

        print('---------------------------')
        print('Интерфейсы загружены')

        #print(commands)
        #print(rexp_commands)
        print('Запускаем постоянное считывание ленты сообщений...')
        if longpoll == None:
            longpoll = VkLongPoll(vk)
        else:
            longpoll.update_longpoll_server()
        print('Считывание ленты запущено.')
        for event in longpoll.listen():
            if event.type == VkEventType.MESSAGE_NEW:
                print('Новое сообщение:')
                if event.to_me:
                    print('Для меня от: ', end='')
                    print(str(event.user_id))
                    if not_sticker(vk, event):
                        command(event, commands, rexp_commands, vk)
                elif event.from_me:
                    print('От меня для: ', end='')
                    print(str(event.user_id))

                try:
                    print('Текст: ', event.text)
                except UnicodeEncodeError as e:
                    print(e)
                except KeyboardInterrupt:
                    print("Процесс бота завершен пользователем!")
                    raise
                except Exception as e:
                    print(e)
                    raise
                print()
            else:
                print(event.type, event.raw[1:])
    except Exception as e:
        print(e)
        time.sleep(10)
        main(developing=developing, longpoll=longpoll)