def remove_channel(self, chat_id: int, channel_title: str): channel_info = youtube.get_channel_info(channel_title) if channel_info == 404: message = "Канал с таким названием не найден" elif channel_info == 403: message = "Что-то пошло не так. Без паники! Всем оставаться на своих местах!" else: # Получаем id ютуб канала channel_id = channel_info["id"] # Получаем id всех ютуб каналов, на которые подписана беседа mycursor.execute("SELECT * FROM Channels where chat_id = %s", (chat_id)) channel_ids = [channel[1] for channel in mycursor.fetchall()] # Если беседа не подписана на ютуб канал if channel_id not in channel_ids: message = "Как ты собрался отписаться от канала, на который не подписан? Петух" else: # Удаляем ютуб канал из подписок беседы mycursor.execute( """ DELETE FROM Channels WHERE chat_id = %s AND channel_id = %s """, (chat_id, channel_id)) db.commit() message = f"❌Вы отписались от канала {channel_title}" console_log( f"Беседа {chat_id} отписалась от канала {channel_title}") self.bot.messages.send(chat_id=chat_id, message=message, random_id=get_random_id())
def quota_exceeded(self): """ Квота превышена :( Меняем ключ для работы с api """ self.api_key = get_next(self.api_keys, self.api_key) console_log("Квота превышена :(") console_log("Меняем ключ для доступа к YouTube api")
def add_chat(self, chat_id: int): """Записываем в базу данных id новой беседы""" try: console_log(f"Бот добавлен в беседу {chat_id}") mycursor.execute("INSERT INTO Chats (id, added) VALUES (%s, %s)", (chat_id, datetime.now())) db.commit() except Exception as e: console_log("Что-то пошло не так") print(e)
def listen(self): """Начинаем прослушку всех бесед""" console_log("Бот запущен") while True: try: # Отслеживаем каждое событие в беседе for event in self.longpoll.listen(): if event.type == VkBotEventType.MESSAGE_NEW and event.from_chat: received_message = event.message["text"].lower() chat_id = event.chat_id # Если сообщение появилось из беседы и этой беседы нет в базе данных, то довабляем её id mycursor.execute("SELECT id FROM Chats") result = mycursor.fetchall() chat_ids = [chat_id[0] for chat_id in result] if chat_id not in chat_ids: self.add_chat(chat_id) # Если бота пригласили в новую беседу if "action" in event.message: if event.message["action"][ "type"] == "chat_invite_user": if event.message["action"][ "member_id"] == -int( config["group"]["group_id"]): self.add_chat(chat_id) # Пропускаем невалидные команды if received_message in ["!подписаться", "!видео"]: continue if received_message[:12] == "!подписаться": channel_title = received_message.split( " ")[1].replace(" ", "") self.add_channel(chat_id, channel_title) elif received_message == "!отписаться": self.remove_all_channels(chat_id) elif received_message[:12] == "!отписаться ": channel_title = received_message.split(" ")[1] self.remove_channel(chat_id, channel_title) elif fuzz.ratio(received_message, "!подписки") > 75: self.show_subscriptions(chat_id) elif fuzz.ratio(received_message, "!видео") > 75: video_title = received_message.split(" ")[1] self.show_video(chat_id, video_title) elif fuzz.ratio(received_message, "!помощь") > 75: self.get_help(chat_id) elif fuzz.ratio(received_message, "!топ") > 75: self.show_top_channels(chat_id) except (requests.exceptions.ReadTimeout, requests.exceptions.ConnectionError) as e: # Перезагрузка серверов ВКонтакте print(e) console_log("Перезапуск бота")
def add_channel(self, chat_id: int, channel_title: str): """Добавляет ютуб канал в подписки беседы""" channel_info = youtube.get_channel_info(channel_title) if channel_info == 404: message = "Канал с таким названием не найден" elif channel_info == 403: message = "Что-то пошло не так. Без паники! Всем оставаться на своих местах!" else: # Получаем id ютуб канала channel_id = channel_info["id"] # Выбираем из базы данных все ютуб каналы, на которые подписана беседа mycursor.execute("SELECT * FROM Channels where chat_id = %s", (chat_id)) # Составляем список из id ютуб каналов, на которые подписана беседа channel_ids = [channel[1] for channel in mycursor.fetchall()] # Если беседа уже подписана на этот ютуб канал if channel_id in channel_ids: message = f"Вы уже подписаны на этот канал" else: # Максимальное число подписок - 3 if len(channel_ids) == 3: message = f"Вы подписались на максимальное количество каналов. " \ f"Отпишитесь от другого канала, чтобы подписаться на этот канал." else: # Получаем информацию о ютуб канале channel_title = channel_info["title"] channel_photo_url = channel_info["photo_url"] last_video_id = youtube.get_last_video(channel_id) last_video_title = youtube.get_video_title(last_video_id) # Добавляем ютуб канал в подписки беседы mycursor.execute( """ INSERT INTO Channels (chat_id, channel_id, channel_title, channel_photo_url, last_video_id, last_video_title) VALUES (%s, %s, %s, %s, %s, %s) """, (chat_id, channel_id, channel_title, channel_photo_url, last_video_id, last_video_title)) db.commit() message = f"✅Вы подписались на канал {channel_title}" console_log( f"Беседа {chat_id} подписалась на канал {channel_title}" ) self.bot.messages.send(chat_id=chat_id, message=message, random_id=get_random_id())
def check_chats(self): while True: console_log("Проверка всех чатов") # Получаем id всех чатов, в которых состоит бот mycursor.execute("SELECT id FROM Chats") chat_ids = [chat[0] for chat in mycursor.fetchall()] for chat_id in chat_ids: # Составляем список из всех ютуб каналов, на которые подписана беседа mycursor.execute("SELECT * FROM Channels WHERE chat_id = %s", chat_id) channels = [channel for channel in mycursor.fetchall()] for channel in channels: channel_id = channel[1] channel_title = channel[2] last_video_id = youtube.get_last_video(channel_id) # Если на канале вышло новое видео if last_video_id != 403 and last_video_id != channel[4]: # Обновляем id последнего видео у ютуб канала last_video_id = youtube.get_last_video(channel_id) last_video_title = youtube.get_video_title( last_video_id) mycursor.execute( """ UPDATE Channels SET last_video_id = %s, last_video_title = %s WHERE chat_id = %s AND channel_id = %s """, (last_video_id, last_video_title, chat_id, channel_id)) db.commit() channel = { "channel_id": channel_id, "channel_title": channel_title, "last_video_id": last_video_id, "last_video_title": last_video_title } # Отправляем уведомление в беседу self.notification(chat_id, channel) time.sleep(3600) # Следующая проверка через час
def notification(self, chat_id: int, channel: dict): """Отправляет в беседу уведомление о выходе нового видео""" channel_id = channel["channel_id"] channel_title = channel["channel_title"] video_id = channel["last_video_id"] video_title = channel["last_video_title"] video_url = f"https://www.youtube.com/watch?v={video_id}&ab_channel={channel_id}" message = f"На канале {channel_title} вышло новое видео!" console_log(message) console_log(video_title) self.bot.messages.send(chat_id=chat_id, message=message, attachment=self.upload_video( video_url, video_title), random_id=get_random_id())
def reconnect(): """Подключаемся к базе данных""" global db, mycursor try: db.close() db = pymysql.connect(host=config["database"]["host"], user=config["database"]["user"], passwd=config["database"]["passwd"], db=config["database"]["db"]) mycursor = db.cursor() console_log("Переподключаемся к базе данных") except: """Если подключение первое""" db = pymysql.connect(host=config["database"]["host"], user=config["database"]["user"], passwd=config["database"]["passwd"], db=config["database"]["db"]) mycursor = db.cursor() console_log("Подключаемся к базе данных")
def create_tables(): """Создаём таблицы Chats и Channels, если их нет""" # Создаём таблицу с чатами, если её нет mycursor.execute(""" CREATE TABLE IF NOT EXISTS Chats( id int PRIMARY KEY, added datetime NOT NULL ) """) console_log("Таблица Chats создана") # Создаём таблицу с ютуб каналами, если её нет mycursor.execute(""" CREATE TABLE IF NOT EXISTS Channels( chat_id int, channel_id VARCHAR(50), channel_title VARCHAR(50), channel_photo_url VARCHAR(125), last_video_id VARCHAR(50), last_video_title VARCHAR(100) ) """) console_log("Таблица Channels создана")
def remove_all_channels(self, chat_id: int): """Удаляет все ютуб каналы, на которые подписана беседа""" # Получаем id всех ютуб каналов, на которые подписана беседа mycursor.execute("SELECT channel_id FROM Channels WHERE chat_id = %s", chat_id) channel_ids = [channel[0] for channel in mycursor.fetchall()] if len(channel_ids) == 0: message = "От чего ты отписываться собрался? Петух" else: # Удаляем все ютуб каналы, на которые подписана беседа mycursor.execute("DELETE FROM Channels WHERE chat_id = %s", chat_id) db.commit() message = "Вы отписались от всех каналов" console_log(f"Беседа {chat_id} отписалась от всех каналов") self.bot.messages.send(chat_id=chat_id, message=message, random_id=get_random_id())
def widget(self): """Меняет виджет каждый день""" while True: utils.set_widget() console_log("Виджет обновлён") time.sleep(86400)
def status(self): """Меняет статус каждый день""" while True: utils.set_status() console_log("Статус обновлён") time.sleep(86400)