Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.idea
build
dist
src/*.egg-info
src/*.egg-info
__pycache__
27 changes: 27 additions & 0 deletions example/example_captcha.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
from __future__ import print_function

try:
import vkaudiotoken
except ImportError:
import path_hack

from vkaudiotoken import get_kate_token, get_vk_official_token, TokenException
import sys

login = sys.argv[1]
password = sys.argv[2]
# for 2 factor authentication with sms
auth_code = sys.argv[3] if len(sys.argv) > 3 else 'GET_CODE'

captcha_sid = None
captcha_key = None
while True:
try:
print(get_kate_token(login, password, auth_code, captcha_sid, captcha_key))
break
except TokenException as err:
if err.code == TokenException.CAPTCHA_REQ and 'captcha_sid' in err.extra:
captcha_sid = err.extra['captcha_sid']
captcha_key = input("Enter captcha key from image (" + err.extra["captcha_img"] + "): ")
else:
raise
8 changes: 8 additions & 0 deletions src/vkaudiotoken/CommonParams.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,14 @@ def get_two_factor_part(self, code=None):
('force_sms', 1)
] + [] if code == 'GET_CODE' else [('code', code)]

def get_captcha(self, captcha_sid=None, captcha_key=None):
if captcha_sid is None or captcha_key is None:
return []
return [
('captcha_sid', captcha_sid),
('captcha_key', captcha_key)
]

def generate_random_string(self, length, characters):
return ''.join(random.choice(characters) for _ in range(length))

Expand Down
4 changes: 4 additions & 0 deletions src/vkaudiotoken/TokenException.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ class TokenException(Exception):
REQUEST_ERR = 3
TWOFA_REQ = 4
TWOFA_ERR = 5
CAPTCHA_REQ = 6

@property
def extra(self):
Expand Down Expand Up @@ -37,3 +38,6 @@ def __init__(self, code, extra=None):
elif code == TokenException.TWOFA_ERR:
super(TokenException, self).__init__(
"2FA Error. Code: {0}. Error extra: {1}".format(code, extrastr))
elif code == TokenException.CAPTCHA_REQ:
super(TokenException, self).__init__(
"Captcha needed. Code: {0}. Error extra: {1}".format(code, extrastr))
30 changes: 18 additions & 12 deletions src/vkaudiotoken/TokenReceiver.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@


class TokenReceiver:
def __init__(self, login, password, auth_data, params, auth_code=None, scope='audio,offline'):
def __init__(self, login, password, auth_data, params, auth_code=None, captcha_sid=None, captcha_key=None, scope='audio,offline'):
self._params = params
self._login = login
self._password = password
self._auth_code = auth_code
self._auth_data = auth_data
self._captcha_sid = captcha_sid
self._captcha_key = captcha_key
self._scope = scope
self._client = KATE

Expand Down Expand Up @@ -61,17 +63,21 @@ def _get_non_refreshed(self):
self._params.set_common_vk(session)
dec = session.get('https://oauth.vk.com/token',
params=[
('grant_type', 'password'),
('client_id', self._client.client_id),
('client_secret', self._client.client_secret),
('username', self._login),
('password', self._password),
('v', '5.95'),
('lang', 'en'),
('scope', self._scope)
] + self._params.get_two_factor_part(self._auth_code)).json()
if 'error' in dec and dec['error'] == 'need_validation':
raise TokenException(TokenException.TWOFA_REQ, dec)
('grant_type', 'password'),
('client_id', self._client.client_id),
('client_secret', self._client.client_secret),
('username', self._login),
('password', self._password),
('v', '5.95'),
('lang', 'en'),
('scope', self._scope)
] + self._params.get_two_factor_part(self._auth_code)
+ self._params.get_captcha(self._captcha_sid, self._captcha_key)).json()
if 'error' in dec:
if dec['error'] == 'need_validation':
raise TokenException(TokenException.TWOFA_REQ, dec)
if dec['error'] == 'need_captcha':
raise TokenException(TokenException.CAPTCHA_REQ, dec)
if 'user_id' not in dec:
raise TokenException(TokenException.TOKEN_NOT_RECEIVED, dec)
return dec['access_token']
Expand Down
32 changes: 19 additions & 13 deletions src/vkaudiotoken/TokenReceiverOfficial.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@


class TokenReceiverOfficial:
def __init__(self, login, password, params, auth_code=None, scope='all'):
def __init__(self, login, password, params, auth_code=None, captcha_sid=None, captcha_key=None, scope='all'):
self._login = login
self._password = password
self._params = params
self._auth_code = auth_code
self._captcha_sid = captcha_sid
self._captcha_key = captcha_key
self._scope = scope
self._client = VK_OFFICIAL

Expand All @@ -21,19 +23,23 @@ def _get_non_refreshed(self):
device_id = self._params.generate_random_string(16, '0123456789abcdef')
dec = session.get('https://oauth.vk.com/token',
params=[
('grant_type', 'password'),
('client_id', self._client.client_id),
('client_secret', self._client.client_secret),
('username', self._login),
('password', self._password),
('v', '5.116'),
('lang', 'en'),
('scope', self._scope),
('device_id', device_id)
] + self._params.get_two_factor_part(self._auth_code)).json()
('grant_type', 'password'),
('client_id', self._client.client_id),
('client_secret', self._client.client_secret),
('username', self._login),
('password', self._password),
('v', '5.116'),
('lang', 'en'),
('scope', self._scope),
('device_id', device_id)
] + self._params.get_two_factor_part(self._auth_code)
+ self._params.get_captcha(self._captcha_sid, self._captcha_key)).json()

if 'error' in dec and dec['error'] == 'need_validation':
raise TokenException(TokenException.TWOFA_REQ, dec)
if 'error' in dec:
if dec['error'] == 'need_validation':
raise TokenException(TokenException.TWOFA_REQ, dec)
if dec['error'] == 'need_captcha':
raise TokenException(TokenException.CAPTCHA_REQ, dec)
if 'user_id' not in dec:
raise TokenException(TokenException.TOKEN_NOT_RECEIVED, dec)
return {'access_token': dec['access_token']}
8 changes: 4 additions & 4 deletions src/vkaudiotoken/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from . import supported_clients


def get_kate_token(login, password, auth_code='GET_CODE', non_refreshed_token=None):
def get_kate_token(login, password, auth_code='GET_CODE', captcha_sid=None, captcha_key=None, non_refreshed_token=None):
params = CommonParams(supported_clients.KATE.user_agent)
protobuf_helper = SmallProtobufHelper()

Expand All @@ -22,13 +22,13 @@ def get_kate_token(login, password, auth_code='GET_CODE', non_refreshed_token=No
mtalkClient = MTalkClient(auth_data, protobuf_helper)
mtalkClient.send_request()

receiver = TokenReceiver(login, password, auth_data, params, auth_code)
receiver = TokenReceiver(login, password, auth_data, params, auth_code, captcha_sid, captcha_key)
return {'token': receiver.get_token(non_refreshed_token), 'user_agent': supported_clients.KATE.user_agent}


def get_vk_official_token(login, password, auth_code='GET_CODE'):
def get_vk_official_token(login, password, auth_code='GET_CODE', captcha_sid=None, captcha_key=None):
params = CommonParams(supported_clients.VK_OFFICIAL.user_agent)
receiver = TokenReceiverOfficial(login, password, params, auth_code)
receiver = TokenReceiverOfficial(login, password, params, auth_code, captcha_sid, captcha_key)

return {
'token': receiver.get_token()['access_token'],
Expand Down