blob: 86cf86060e2712521106273fb2561e68d698cefe [file] [log] [blame]
Tang Cheng4a7dac42013-01-15 16:42:54 +08001#!/usr/bin/python
Tang Chenge90e9bb2012-07-03 13:38:01 +08002# -*- coding: utf-8 -*-
Cheng Tangc92b3ea2012-07-02 17:29:24 +08003
4from ctypes import *
5
Cheng Tangc92b3ea2012-07-02 17:29:24 +08006xpack_path = 'cpack.dat'
7
8cpack_fields = [
9"scust_no",
10"scust_no2",
11"sholder_ac_no",
12"sholder_ac_no2",
13"sholder_type",
14"sholder_type2",
15"sname",
16"sname2",
17"sall_name",
18"smarket_code",
19"smarket_code2",
20"sdate0",
21"sdate1",
22"sdate2",
23"sdate3",
24"stime0",
25"stime1",
26"stime2",
27"stime3",
28"lvol0",
29"lvol1",
30"lvol2",
31"lvol3",
32"lvol4",
33"lvol5",
34"lvol6",
35"lvol7",
36"lvol8",
37"lvol9",
38"lvol10",
39"lvol11",
40"lvol12",
41"damt0",
42"damt1",
43"damt2",
44"damt3",
45"damt4",
46"damt5",
47"damt6",
48"damt7",
49"damt8",
50"damt9",
51"damt10",
52"damt11",
53"damt12",
54"damt13",
55"damt14",
56"damt15",
57"damt16",
58"damt17",
59"damt18",
60"damt19",
61"damt20",
62"damt21",
63"damt22",
64"damt23",
65"damt24",
66"damt25",
67"damt26",
68"damt27",
69"damt28",
70"damt29",
71"damt30",
72"damt31",
73"damt32",
74"damt33",
75"sstock_code",
76"sstock_code2",
77"scust_type",
78"scust_type2",
79"sstat_type",
80"sstat_type2",
81"sroom_no",
82"sroom_no2",
83"sopen_emp",
84"sclose_emp",
85"schange_emp",
86"scheck_emp",
87"semp",
88"snation_code",
89"lcert_code",
90"stx_pwd",
91"stx_pwd2",
92"swithdraw_pwd",
93"swithdraw_pwd2",
94"semp_pwd",
95"semp_pwd2",
96"sbank_pwd",
97"sbank_pwd2",
98"scust_auth",
99"scust_auth2",
100"scust_limit",
101"scust_limit2",
102"lsafe_level",
103"lsafe_level2",
104"spost_code",
105"spost_code2",
106"sphone",
107"sphone2",
108"sphone3",
109"spager",
110"semail",
111"semail2",
112"snote",
113"snote2",
114"scert_no",
115"scert_no2",
116"scert_addr",
117"sstatus0",
118"sstatus1",
119"sstatus2",
120"sstatus3",
121"sstatus4",
122"lwithdraw_flag",
123"saddr",
124"saddr2",
125"sserial0",
126"sserial1",
127"sserial2",
128"sserial3",
129"sserial4",
130"scurrency_type",
131"scurrency_type2",
132"sbranch_code0",
133"sbranch_code1",
134"sbranch_code2",
135"usset0",
136"usset1",
137"usset2",
138"usset3",
139"usset4",
140"usset5",
141"usset6",
142"sstation0",
143"sstation1",
144"sbank_acc",
145"sbank_acc2",
146"lbank_acc_type",
147"lbank_acc_type2",
148"smain_flag",
149"smain_flag2",
150"sbank_code",
151"sbank_code2",
152"semp_no",
153"semp_no2",
154"drate0",
155"drate1",
156"lserial0",
157"lserial1",
158"sbankname",
159"sbankname2",
160"scard0",
161"scard1",
162"sorder0",
163"sorder1",
164"sorder2",
165"scusttypes",
166"ssectypes",
167"vsmess",
168"vsvarstr0",
169"vsvarstr1",
Tang Cheng4a7dac42013-01-15 16:42:54 +0800170"vsvarstr2",
171"vsvarstr3"
Cheng Tangc92b3ea2012-07-02 17:29:24 +0800172]
173
Cheng Tangc92b3ea2012-07-02 17:29:24 +0800174
175class pyBccclt:
176 drtp_no = -1
Tang Cheng4a7dac42013-01-15 16:42:54 +0800177 bccclt_dll = None
178
179 @staticmethod
180 def load_bccclt():
181 pyBccclt.bccclt_dll = cdll.LoadLibrary('bccclt.dll')
182
183 @staticmethod
184 def setup(ip, port, xpack='cpack.dat', debug=0):
Tang Chenge90e9bb2012-07-03 13:38:01 +0800185 ''' 初始化 '''
Tang Cheng4a7dac42013-01-15 16:42:54 +0800186 if not pyBccclt.bccclt_dll:
187 pyBccclt.load_bccclt()
Cheng Tangc92b3ea2012-07-02 17:29:24 +0800188 global xpack_path
189 xpack_path = xpack
Tang Cheng4a7dac42013-01-15 16:42:54 +0800190 pyBccclt.bccclt_dll.SetDebugSwitch(debug)
191 r = pyBccclt.bccclt_dll.BCCCLTInit(1)
Cheng Tangc92b3ea2012-07-02 17:29:24 +0800192 if not r:
Tang Chenge90e9bb2012-07-03 13:38:01 +0800193 raise RuntimeError(u"初始化连接失败")
Tang Cheng4a7dac42013-01-15 16:42:54 +0800194 no = pyBccclt.bccclt_dll.AddDrtpNode(ip, port)
Cheng Tangc92b3ea2012-07-02 17:29:24 +0800195 pyBccclt.drtp_no = no
196 if pyBccclt.drtp_no < 0:
Tang Chenge90e9bb2012-07-03 13:38:01 +0800197 raise RuntimeError(u'初始化通讯平台连接失败')
Tang Cheng4a7dac42013-01-15 16:42:54 +0800198
199 def __init__(self, mainfunc):
200 self.handle = pyBccclt.bccclt_dll.NewXpackHandle(xpack_path)
201 if isinstance(mainfunc, str) or isinstance(mainfunc, unicode):
202 self.mainfunc = int(mainfunc)
203 else:
204 self.mainfunc = mainfunc
Cheng Tangc92b3ea2012-07-02 17:29:24 +0800205 self.reset()
Tang Cheng4a7dac42013-01-15 16:42:54 +0800206
Cheng Tangc92b3ea2012-07-02 17:29:24 +0800207 def get_errormsg(self):
Tang Cheng4a7dac42013-01-15 16:42:54 +0800208 return self.error_msg.value.decode('gbk')
209
Cheng Tangc92b3ea2012-07-02 17:29:24 +0800210 def reset(self):
211 self.request_row = 0
212 self.error_code = c_int(0)
213 self.error_msg = create_string_buffer('\000' * 1024)
214 self.return_code = c_int(0)
215 self.record_count = 0
216 self.record = None
217 self.timeout = 5000
218 self.response_row = 0
Tang Cheng4a7dac42013-01-15 16:42:54 +0800219 self.raw_resp = None
220 pyBccclt.bccclt_dll.ResetPackHandle(self.handle)
221
Cheng Tangc92b3ea2012-07-02 17:29:24 +0800222 def close(self):
Tang Cheng4a7dac42013-01-15 16:42:54 +0800223 if self.handle != None:
224 pyBccclt.bccclt_dll.DeleteXpackHandle(self.handle)
Cheng Tangc92b3ea2012-07-02 17:29:24 +0800225 self.handle = None
Tang Cheng4a7dac42013-01-15 16:42:54 +0800226
227 def callsvr(self, func, request, timeout=1000):
Cheng Tangc92b3ea2012-07-02 17:29:24 +0800228 self.reset()
229 self.timeout = timeout
Tang Cheng4a7dac42013-01-15 16:42:54 +0800230 if request:
231 for k, v in request.iteritems():
232 if k not in cpack_fields:
233 raise ValueError(u"字段 %s 不存在" % k)
234 if isinstance(v, int):
235 pyBccclt.bccclt_dll.SetIntFieldByName(self.handle, self.request_row, k, v)
236 elif isinstance(v, float):
237 pyBccclt.bccclt_dll.SetDoubleFieldByName(self.handle, self.request_row, k, v)
238 elif isinstance(v, str):
239 pyBccclt.bccclt_dll.SetStringFieldByName(self.handle, self.request_row, k, v)
240 else:
241 raise ValueError(u"字段 %s 数据类型错误" % k)
242
243 pyBccclt.bccclt_dll.SetRequestType(self.handle, func)
Cheng Tangc92b3ea2012-07-02 17:29:24 +0800244 #print "CallRequest %d:%d" % (self.mainfunc,func)
Tang Cheng4a7dac42013-01-15 16:42:54 +0800245 if not pyBccclt.bccclt_dll.CallRequest(self.handle, pyBccclt.drtp_no, 0,
246 self.mainfunc, timeout, byref(self.error_code), self.error_msg):
Cheng Tangc92b3ea2012-07-02 17:29:24 +0800247 #print "CallRequest error "
248 return False
Tang Cheng4a7dac42013-01-15 16:42:54 +0800249
Cheng Tangc92b3ea2012-07-02 17:29:24 +0800250 self.get_return_error()
Cheng Tangc92b3ea2012-07-02 17:29:24 +0800251 cnt = c_int(0)
Tang Cheng4a7dac42013-01-15 16:42:54 +0800252 pyBccclt.bccclt_dll.GetRecordCount(self.handle, byref(cnt))
Cheng Tangc92b3ea2012-07-02 17:29:24 +0800253 self.record_count = cnt.value
254 return True
Tang Cheng4a7dac42013-01-15 16:42:54 +0800255
Cheng Tangc92b3ea2012-07-02 17:29:24 +0800256 def get_retcode(self):
257 return self.return_code.value
Tang Cheng4a7dac42013-01-15 16:42:54 +0800258
Cheng Tangc92b3ea2012-07-02 17:29:24 +0800259 def get_return_error(self):
Tang Cheng4a7dac42013-01-15 16:42:54 +0800260 r = pyBccclt.bccclt_dll.GetRetCode(self.handle, byref(self.return_code))
Cheng Tangc92b3ea2012-07-02 17:29:24 +0800261 if not r:
Tang Chenge90e9bb2012-07-03 13:38:01 +0800262 raise RuntimeError(u'取返回码错误')
Tang Cheng4a7dac42013-01-15 16:42:54 +0800263 if self.get_retcode() != 0:
264 pyBccclt.bccclt_dll.GetStringFieldByName(self.handle, 0, "vsmess", self.error_msg)
Cheng Tangc92b3ea2012-07-02 17:29:24 +0800265 return self.return_code.value
Tang Cheng4a7dac42013-01-15 16:42:54 +0800266
Cheng Tangc92b3ea2012-07-02 17:29:24 +0800267 def has_more_record(self):
268 #print "resp:%d, record: %d" % (self.response_row , self.record_count)
269 if self.response_row < self.record_count:
270 return True
Tang Cheng4a7dac42013-01-15 16:42:54 +0800271 elif not pyBccclt.bccclt_dll.HaveNextPack(self.handle):
Cheng Tangc92b3ea2012-07-02 17:29:24 +0800272 return False
Tang Cheng4a7dac42013-01-15 16:42:54 +0800273 elif not pyBccclt.bccclt_dll.CallNext(self.handle, self.timeout,
274 byref(self.error_code), self.error_msg):
Tang Chenge90e9bb2012-07-03 13:38:01 +0800275 raise RuntimeError(u'获取后续数据包异常')
Cheng Tangc92b3ea2012-07-02 17:29:24 +0800276 else:
277 self.response_row = 0
278 self.record_count = 0
279 self.get_return_error()
Tang Cheng4a7dac42013-01-15 16:42:54 +0800280 if self.get_retcode() != 0:
Tang Chenge90e9bb2012-07-03 13:38:01 +0800281 raise RuntimeError(u'取后续数据返回错误,ret=%d' % self.get_retcode())
Cheng Tangc92b3ea2012-07-02 17:29:24 +0800282 cnt = c_int(0)
Tang Cheng4a7dac42013-01-15 16:42:54 +0800283 pyBccclt.bccclt_dll.GetRecordCount(self.handle, byref(cnt))
Cheng Tangc92b3ea2012-07-02 17:29:24 +0800284 self.record_count = cnt.value
Tang Cheng4a7dac42013-01-15 16:42:54 +0800285 # print "next count: %d" % self.record_count
286 if self.response_row < self.record_count:
Cheng Tangc92b3ea2012-07-02 17:29:24 +0800287 return True
288 return False
Tang Cheng4a7dac42013-01-15 16:42:54 +0800289
290 def convert_ascii(self, data):
Cheng Tangc92b3ea2012-07-02 17:29:24 +0800291 i = 0
292 datalen = len(data)
Tang Cheng4a7dac42013-01-15 16:42:54 +0800293 result = []
Cheng Tangc92b3ea2012-07-02 17:29:24 +0800294 while i < datalen:
Tang Cheng4a7dac42013-01-15 16:42:54 +0800295 t = data[i: i + 2]
296 t1 = int(t, 16) & 0xFF
297 if t1 == 0:
298 break
Cheng Tangc92b3ea2012-07-02 17:29:24 +0800299 if (t1 < ord('0') or t1 > ord('9')) and (t1 < ord('A') or t1 > ord('F')):
Tang Cheng4a7dac42013-01-15 16:42:54 +0800300 raise ValueError("Value is non-hexdicimal %s:%d" % (chr(t1), t1))
301 result.append(chr(t1))
Cheng Tangc92b3ea2012-07-02 17:29:24 +0800302 i += 2
Tang Cheng4a7dac42013-01-15 16:42:54 +0800303 return "".join(result)
304
305 def next_record(self, fields):
Cheng Tangc92b3ea2012-07-02 17:29:24 +0800306 if self.response_row >= self.record_count:
Tang Chenge90e9bb2012-07-03 13:38:01 +0800307 raise ValueError(u'无可用记录')
Tang Cheng4a7dac42013-01-15 16:42:54 +0800308
Cheng Tangc92b3ea2012-07-02 17:29:24 +0800309 self.record = {}
310 for f in fields:
Tang Chenge90e9bb2012-07-03 13:38:01 +0800311 #print "获取字段 ",f
Cheng Tangc92b3ea2012-07-02 17:29:24 +0800312 if f not in cpack_fields:
Tang Chenge90e9bb2012-07-03 13:38:01 +0800313 raise ValueError(u"字段 %s 不存在" % f)
Tang Cheng4a7dac42013-01-15 16:42:54 +0800314
Cheng Tangc92b3ea2012-07-02 17:29:24 +0800315 ctype_field = create_string_buffer(f)
316 if f[0] == 'l':
317 v = c_int(0)
Tang Cheng4a7dac42013-01-15 16:42:54 +0800318 r = pyBccclt.bccclt_dll.GetIntFieldByName(self.handle, self.response_row,
319 ctype_field, byref(v))
Cheng Tangc92b3ea2012-07-02 17:29:24 +0800320 if not r:
Tang Chenge90e9bb2012-07-03 13:38:01 +0800321 raise ValueError(u"字段 %s 未返回" % f)
Cheng Tangc92b3ea2012-07-02 17:29:24 +0800322 self.record[f] = v.value
Tang Cheng4a7dac42013-01-15 16:42:54 +0800323 elif f[0] == 's' or f[0] == 'v':
Cheng Tangc92b3ea2012-07-02 17:29:24 +0800324 v = create_string_buffer('\000' * 512)
Tang Cheng4a7dac42013-01-15 16:42:54 +0800325 r = pyBccclt.bccclt_dll.GetStringFieldByName(self.handle, self.response_row, ctype_field, v)
Cheng Tangc92b3ea2012-07-02 17:29:24 +0800326 if not r:
Tang Chenge90e9bb2012-07-03 13:38:01 +0800327 raise ValueError(u"字段 %s 未返回" % f)
Cheng Tangc92b3ea2012-07-02 17:29:24 +0800328 #print "%s: %s" % (f,v.value)
329 self.record[f] = v.value
330 elif f[0] == 'd':
331 v = c_double(0.0)
Tang Cheng4a7dac42013-01-15 16:42:54 +0800332 r = pyBccclt.bccclt_dll.GetDoubleFieldByName(self.handle, self.response_row,
333 ctype_field, byref(v))
Cheng Tangc92b3ea2012-07-02 17:29:24 +0800334 if not r:
Tang Chenge90e9bb2012-07-03 13:38:01 +0800335 raise ValueError(u"字段 %s 未返回" % f)
Cheng Tangc92b3ea2012-07-02 17:29:24 +0800336 self.record[f] = v.value
337 elif f[0] == 'u':
338 v = create_string_buffer('\000' * 1024)
Tang Cheng4a7dac42013-01-15 16:42:54 +0800339 r = pyBccclt.bccclt_dll.GetStringFieldByName(self.handle, self.response_row,
340 ctype_field, v)
Cheng Tangc92b3ea2012-07-02 17:29:24 +0800341 if not r:
Tang Chenge90e9bb2012-07-03 13:38:01 +0800342 raise ValueError(u"字段 %s 未返回" % f)
Tang Cheng4a7dac42013-01-15 16:42:54 +0800343
Cheng Tangc92b3ea2012-07-02 17:29:24 +0800344 data = v.value
345 data = data[2:]
346 data = self.convert_ascii(data)
347 self.record[f] = data
348 else:
Tang Chenge90e9bb2012-07-03 13:38:01 +0800349 raise ValueError(u'字段类型错误 %s' % f)
Cheng Tangc92b3ea2012-07-02 17:29:24 +0800350 self.response_row += 1
351 #print "fetch one record , " ,self.record
352 return self.record
Tang Cheng4a7dac42013-01-15 16:42:54 +0800353
354 def fetch_record(self, fields):
Cheng Tangc92b3ea2012-07-02 17:29:24 +0800355 while self.has_more_record():
356 ret = self.next_record(fields)
357 yield ret
Tang Cheng4a7dac42013-01-15 16:42:54 +0800358
359 def send_raw_data(self, data, requesttype, timeout):
360 if isinstance(data, unicode):
361 data = data.encode('gbk')
362 pyBccclt.bccclt_dll.SetRawRecord(self.handle, 0, data, len(data))
363 pyBccclt.bccclt_dll.SetRequestType(self.handle, requesttype)
364 r = pyBccclt.bccclt_dll.CallRequest(self.handle, pyBccclt.drtp_no, 0,
365 self.mainfunc, timeout, byref(self.error_code), self.error_msg)
366 if not r:
367 return False
368 if self.raw_resp is None:
369 self.raw_resp = create_string_buffer(8196)
370 else:
371 memset(self.raw_resp, 0, sizeof(self.raw_resp))
372 r = pyBccclt.bccclt_dll.GetRawRecord(self.handle, 0, self.raw_resp, 8196)
373 if not r:
374 return False
375 return True
376
377 def raw_data(self):
378 if self.raw_resp is None:
379 raise ValueError(u"response is None")
380 return self.raw_resp.value