Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import os
- import re
- import time
- import requests
- from urllib.parse import urlparse
- __author__ = "Sergey Sergeev <[email protected]>"
- __license__ = "GNU General Public License v. 3"
- class VkClient(object):
- """Класс для работы с API Вконтакте.
- Методы API Вконтакте можно вызывать в нативном виде:
- <object VkClient>.users.get(user_id=1)
- Параметры можно паредать в виде словаря:
- <object VkClient>.users.get({'user_id': 1})
- Оба варианта анологичны такой записи:
- <object VkClient>.api('users.get', {'user_id': 1})
- См.: http://vk.com/dev/methods
- """
- def __init__(self, apiVersion=None, accessToken=None, apiDelay=None):
- """Конструктор.
- :param apiVersion: Версия API Вконтакте. Об актуальной версии можно
- узнать тут <http://vk.com/dev>.
- :param accessToken: Токен полученный при авторизации.
- :param apiDelay: Принудительная задержка возвращения результата
- выполения метода API. Для приложений есть лимиты обращения к API
- в секунду <http://vk.com/dev/api_requests>.
- """
- self.apiVersion = apiVersion
- self.accessToken = accessToken
- self.apiDelay = apiDelay
- self.session = requests.session()
- def api(self, method, params=None):
- """Отправляет запрос к API.
- :param method: Имя метода.
- :param params: - словарь, необязательный. Параметры запроса.
- :return: Значение поля `response`.
- """
- params = dict(params) or {}
- if self.accessToken and not 'access_token' in params:
- params['access_token'] = self.accessToken
- if self.apiVersion and not 'v' in params:
- params['v'] = self.apiVersion
- if self.apiDelay:
- time.sleep(self.apiDelay)
- u = 'https://api.vk.com/method/{}'.format(method)
- r = self.session.post(u, params).json()
- if 'error' in r:
- details = r['error']
- error = VkError(details['error_msg'], details['error_code'],
- method, params, details.get('captcha_img'),
- details.get('captcha_sid'),
- details.get('redirect_uri'))
- if error.code == 14:
- return self.captchaHandler(error)
- elif error.code == 17:
- return self.validationHandler(error)
- raise error
- return r['response']
- def execute(self, code, **kw):
- kw['code'] = code
- return self.api('execute', kw)
- def captchaHandler(self, error):
- raise error
- def validationHandler(self, error):
- raise error
- def upload(self, url, files):
- """Загружает файлы на сервер.
- :param url: Адрес сервера для загрузки файлов.
- :param files: Словарь, где "имя поля" => "путь до файла"(может быть
- ссылкой). Так же можно передавать кортеж или список вида
- ("имя файла", "содержимое"). На сервере проверяется расширение
- файла, mime тип не учитывается(поэтому клиентом он не передается).
- Проверяются сигнатуры файлов
- <http://en.wikipedia.org/wiki/List_of_file_signatures> при
- загрузке изображений.
- """
- files = dict(files)
- for k, v in files.items():
- if not isinstance(v, str):
- continue
- filename = v
- if re.match('(?i)https?://', filename):
- content = self.session.get(filename).content
- # http://example.com/path/to/file?query -> path/to/file
- filename = urlparse(filename).path
- else:
- content = open(filename, 'rb').read()
- # path/to/file -> file
- filename = os.path.basename(filename)
- files[k] = (filename, content)
- r = self.session.post(url, files=files).json()
- if 'error' in r:
- raise VkError(r['error'])
- return r
- def uploadWallPhoto(self, photo, group_id=None):
- """Метод для тестирования загрузки фото на стену."""
- args = {'group_id': group_id} if group_id else {}
- u = self.photos.getWallUploadServer(args)['upload_url']
- r = self.upload(u, {'photo': photo})
- photos = self.photos.saveWallPhoto(r)
- # return "photo{owner_id}_{id}".format(**photos[0])
- return photos
- # Комплексные методы вида <namespace>.<method>.
- def __getattr__(self, name):
- if re.match('[a-z]+$', name):
- return ComplexMethod(self, name)
- class ComplexMethod(object):
- def __init__(self, client, prefix):
- self._client = client
- self._prefix = prefix
- def __getattr__(self, name):
- def wrapper(*arg, **kw):
- if len(arg) == 1 and isinstance(arg[0], dict):
- dict.update(arg[0], kw)
- kw = arg[0]
- return self._client.api(self._prefix + '.' + name, kw)
- # Имена методов должны быть в camelCase.
- if re.match('[a-z]+([A-Z][a-z]+)*$', name):
- return wrapper
- class VkError(Exception):
- def __init__(self, message=None, code=-1, method=None, params=None,
- captchaImg=None, captchaSid=None, redirectUri=None):
- Exception.__init__(self, message)
- self.code = code
- self.message = message
- self.method = method
- self.params = params
- self.captchaSid = captchaSid
- self.captchaImg = captchaImg
- self.redirectUri = redirectUri
Advertisement
Add Comment
Please, Sign In to add comment