From 5be43e8336b5aea55979ea33bca5c45830151857 Mon Sep 17 00:00:00 2001 From: Kylmakalle Date: Fri, 23 Jun 2017 01:02:13 +0300 Subject: [PATCH] Docs uploading feature, access_token stashing in redis --- .gitignore | 5 ++- bot.py | 115 +++++++++++++++++++++++++++++++++++------------------ 2 files changed, 81 insertions(+), 39 deletions(-) diff --git a/.gitignore b/.gitignore index 7ada594..3043b2e 100644 --- a/.gitignore +++ b/.gitignore @@ -139,4 +139,7 @@ $RECYCLE.BIN/ *.lnk # Bot credentials -credentials.py \ No newline at end of file +credentials.py + +# PyCharm project +.idea \ No newline at end of file diff --git a/bot.py b/bot.py index 99cbbc6..cbdd3bb 100644 --- a/bot.py +++ b/bot.py @@ -5,49 +5,64 @@ import vk import threading import re import logging +import requests +import ujson +import wget +import os import cherrypy +import redis + from credentials import token, vk_app_id, local_port logging.basicConfig(format='%(levelname)-8s [%(asctime)s] %(message)s', level=logging.WARNING, filename='vk.log') vk_threads = {} -vk_tokens = {} +FILE_URL = 'https://api.telegram.org/file/bot{0}/{1}' + +tokens_pool = redis.ConnectionPool(host='localhost', port=6379, db=0) +vk_tokens = redis.StrictRedis(connection_pool=tokens_pool) bot = telebot.AsyncTeleBot(token) bot.remove_webhook() link = 'https://oauth.vk.com/authorize?client_id={}&' \ - 'display=page&redirect_uri=https://oauth.vk.com/blank.html&scope=friends,messages,offline' \ + 'display=page&redirect_uri=https://oauth.vk.com/blank.html&scope=friends,messages,offline,docs' \ '&response_type=token&v=5.65'.format(vk_app_id) - mark = types.InlineKeyboardMarkup() yes = types.InlineKeyboardButton('ВХОД', url=link) mark.add(yes) -def create_thread(message, vk_token): +def create_thread(uid, vk_token): a = VkPolling() - t = threading.Thread(name='vk' + str(message.from_user.id), target=a.run, args=(vk_token, bot, message.chat.id,)) + t = threading.Thread(name='vk' + str(uid), target=a.run, args=(VkMessage(vk_token), bot, uid,)) t.setDaemon(True) t.start() - vk_threads[str(message.from_user.id)] = a - vk_tokens[str(message.from_user.id)] = vk_token + vk_threads[str(uid)] = a + vk_tokens.set(str(uid), vk_token) -def check_thread(message): +def check_thread(uid): for th in threading.enumerate(): - if th.getName() == 'vk' + str(message.from_user.id): + if th.getName() == 'vk' + str(uid): return False return True +# Creating VkPolling threads after bot reboot using existing tokens +for uid in vk_tokens.scan_iter(): + if check_thread(uid.decode("utf-8")): + create_thread(uid.decode("utf-8"), vk_tokens.get(uid)) + + def stop_thread(message): for th in threading.enumerate(): if th.getName() == 'vk' + str(message.from_user.id): t = vk_threads[str(message.from_user.id)] t.terminate() th.join() + vk_tokens.delete(str(message.from_user.id)) def extract_unique_code(text): @@ -71,7 +86,7 @@ def info_extractor(info): @bot.message_handler(commands=['stop']) def stop_command(message): - if not check_thread(message): + if not check_thread(message.from_user.id): stop_thread(message) bot.send_message(message.chat.id, 'Успешный выход!').wait() else: @@ -80,7 +95,7 @@ def stop_command(message): @bot.message_handler(commands=['start']) def start_command(message): - if check_thread(message): + if check_thread(message.from_user.id): bot.send_message(message.chat.id, 'Привет, этот бот поможет тебе общаться ВКонтакте, войди по кнопке ниже' ' и отправь мне то, что получишь в адресной строке.', @@ -89,32 +104,54 @@ def start_command(message): bot.send_message(message.chat.id, 'Вход уже выполнен!\n/stop для выхода.').wait() -"""def vk_sender(message, method): +def vk_sender(message, method): if message.reply_to_message: - if str(message.from_user.id) in vk_tokens: + if vk_tokens.get(str(message.from_user.id)): info = info_extractor(message.reply_to_message.entities) if info is not None: - if len(info) - 1: - method(message, info[0], False) - vk.API(vk_tokens[str(message.from_user.id)].session).messages.send(chat_id=info[1], - message=message.text) + if int(info[1]): + method(message, info[1], group=True) else: - method(message, info[0], True) - vk.API(vk_tokens[str(message.from_user.id)].session).messages.send(user_id=info[0], - message=message.text) + method(message, info[0], group=False) else: - bot.send_message(message.chat.id, 'Вход не выполнен! /start дл входа').wait() + bot.send_message(message.chat.id, 'Вход не выполнен! /start для входа').wait() -def send_audio(msg, info, private): - if private: - pass +def send_doc(message, userid, group): + session = VkMessage(vk_tokens.get(str(message.from_user.id))).session + file = wget.download( + FILE_URL.format(token, bot.get_file(message.document.file_id).wait().file_path)) + openedfile = open(file, 'rb') + files = {'file': openedfile} + fileonserver = ujson.loads(requests.post(vk.API(session).docs.getUploadServer()['upload_url'], + files=files).text) + attachment = vk.API(session).docs.save(file=fileonserver['file'], title=message.document.file_name, + tags='') + if group: + vk.API(session).messages.send(chat_id=userid, + attachment='doc{}_{}'.format(attachment[0]['owner_id'], + attachment[0]['did'])) else: - pass + vk.API(session).messages.send(user_id=userid, + attachment='doc{}_{}'.format(attachment[0]['owner_id'], + attachment[0]['did'])) + openedfile.close() + os.remove(file) -@bot.message_handler(content_types=['audio']) -def reply_audio(message): - vk_sender(message, send_audio)""" + +@bot.message_handler(content_types=['document']) +def reply_document(message): + vk_sender(message, send_doc) + """if message.reply_to_message: + if vk_tokens.get(str(message.from_user.id)): + info = info_extractor(message.reply_to_message.entities) + if info is not None: + if int(info[1]): + send_doc(message, info[1], True) + else: + send_doc(message, info[0], False) + else: + bot.send_message(message.chat.id, 'Вход не выполнен! /start для входа').wait()""" @bot.message_handler(content_types=['text']) @@ -123,10 +160,10 @@ def reply_text(message): message.text) if m: code = extract_unique_code(m.group(0)) - if check_thread(message): + if check_thread(message.from_user.id): try: verifycode(code) - create_thread(message, VkMessage(code)) + create_thread(message.from_user.id, code) bot.send_message(message.chat.id, 'Вход выполнен!').wait() bot.send_message(message.chat.id, 'Бот позволяет получать и отвечать на текстовые сообщения' ' из ВКонтакте\nПример личного сообщения:').wait() @@ -147,20 +184,22 @@ def reply_text(message): return if message.reply_to_message: - if str(message.from_user.id) in vk_tokens: + if vk_tokens.get(str(message.from_user.id)): info = info_extractor(message.reply_to_message.entities) if info is not None: - if len(info) - 1: - vk.API(vk_tokens[str(message.from_user.id)].session).messages.send(chat_id=info[1], - message=message.text) + if int(info[1]): + vk.API(VkMessage(vk_tokens.get(str(message.from_user.id))).session).messages.send( + chat_id=info[1], + message=message.text) else: - vk.API(vk_tokens[str(message.from_user.id)].session).messages.send(user_id=info[0], - message=message.text) + vk.API(VkMessage(vk_tokens.get(str(message.from_user.id))).session).messages.send( + user_id=info[0], + message=message.text) else: - bot.send_message(message.chat.id, 'Вход не выполнен! /start дл входа').wait() + bot.send_message(message.chat.id, 'Вход не выполнен! /start для входа').wait() -#bot.polling() +# bot.polling() class WebhookServer(object): # index равнозначно /, т.к. отсутствию части после ip-адреса (грубо говоря) @cherrypy.expose