1010import sys
1111from collections import namedtuple
1212
13- from .utils import sjson_dumps
13+ from .exceptions import VkRequestsPoolException
1414from .execute import VkFunction
15+ from .utils import sjson_dumps
1516
1617if sys .version_info .major == 2 :
1718 range = xrange
1819
1920
20- class VkRequestsPoolException (Exception ):
21- pass
22-
23-
2421PoolRequest = namedtuple ('PoolRequest' , ['method' , 'values' , 'result' ])
2522
2623
@@ -51,7 +48,13 @@ def result(self):
5148 raise RuntimeError ('Result is not available in `with` context' )
5249
5350 if self ._error :
54- raise VkRequestsPoolException ('Got error while executing request' )
51+ raise VkRequestsPoolException (
52+ self ._error ,
53+ 'Got error while executing request: [{}] {}' .format (
54+ self .error ['error_code' ],
55+ self .error ['error_msg' ]
56+ )
57+ )
5558
5659 return self ._result
5760
@@ -74,28 +77,20 @@ class VkRequestsPool(object):
7477 Служит как менеджер контекста: запросы к API добавляются в
7578 открытый пул, и выполняются при его закрытии.
7679
77- :param vk : Объект :class:`VkApi`
80+ :param vk_session : Объект :class:`VkApi`
7881 """
7982
80- __slots__ = ('vk ' , 'pool' , 'one_param' , 'execute_errors ' )
83+ __slots__ = ('vk_session ' , 'pool' )
8184
82- def __init__ (self , vk ):
83- self .vk = vk
85+ def __init__ (self , vk_session ):
86+ self .vk_session = vk_session
8487 self .pool = []
85- self .one_param = {}
86- self .execute_errors = []
8788
8889 def __enter__ (self ):
8990 return self
9091
9192 def __exit__ (self , * args , ** kwargs ):
92- if self .one_param :
93- self .execute_one_param ()
94- else :
95- self .execute ()
96-
97- def get_execute_errors (self ):
98- return self .execute_errors
93+ self .execute ()
9994
10095 def method (self , method , values = None ):
10196 """
@@ -111,9 +106,6 @@ def method(self, method, values=None):
111106 :rtype: RequestResult
112107 """
113108
114- if self .one_param :
115- raise RuntimeError ('One param mode does not work with self.method' )
116-
117109 if values is None :
118110 values = {}
119111
@@ -122,44 +114,6 @@ def method(self, method, values=None):
122114
123115 return result
124116
125- def method_one_param (self , method , key , values , default_values = None ):
126- """
127- Использовать, если изменяется значение только одного параметра.
128- Невозможно использовать вместе с :func:`method`.
129- Возвращаемое значение будет содержать результат после закрытия пула.
130-
131- :param method: метод
132- :type method: str
133-
134- :param default_values: одинаковые значения для запросов
135- :type default_values: dict
136-
137- :param key: ключ изменяющегося параметра
138- :type key: str
139-
140- :param values: список значений изменяющегося параметра (max: 25)
141- :type values: list
142-
143- :rtype: RequestResult
144- """
145-
146- if not self .one_param and self .pool :
147- raise RuntimeError ('One param mode does not work with self.method' )
148-
149- if default_values is None :
150- default_values = {}
151-
152- self .one_param = {
153- 'method' : method ,
154- 'default' : default_values ,
155- 'key' : key ,
156- 'return' : RequestResult ()
157- }
158-
159- self .pool = values
160-
161- return self .one_param ['return' ]
162-
163117 def execute (self ):
164118 for i in range (0 , len (self .pool ), 25 ):
165119 cur_pool = self .pool [i :i + 25 ]
@@ -169,45 +123,24 @@ def execute(self):
169123 if one_method :
170124 value_list = [i .values for i in cur_pool ]
171125
172- response_raw = vk_one_method (self .vk , one_method , value_list )
126+ response_raw = vk_one_method (
127+ self .vk_session , one_method , value_list
128+ )
173129 else :
174- response_raw = vk_many_methods (self .vk , cur_pool )
175-
176- response = response_raw ['response' ]
177- response_errors = response_raw .get ('execute_errors' )
178-
179- if response_errors :
180- self .execute_errors += response_errors [:- 1 ]
181-
182- for x , response in enumerate (response ):
183- if response is not False :
184- cur_pool [x ].result .result = response
185- else :
186- cur_pool [x ].result .error = True
187-
188- def execute_one_param (self ):
189- result = {}
190-
191- method = self .one_param ['method' ]
192- default = self .one_param ['default' ]
193- key = self .one_param ['key' ]
194-
195- for i in range (0 , len (self .pool ), 25 ):
196- cur_pool = self .pool [i :i + 25 ]
197-
198- response_raw = vk_one_param (self .vk , method , cur_pool , default , key )
130+ response_raw = vk_many_methods (self .vk_session , cur_pool )
199131
200132 response = response_raw ['response' ]
201- response_errors = response_raw .get ('execute_errors' )
133+ response_errors = response_raw .get ('execute_errors' , [] )
202134
203- if response_errors :
204- self .execute_errors += response_errors [:- 1 ]
135+ response_errors_iter = iter (response_errors )
205136
206- for x , r in enumerate (response ):
207- if r is not False :
208- result [cur_pool [x ]] = r
137+ for x , current_response in enumerate (response ):
138+ current_result = cur_pool [x ].result
209139
210- self .one_param ['return' ].result = result
140+ if current_response is not False :
141+ current_result .result = current_response
142+ else :
143+ current_result .error = next (response_errors_iter )
211144
212145
213146def check_one_method (pool ):
@@ -242,6 +175,65 @@ def check_one_method(pool):
242175''' )
243176
244177
178+ def vk_many_methods (vk_session , pool ):
179+ requests = ',' .join (
180+ 'API.{}({})' .format (i .method , sjson_dumps (i .values ))
181+ for i in pool
182+ )
183+
184+ code = 'return [{}];' .format (requests )
185+
186+ return vk_session .method ('execute' , {'code' : code }, raw = True )
187+
188+
189+ def vk_request_one_param_pool (vk_session , method , key , values ,
190+ default_values = None ):
191+ """
192+ Использовать, если изменяется значение только одного параметра.
193+ Невозможно использовать вместе с :func:`method`.
194+ Возвращаемое значение будет содержать результат после закрытия пула.
195+
196+ :param vk_session: метод
197+ :type vk_session: vk_api.VkAPi
198+
199+ :param method: метод
200+ :type method: str
201+
202+ :param default_values: одинаковые значения для запросов
203+ :type default_values: dict
204+
205+ :param key: ключ изменяющегося параметра
206+ :type key: str
207+
208+ :param values: список значений изменяющегося параметра (max: 25)
209+ :type values: list
210+
211+ :rtype: (dict, dict)
212+ """
213+
214+ result = {}
215+ errors = {}
216+
217+ for i in range (0 , len (values ), 25 ):
218+ current_values = values [i :i + 25 ]
219+
220+ response_raw = vk_one_param (
221+ vk_session , method , current_values , default_values , key
222+ )
223+
224+ response = response_raw ['response' ]
225+ response_errors = response_raw .get ('execute_errors' , [])
226+ response_errors_iter = iter (response_errors )
227+
228+ for x , r in enumerate (response ):
229+ if r is not False :
230+ result [current_values [x ]] = r
231+ else :
232+ errors [current_values [x ]] = next (response_errors_iter )
233+
234+ return result , errors
235+
236+
245237vk_one_param = VkFunction (
246238 args = ('method' , 'values' , 'default_values' , 'key' ),
247239 clean_args = ('method' , 'key' ),
@@ -262,14 +254,3 @@ def check_one_method(pool):
262254
263255 return result;
264256''' )
265-
266-
267- def vk_many_methods (vk_session , pool ):
268- requests = ',' .join (
269- 'API.{}({})' .format (i .method , sjson_dumps (i .values ))
270- for i in pool
271- )
272-
273- code = 'return [{}];' .format (requests )
274-
275- return vk_session .method ('execute' , {'code' : code }, raw = True )
0 commit comments