1
# -*- coding: utf-8 -*-
5
@author: Sergey Prokhorov <root@seriyps.ru>
7
from gwibber.microblog import network
8
from gwibber.microblog.util import log
12
class vkException(Exception):
14
def __init__(self, code, msg, url, response):
17
self.response=response
19
Exception.__init__(self, code, msg, url, response)
23
"""Vkontakte.ru (vk.com) API wrapper for Gwibber
26
api=vk_api(access_token)
27
"access_token" can be retrieved from call to http://api.vkontakte.ru/oauth/authorize
28
(see http://vkontakte.ru/developers.php?o=-1&p=%C0%E2%F2%EE%F0%E8%E7%E0%F6%E8%FF%20%EA%EB%E8%E5%ED%F2%F1%EA%E8%F5%20%EF%F0%E8%EB%EE%E6%E5%ED%E8%E9)
29
Make calls to simple methods (has no dots in name, like "getProfiles", "isAppUser"):
30
res=api.method(arg_name1=arg1, arg_name2=arg2)
31
eg res=api.getProfiles(uids="535397,1", fields="uid,first_name,last_name")
32
Make calls to namespaced methods (has dots in name, like "wall.post", "newsfeed.get"):
33
res=api.namespace.method(arg_name1=arg1, arg_name2=arg2)
34
eg res=api.wall.post(message="New wall post from API")
35
Alternative call syntax (better performance):
36
res=api._load('namespace.method', arg_name1=arg1, arg_name2=arg2)
37
eg res=api._get('wall.post', message="New wall post from API")
40
api_url='https://api.vkontakte.ru/method/%s'
42
def __init__(self, access_token):
43
self._access_token=access_token
46
def _load(self, method, **params):
47
"""Make call by method name and arguments"""
48
params["access_token"]=self._access_token
49
url=self.api_url%method
50
for _i in xrange(3):#this cycle used for API error #6 "Too many requests"
51
log.logger.debug("Perform API request to method %s. URL: %s?%s", method, url, urllib.urlencode(params))
52
res=network.Download(url, params, False).get_json()
53
if not res.has_key("error"):
54
#log.logger.debug("%s"%res)
57
if res["error"]["error_code"]!=6:
59
log.logging.warning('Error #6 "%s". Wait 0.5s and retry...', res["error"]["error_msg"])
60
'''if we get error #6 "Too many requests per second" (vk allow
61
max 3rps http://vkontakte.ru/developers.php?o=-1&p=%D0%92%D0%B7%D0%B0%D0%B8%D0%BC%D0%BE%D0%B4%D0%B5%D0%B9%D1%81%D1%82%D0%B2%D0%B8%D0%B5+%D0%BF%D1%80%D0%B8%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F+%D1%81+API )
62
try to sleep with small delay and retry request not more then 3x times'''
63
time.sleep(0.5)#TODO: play with sleep value
64
raise vkException(res["error"]["error_code"],
65
res["error"]["error_msg"],
66
"%s?%s"%(url, urllib.urlencode(params)),
70
"""Support for api.namespace.method(**kwargs) calls below"""
71
def __getattr__(self, name):
72
self._prefix.append(name)
75
def __call__(self, **kwargs):
77
method=".".join(self._prefix)
80
method=kwargs.pop("method")
81
return self._load(method, **kwargs)