def starter(bot): for group in config.sections()[1:]: poster.updater(bot, group, config.getint(group, 'last_id')) log.info('Очистка кэша') for data in listdir('.'): remove(data) log.info('Переход в режим сна')
def generate_music(self): if 'attachments' in self.post: log.info('[AP] Извлечение аудио...') log.info('[AP] Данная функция находится в стадии тестирования.') n = 0 session.http.cookies.update(dict(remixmdevice=self.remixmdevice)) user_id = api_vk.users.get()[0]['id'] for attachment in self.post['attachments']: if attachment['type'] == 'audio': post_url = 'https://m.vk.com/wall%(owner_id)s_%(id)s' % self.post soup = BeautifulSoup(session.http.get(post_url).text, 'html.parser') track_list = [decode_audio_url(track.get('value'), user_id) for track in soup.find_all(type='hidden') if 'mp3' in track.get('value')] dur_list = [dur.get('data-dur') for dur in soup.find_all('div') if dur.get('data-dur')] name = sub(r"[/\"?:|<>*]", '', attachment['audio']['artist'] + ' - ' + attachment['audio']['title'] + '.mp3') try: file = download(track_list[n], out=name) except urllib.error.URLError: continue try: music = EasyID3(file) except id3.ID3NoHeaderError: music = File(file, easy=True) music.add_tags() music['title'] = attachment['audio']['title'] music['artist'] = attachment['audio']['artist'] music.save() del music self.tracks.append((name, dur_list[n])) n += 1
def generate_videos(self): if 'attachments' in self.post: log.info('[AP] Извлечение видео...') log.info( '[AP] Данная функция находится в стадии тестирования. В некоторых видео может быть только звук, а может вообще не запуститься.' ) for attachment in self.post['attachments']: if attachment['type'] == 'video': video = 'https://m.vk.com/video%(owner_id)s_%(id)s' % attachment[ 'video'] soup = BeautifulSoup( session.http.get(video).text, 'html.parser') if soup.find_all('source'): file = download(soup.find_all('source')[1].get('src')) if getsize(file) > 20971520: del file continue self.videos.append(file) elif soup.iframe: video_id = self.regex.findall( soup.iframe['src'])[0].split('/')[3] yt = YouTube(self.youtube_link + video_id) for stream in yt.streams.all(): if stream.filesize <= 20971520 and ( '.mp4' in stream.default_filename): file = stream.default_filename stream.download() self.videos.append(file) break
def stop(bot, update): if str(config.get('global', 'admin')) == str(update.message.from_user.id): global job_status if job_status: if job_status.enabled: job_status.enabled = False update.message.reply_text('Бот остановлен.', quote=True) log.info('Stopping a job_status...')
def generate_post(self): log.info('[AP] Начало извлечения содержимого поста...') self.generate_user() self.generate_text() self.generate_photos() self.generate_docs() self.generate_videos() self.generate_music()
def send_post(bot, domain, post): log.info("[TG] Отправка поста...") if post.text: if post.photos: pass else: bot.sendMessage(chat_id=config.get(domain, 'channel'), text=post.text, parse_mode='HTML', disable_web_page_preview=True) if post.photos: # noinspection PyBroadException try: if post.text: if len(post.photos) == 1 and len(post.text) < 200: bot.sendPhoto(chat_id=config.get(domain, 'channel'), photo=post.photos[0]['media'], caption=post.text, parse_mode='HTML') else: bot.sendMessage(chat_id=config.get(domain, 'channel'), text=post.text, parse_mode='HTML', disable_web_page_preview=True) bot.sendMediaGroup(chat_id=config.get(domain, 'channel'), media=post.photos) else: bot.sendMediaGroup(chat_id=config.get(domain, 'channel'), media=post.photos) except Exception: log.warning('[TG] Невозможно отправить фото: {0}.'.format( sys.exc_info()[1])) for m in post.videos: try: bot.sendVideo(chat_id=config.get(domain, 'channel'), video=open(m, 'rb'), timeout=60) except Exception: pass for m in post.docs: bot.sendDocument(chat_id=config.get(domain, 'channel'), document=open(m, 'rb'), timeout=60) for (m, n) in post.tracks: try: if getsize(m) > 52428800: remove(m) else: try: bot.sendAudio(chat_id=config.get(domain, 'channel'), audio=open(m, 'rb'), duration=int(n), timeout=60) except: pass remove(m) except FileNotFoundError: continue
def is_admin(bot, update): if update.message.text == config.get('global', 'bot_token'): if config.get('global', 'admin') != update.message.from_user.id: update_parameter('global', 'admin', update.message.from_user.id) log.info('[TG] Установлен администратор бота с ID {0}'.format( update.message.from_user.id)) update.message.reply_text( 'Доступ получен.\n\nКоманда просмотра всех доступных команд: /help' )
def generate_docs(self): if 'attachments' in self.post: log.info('[AP] Извлечение вложениий (файлы, гифки и т.п.)...') for attachment in self.post['attachments']: if attachment['type'] == 'doc' and attachment['doc']['size'] < 52428800: try: doc = download(attachment['doc']['url'], out='file' + '.' + attachment['doc']['ext']) self.docs.append(doc) except urllib.error.URLError: log.warn('[AP] Невозможно скачать вложенный файл: {0}.'.format(sys.exc_info()[1]))
def run(bot, update): if str(config.get('global', 'admin')) == str(update.message.from_user.id): try: global job_status if job_status: if job_status.enabled: return 0 job_status = job_queue.run_repeating(job_repeated, interval=5 * 60, first=0) log.info('Running a job_status...') update.message.reply_text('Бот запущен', quote=True) except Exception: log.info('Got an error while running a job_status: %s.' % sys.exc_info()[0]) update.message.reply_text('Не удалось запустить бота: {}'.format(sys.exc_info()[1]), quote=True)
def generate_photos(self): if 'attachments' in self.post: log.info('[AP] Извлечение фото...') for attachment in self.post['attachments']: if attachment['type'] == 'photo': photo = attachment['photo']['photo_75'] try: photo = attachment['photo']['photo_130'] photo = attachment['photo']['photo_604'] photo = attachment['photo']['photo_807'] photo = attachment['photo']['photo_1280'] photo = attachment['photo']['photo_2560'] except KeyError: pass # self.photos.append({'media': open(download(photo), 'rb'), 'type': 'photo'}) self.photos.append(InputMediaPhoto(photo))
def updater(bot, domain, last_id): log.info('[VK] Проверка на наличие новых постов в {0} с последним ID {1}'.format(domain, last_id)) posts = get_data(domain) for post in reversed(posts): if post['id'] > last_id: log.info("[VK] Обнаружен новый пост с ID {0}".format(post['id'])) new_post = Post(post, domain) new_post.generate_post() send_post(bot, domain, new_post) last_id = update_parameter(domain, 'last_id', post['id']) time.sleep(5) if post['id'] == last_id: log.info('[VK] Новых постов больше не обнаружено') log.info('[VK] Проверка завершена, last_id = {0}.'.format(last_id))
def generate_text(self): if self.post['text']: log.info('[AP] Обнаружен текст. Извлечение...') self.text = self.post['text'] self.text = self.text.replace(self.pattern, '') if 'attachments' in self.post: for attachment in self.post['attachments']: if attachment['type'] == 'link': self.text += '\n<a href="%(url)s">%(title)s</a>' % attachment[ 'link'] # self.text += '\n[%(title)s](%(url)s)' % attachment['link'] if config.getboolean('global', 'sign') and self.user: log.info( '[AP] Подписывание поста и добавление ссылки на его оригинал.' ) # Markdown Parsing # self.text += '\nАвтор поста: [%(first_name)s %(last_name)s](https://vk.com/%(domain)s)' % self.user # self.text += '\nОригинал поста: [ссылка](https://vk.com/wall%(owner_id)s_%(id)s)' % self.post # HTML Parsing self.text += '\nАвтор поста: <a href="https://vk.com/%(domain)s">%(first_name)s %(last_name)s</a>' % self.user self.text += '\nОригинал поста: <a href="https://vk.com/wall%(owner_id)s_%(id)s">ссылка</a>' % self.post elif config.getboolean('global', 'sign') and not self.user: log.info( '[AP] Добавление только ссылки на оригинал поста, так как в нем не указан автор.' ) # Markdown Parsing # self.text += '\nОригинал поста: [ссылка](https://vk.com/wall%(owner_id)s_%(id)s)' % self.post # HTML Parsing self.text += '\nОригинал поста: <a href="https://vk.com/wall%(owner_id)s_%(id)s">ссылка</a>' % self.post
def update_parameter(section, name, num) -> int: config.set(section, name, str(num)) with open('../config.ini', 'w', encoding='utf-8') as f: config.write(f) return num def remove_section(section: str) -> tuple: channel = config.get(section, 'channel') last_id = config.get(section, 'last_id') config.remove_section(section) with open('../config.ini', 'w', encoding='utf-8') as f: config.write(f) return section, channel, last_id def add_section(domain, chat_id, last_id='0', *args): config.add_section(domain) config.set(domain, 'channel', chat_id) config.set(domain, 'last_id', last_id) with open('../config.ini', 'w', encoding='utf-8') as f: config.write(f) return domain, chat_id, last_id log.info('Запуск') log.info('Авторизация на сервере ВК') setting(config.get('global', 'login'), config.get('global', 'pass'))