Skip to content

Commit

Permalink
Merge branch 'DjHaski-patch-1'
Browse files Browse the repository at this point in the history
  • Loading branch information
Fahreeve committed Jul 15, 2018
2 parents 4a34771 + d1201f3 commit d039cdb
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 23 deletions.
4 changes: 4 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,10 @@ Supports both variants like API object

Long Poll
---------
**UserLongPoll** - for User Long Poll API. See https://vk.com/dev/using_longpoll

**BotsLongPoll** - for Bots Long Poll API. See https://vk.com/dev/bots_longpoll

Use exist API object

.. code-block:: python
Expand Down
2 changes: 1 addition & 1 deletion aiovk/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
__version__ = '2.1.1'
__version__ = '2.2.0'

from aiovk.sessions import ImplicitSession, TokenSession, AuthorizationCodeSession
from aiovk.api import API
Expand Down
101 changes: 80 additions & 21 deletions aiovk/longpoll.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,32 @@
import json
from abc import ABC, abstractmethod

from aiovk import API
from aiovk.api import LazyAPI
from aiovk.exceptions import VkLongPollError


class LongPoll:
def __init__(self, session_or_api, mode, wait=25, version=1, timeout=None):
if type(session_or_api) == API:
class BaseLongPoll(ABC):
"""Interface for all types of Longpoll API"""
def __init__(self, session_or_api, mode: int or list, wait: int=25, version: int=2, timeout: int=None):
"""
:param session_or_api: session object or data for creating a new session
:type session_or_api: BaseSession or API or LazyAPI
:param mode: additional answer options
:param wait: waiting period
:param version: protocol version
:param timeout: timeout for *.getLongPollServer request in current session
"""
if isinstance(session_or_api, (API, LazyAPI)):
self.api = session_or_api
else:
self.api = API(session_or_api)

self.timeout = timeout or self.api._session.timeout

if type(mode) == list:
mode = sum(mode)

self.base_params = {
'version': version,
'wait': wait,
Expand All @@ -24,48 +38,93 @@ def __init__(self, session_or_api, mode, wait=25, version=1, timeout=None):
self.key = None
self.base_url = None

async def _get_long_poll_server(self, need_pts=False):
response = await self.api('messages.getLongPollServer', need_pts=int(need_pts), timeout=self.timeout)
self.pts = response.get('pts')
self.ts = response['ts']
self.key = response['key']
self.base_url = 'https://{}'.format(response['server'])
@abstractmethod
async def _get_long_poll_server(self, need_pts: bool=False) -> None:
"""Send *.getLongPollServer request and update internal data
async def wait(self, need_pts=False):
:param need_pts: need return the pts field
"""

async def wait(self, need_pts=False) -> dict:
"""Send long poll request
:param need_pts: need return the pts field
"""
if not self.base_url:
await self._get_long_poll_server(need_pts)

params = {
'ts': self.ts,
'key': self.key,
}
params.update(self.base_params)
# invalid mymetype from server
code, response = await self.api._session.driver.get_text(self.base_url, params, timeout=2 * self.base_params['wait'])
# invalid mimetype from server
code, response = await self.api._session.driver.get_text(
self.base_url, params,
timeout=2 * self.base_params['wait']
)

if code == 403:
raise VkLongPollError(403,
'smth weth wrong',
self.base_url + '/',
params
)
raise VkLongPollError(403, 'smth weth wrong', self.base_url + '/', params)

response = json.loads(response)
failed = response.get('failed')

if not failed:
self.ts = response['ts']
return response

if failed == 1:
self.ts = response['ts']
elif failed == 4:
raise VkLongPollError(4,
'An invalid version number was passed in the version parameter',
self.base_url + '/',
params)
raise VkLongPollError(
4,
'An invalid version number was passed in the version parameter',
self.base_url + '/',
params
)
else:
self.base_url = None

return await self.wait()

async def get_pts(self, need_ts=False):
if not self.base_url or not self.pts:
await self._get_long_poll_server(need_pts=True)

if need_ts:
return self.pts, self.ts
return self.pts


class UserLongPoll(BaseLongPoll):
"""Implements https://vk.com/dev/using_longpoll"""

async def _get_long_poll_server(self, need_pts=False):
response = await self.api('messages.getLongPollServer', need_pts=int(need_pts), timeout=self.timeout)
self.pts = response.get('pts')
self.ts = response['ts']
self.key = response['key']
# fucking differences between long poll methods in vk api!
self.base_url = 'https://{}'.format(response['server'])


class LongPoll(UserLongPoll):
"""Implements https://vk.com/dev/using_longpoll
This class for backward compatibility
"""


class BotsLongPoll(BaseLongPoll):
"""Implements https://vk.com/dev/bots_longpoll"""
def __init__(self, session_or_api, mode, group_id, wait=25, version=1, timeout=None):
super().__init__(session_or_api, mode, wait, version, timeout)
self.group_id = group_id

async def _get_long_poll_server(self, need_pts=False):
response = await self.api('groups.getLongPollServer', group_id=self.group_id)
self.pts = response.get('pts')
self.ts = response['ts']
self.key = response['key']
self.base_url = '{}'.format(response['server']) # Method already returning url with https://
2 changes: 1 addition & 1 deletion aiovk/sessions.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ async def send_api_request(self, method_name: str, params: dict = None, timeout:


class TokenSession(BaseSession):
"""Implements simple session that ues existed token for work"""
"""Implements simple session that uses existed token for work"""

API_VERSION = '5.74'
REQUEST_URL = 'https://api.vk.com/method/'
Expand Down

0 comments on commit d039cdb

Please sign in to comment.