@@ -108,9 +108,142 @@ def get_all_slow(self, method, max_count, values=None, key='items',
108108 return {'count' : len (items ), key : items }
109109
110110
111+ class VkRequestsPool (object ):
112+ """ Позволяет сделать несколько обращений к API за один запрос
113+ за счет метода execute
114+ """
115+
116+ __slots__ = ('vk' , 'pool' , 'one_param' )
117+
118+ def __init__ (self , vk ):
119+ self .vk = vk
120+ self .pool = []
121+ self .one_param = False
122+
123+ def __enter__ (self ):
124+ return self
125+
126+ def __exit__ (self , * args , ** kwargs ):
127+ self .execute ()
128+
129+ def method (self , method , values = None ):
130+ """ Добавляет запрос в пулл
131+
132+ :param method: метод
133+ :param values: параметры
134+ """
135+
136+ if self .one_param :
137+ raise Exception ('One param mode dont work with self.method' )
138+
139+ req = (method , values , {})
140+ self .pool .append (req )
141+ return req [2 ]
142+
143+ def method_one_param (self , method , default_values = None , key = None ,
144+ values = None ):
145+
146+ if self .one_param is False and self .pool :
147+ raise Exception ('One param mode dont work with self.method' )
148+
149+ self .one_param = {
150+ 'method' : method ,
151+ 'default' : default_values ,
152+ 'key' : key ,
153+ 'return' : {}
154+ }
155+
156+ self .pool = values
157+
158+ return self .one_param ['return' ]
159+
160+ def check_one_method (self , pool ):
161+ """ Возвращает True, если все запросы в пулле к одному методу """
162+ if len (pool ) > 1 :
163+ first_method = pool [0 ][0 ]
164+
165+ for req in pool [1 :]:
166+ if req [0 ] != first_method :
167+ break
168+ else :
169+ return True
170+
171+ return False
172+
173+ def gen_code_one_method (self , pool ):
174+ """ Генерирует код для одного метода
175+ (если в пулле запросы к одному методу)
176+ """
177+ method = pool [0 ][0 ]
178+
179+ list_values = [i [1 ] for i in pool ]
180+ json_list_values = json .dumps (list_values , separators = (',' , ':' ))
181+ run_code = code_requestspoll_one_method % (
182+ json_list_values , method
183+ )
184+
185+ return run_code
186+
187+ def gen_code_one_param (self , pool ):
188+ """ Генерирует код для одного метода и одного меняющегося параметра
189+ (если в пулле запросы к одному методу, с одним меняющеися параметром)
190+ """
191+ run_code = code_requestspoll_one_param % (
192+ json .dumps (self .one_param ['default' ], separators = (',' , ':' )),
193+ json .dumps (pool , separators = (',' , ':' )),
194+ self .one_param ['key' ],
195+ self .one_param ['method' ]
196+ )
197+
198+ # print(run_code)
199+
200+ return run_code
201+
202+ def gen_code_many_methods (self , pool ):
203+ """ Генерирует код для нескольких методов """
204+ reqs = ',' .join (
205+ 'API.{}({})' .format (i [0 ], json .dumps (i [1 ]), separators = (',' , ':' ))
206+ for i in pool
207+ )
208+ run_code = 'return [{}];' .format (reqs )
209+
210+ return run_code
211+
212+ def execute (self ):
213+ for i in range (0 , len (self .pool ), 25 ):
214+ cur_pool = self .pool [i :i + 25 ]
215+
216+ if self .one_param :
217+ run_code = self .gen_code_one_param (cur_pool )
218+ else :
219+ one_method = self .check_one_method (cur_pool )
220+
221+ if one_method :
222+ run_code = self .gen_code_one_method (cur_pool )
223+ else :
224+ run_code = self .gen_code_many_methods (cur_pool )
225+
226+ response = self .vk .method ('execute' , {'code' : run_code })
227+
228+ for x in range (len (response )):
229+ if self .one_param :
230+ self .one_param ['return' ][cur_pool [x ]] = response [x ]
231+ else :
232+ self .pool [i + x ][2 ].update (response [x ])
233+
234+
111235# Полный код в файле vk_procedures
112236code_get_all_items = """
113237var m=%s,n=%s,b="%s",v=n;var c={count:m,offset:v}+%s;var r=API.%s(c),k=r.count,
114238j=r[b],i=1;while(i<25&&v+m<=k){v=i*m+n;c.offset=v;j=j+API.%s(c)[b];i=i+1;}
115239return {count:k,items:j,offset:v+m};
116240""" .replace ('\n ' , '' )
241+
242+ code_requestspoll_one_method = """
243+ var p=%s,i=0,r=[];while(i<p.length){r.push(API.%s(p[i]));i=i+1;}return r;
244+ """ .replace ('\n ' , '' )
245+
246+ code_requestspoll_one_param = """
247+ var d=%s,v=%s,r=[],i=0;while(i<v.length){d.%s=v[i];r.push(API.%s(d));i=i+1;};
248+ return r;
249+ """ .replace ('\n ' , '' )
0 commit comments