# -*- coding: utf-8 -*- """ this is a patched version of vk_api to use a different user agent for authenticating against VK. Everything else looks the same, the only change in the module is the new user agent, emulating a kate mobile session.""" import time import hashlib import logging import vk_api import threading import requests from . import jconfig_patched as jconfig from vk_api.enums import VkUserPermissions from vk_api.exceptions import * DEFAULT_USER_SCOPE = sum(VkUserPermissions) class VkApi(vk_api.VkApi): def __init__(self, login=None, password=None, token=None, auth_handler=None, captcha_handler=None, config=jconfig.Config, config_filename='vk_config.v2.json', api_version='5.101', app_id=2685278, scope=DEFAULT_USER_SCOPE, client_secret='lxhD8OD7dMsqtXIm5IUY'): self.login = login self.password = password self.token = {'access_token': token} self.api_version = api_version self.app_id = app_id self.scope = scope self.client_secret = client_secret self.storage = config(self.login, filename=config_filename) self.http = requests.Session() self.http.headers.update({'User-agent': 'VKAndroidApp/5.23-2978 (Android 4.4.2; SDK 19; x86; unknown Android SDK built for x86; en; 320x240)'}) self.last_request = 0.0 self.error_handlers = { NEED_VALIDATION_CODE: self.need_validation_handler, CAPTCHA_ERROR_CODE: captcha_handler or self.captcha_handler, TOO_MANY_RPS_CODE: self.too_many_rps_handler, TWOFACTOR_CODE: auth_handler or self.auth_handler } self.lock = threading.Lock() self.logger = logging.getLogger('vk_api_patched') self.logger.info('Started patched VK API client...') def method(self, method, values=None, captcha_sid=None, captcha_key=None, raw=False): """ Вызов метода API :param method: название метода :type method: str :param values: параметры :type values: dict :param captcha_sid: id капчи :type captcha_key: int or str :param captcha_key: ответ капчи :type captcha_key: str :param raw: при False возвращает `response['response']` при True возвращает `response` (может понадобиться для метода execute для получения execute_errors) :type raw: bool """ values = values.copy() if values else {} if 'v' not in values: values['v'] = self.api_version if self.token: values['access_token'] = self.token['access_token'] if captcha_sid and captcha_key: values['captcha_sid'] = captcha_sid values['captcha_key'] = captcha_key with self.lock: # Ограничение 3 запроса в секунду delay = self.RPS_DELAY - (time.time() - self.last_request) if delay > 0: time.sleep(delay) values.update(https=1) response = self.http.post( 'https://api.vk.com/method/' + method, values ) self.last_request = time.time() if response.ok: response = response.json() else: error = ApiHttpError(self, method, values, raw, response) response = self.http_handler(error) if response is not None: return response raise error if 'error' in response: error = ApiError(self, method, values, raw, response['error']) if error.code in self.error_handlers: if error.code == CAPTCHA_ERROR_CODE: error = Captcha( self, error.error['captcha_sid'], self.method, (method,), {'values': values, 'raw': raw}, error.error['captcha_img'] ) response = self.error_handlers[error.code](error) if response is not None: return response raise error return response if raw else response['response']