git reimport

This commit is contained in:
2019-03-15 15:02:19 +04:00
commit 742797309a
90 changed files with 4411 additions and 0 deletions

86
src/zvk/plugins/vk/api.py Normal file
View File

@@ -0,0 +1,86 @@
from __future__ import annotations
import asyncio
from zvk.util.network import Network
from zvk.util.zlogging import logger
# BOT_MESSAGE_RANDOM_ID_MIN = 1337000000
# BOT_MESSAGE_RANDOM_ID_MAX = 1338000000
API_VERSION = '5.85'
class MagicAccumulatingAttributeCatcher:
api: VKApi
full_method_name: str
def __init__(self, api, full_method_name=None):
self.api = api
if full_method_name is None:
full_method_name = ''
self.full_method_name = full_method_name
def __getattr__(self, item):
return MagicAccumulatingAttributeCatcher(self.api, f'{self.full_method_name}.{item}')
async def __call__(self, **kwargs):
return await self.api.call_method(self.full_method_name, **kwargs)
API_CALL_RETRY_COUNT = 3
class VKApi:
"""
VK api asynchronous interaction interface. Supports dope syntax like
`await api.messages.get()`.
"""
_access_token: str
_net: Network
def __init__(self, config, net):
self._access_token = config['api']['access_token']
self._net = net
def __getattr__(self, name):
return MagicAccumulatingAttributeCatcher(self, name)
async def call_method(self, full_method_name, **params):
url = f'https://api.vk.com/method/{full_method_name}'
params['access_token'] = self._access_token
params['v'] = API_VERSION
# TODO: random_id management
# if self.name == 'messages.send' and 'random_id' not in params:
# params['random_id'] = random.randint(BOT_MESSAGE_RANDOM_ID_MIN, BOT_MESSAGE_RANDOM_ID_MAX)
# if self.name == 'messages.send' and 'message' in params:
# params['message'] = params['message'].replace('--', '--')
# filter empty values
params = {k: v for k, v in params.items() if v is not None}
for retry in range(API_CALL_RETRY_COUNT):
response, result = await self._net.post_json(url, sequential=True, data=params)
if 'error' in result:
error = result['error']
if error['error_code'] == 6:
logger.warning('Too many requests, waiting and retrying...')
await asyncio.sleep(1)
continue
raise RuntimeError(f'A significant VKApi error occurred {full_method_name}({params}) -> {error}')
if 'response' not in result:
raise RuntimeError(f'Malformed api response {full_method_name}({params}) -> {result}')
logger.debug(f'VKApi call {full_method_name}({params}) -> {result}')
return result['response']
raise RuntimeError(f'VKApi call unsuccessful after retries: {full_method_name}({params})')