Skip to content

Commit 468d758

Browse files
committed
Optimize regexp
Code formating Add ApiHttpError
1 parent 03eb1ea commit 468d758

1 file changed

Lines changed: 60 additions & 20 deletions

File tree

vk_api/vk_api.py

Lines changed: 60 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,17 @@
1616
DELAY = 0.36 # 3 requests per second
1717
CAPTCHA_ERROR_CODE = 14
1818
NEED_VALIDATION_CODE = 17
19+
HTTP_ERROR_CODE = -1
20+
21+
RE_CAPTCHAID = re.compile(r'sid=(\d+)')
22+
RE_NUMBER_HASH = re.compile(r'security_check.*?hash: \'(.*?)\'\};')
23+
RE_TOKEN_URL = re.compile(r'location\.href = "(.*?)"\+addr;')
24+
RE_PHONE_PREFIX = re.compile(r'phone_number">(.*?)<')
25+
RE_PHONE_POSTFIX = re.compile(r'phone_postfix">(.*?)<')
1926

2027

2128
class VkApi(object):
29+
2230
def __init__(self, login=None, password=None, number=None, token=None,
2331
proxies=None, captcha_handler=None, config_filename=None,
2432
api_version='5.21', app_id=2895443, scope=2097151):
@@ -116,7 +124,7 @@ def vk_login(self, captcha_sid=None, captcha_key=None):
116124
self.sid = remixsid
117125

118126
elif 'sid=' in response.url:
119-
captcha_sid = regexp(r'sid=(\d+)', response.url)[0]
127+
captcha_sid = search_re(RE_CAPTCHAID, response.url)
120128
captcha = Captcha(self, captcha_sid, self.vk_login)
121129

122130
if self.error_handlers[CAPTCHA_ERROR_CODE]:
@@ -135,22 +143,16 @@ def security_check(self, url=None, response=None):
135143
if 'security_check' not in response.url:
136144
return
137145

138-
phone_prefix = regexp(r'label ta_r">(.*?)<',
139-
response.text)
140-
phone_prefix = phone_prefix[0].strip()
141-
142-
phone_postfix = regexp(r'phone_postfix">(.*?)<',
143-
response.text)
144-
phone_postfix = phone_postfix[0].strip()
146+
phone_prefix = search_re(RE_PHONE_PREFIX, response.text).strip()
147+
phone_postfix = search_re(RE_PHONE_POSTFIX, response.text).strip()
145148

146149
if self.number:
147150
code = code_from_number(phone_prefix, phone_postfix, self.number)
148151
else:
149152
code = code_from_number(phone_prefix, phone_postfix, self.login)
150153

151154
if code:
152-
number_hash = regexp(r'security_check.*?hash: \'(.*?)\'\};',
153-
response.text)[0]
155+
number_hash = search_re(RE_NUMBER_HASH, response.text)
154156

155157
values = {
156158
'act': 'security_check',
@@ -200,7 +202,7 @@ def api_login(self):
200202
response = self.http.post(url, values)
201203

202204
if 'access_token' not in response.url:
203-
url = regexp(r'location\.href = "(.*?)"\+addr;', response.text)[0]
205+
url = search_re(RE_TOKEN_URL, response.text)
204206
response = self.http.get(url)
205207

206208
if 'access_token' in response.url:
@@ -236,6 +238,9 @@ def need_validation_handler(self, error):
236238
# TODO: write me
237239
pass
238240

241+
def http_handler(self, error):
242+
pass
243+
239244
def method(self, method, values=None, captcha_sid=None, captcha_key=None):
240245
""" Использование методов API
241246
@@ -270,16 +275,27 @@ def method(self, method, values=None, captcha_sid=None, captcha_key=None):
270275
if delay > 0:
271276
time.sleep(delay)
272277

273-
response = self.http.post(url, values).json()
278+
response = self.http.post(url, values)
274279
self.last_request = time.time()
275280

281+
if response.ok:
282+
response = response.json()
283+
else:
284+
error = ApiHttpError(self, method, values, response)
285+
response = self.http_handler(error)
286+
287+
if response is not None:
288+
return response
289+
290+
raise error
291+
276292
if 'error' in response:
277293
error = ApiError(self, method, values, response['error'])
278294
error_code = error.code
279295

280296
if error_code in self.error_handlers:
281297
if error_code == CAPTCHA_ERROR_CODE:
282-
# TODO: wtf
298+
283299
error = Captcha(
284300
self,
285301
error.error['captcha_sid'],
@@ -295,8 +311,8 @@ def method(self, method, values=None, captcha_sid=None, captcha_key=None):
295311
return response
296312

297313
raise error
298-
else:
299-
return response['response']
314+
315+
return response['response']
300316

301317

302318
def doc(method=None):
@@ -314,12 +330,13 @@ def doc(method=None):
314330
webbrowser.open(url)
315331

316332

317-
def regexp(reg, string):
333+
def search_re(reg, string):
318334
""" Поиск по регулярке """
335+
m = reg.search(string)
336+
groups = m.groups()
319337

320-
reg = re.compile(reg, re.IGNORECASE | re.DOTALL)
321-
reg = reg.findall(string)
322-
return reg
338+
if groups:
339+
return groups[0]
323340

324341

325342
def code_from_number(phone_prefix, phone_postfix, number):
@@ -330,6 +347,7 @@ def code_from_number(phone_prefix, phone_postfix, number):
330347
return
331348

332349
# Сравниваем начало номера
350+
# TODO: ignore "+" symbole
333351
if not number[:prefix_len] == phone_prefix:
334352
return
335353

@@ -349,17 +367,19 @@ class BadPassword(AuthorizationError):
349367

350368

351369
class SecurityCheck(AuthorizationError):
370+
352371
def __init__(self, phone_prefix, phone_postfix):
353372
self.phone_prefix = phone_prefix
354373
self.phone_postfix = phone_postfix
355374

356375
def __str__(self):
357-
return 'Security check. Enter number: {}...{}'.format(
376+
return 'Security check. Enter number: {} ... {}'.format(
358377
self.phone_prefix, self.phone_postfix
359378
)
360379

361380

362381
class ApiError(Exception):
382+
363383
def __init__(self, vk, method, values, error):
364384
self.vk = vk
365385
self.method = method
@@ -379,7 +399,27 @@ def __str__(self):
379399
self.error['error_msg'])
380400

381401

402+
class ApiHttpError(object):
403+
404+
def __init__(self, vk, method, values, response):
405+
self.vk = vk
406+
self.method = method
407+
self.values = values
408+
self.response = response
409+
410+
def try_method(self):
411+
""" Пробует отправить запрос заново
412+
413+
"""
414+
415+
return self.vk.method(self.method, self.values)
416+
417+
def __str__(self):
418+
return 'Response code {}'.format(self.response.status_code)
419+
420+
382421
class Captcha(Exception):
422+
383423
def __init__(self, vk, captcha_sid,
384424
func, args=None, kwargs=None, url=None):
385425
self.vk = vk

0 commit comments

Comments
 (0)