blob: 671e612d3f4df551739b52d31fe2985340fd6d59 [file] [log] [blame]
Tang Cheng53ca4872012-11-05 14:00:43 +08001# -*- coding: utf-8 -*-
2""" 一卡通后台通讯协议包封装
3所有数据都是 unicode utf-8 编码
4"""
5import traceback
Cheng Tangd7538e52013-02-21 13:54:29 +08006try:
7 import json
8except ImportError:
9 import simplejson as json
Tang Cheng53ca4872012-11-05 14:00:43 +080010
Tang Chengd36592e2012-12-20 14:24:27 +080011"""
12后台服务的字符编码
13"""
14SERVICE_ENCODING = 'utf-8'
Tang Cheng53ca4872012-11-05 14:00:43 +080015
16
17class message_writer:
18 """ 后台消息写接口
19 """
20 def __init__(self):
21 self.clear()
22
Tang Chengdf8e9942012-12-21 10:23:57 +080023 def _unicode_str(self, value):
Tang Chengd36592e2012-12-20 14:24:27 +080024 if isinstance(value, str):
25 return value.decode('utf-8')
26 elif isinstance(value, unicode):
27 return value
28 else:
29 return unicode(value)
30
Tang Cheng53ca4872012-11-05 14:00:43 +080031 def clear(self):
32 self._attr = {}
33 self._row_data = []
34 self._col_names = []
35 self._row = {}
36 self._frozen = False
37
38 def attr(self, name, value):
39 if name in self._attr:
40 raise ValueError('Attribute [%s] already exists' % name)
Tang Chengd36592e2012-12-20 14:24:27 +080041 self._attr[name] = self._unicode_str(value)
Tang Cheng53ca4872012-11-05 14:00:43 +080042 return self
43
44 def row(self, name, value):
45 if not (name in self._col_names):
46 self._col_names.append(name)
Tang Chengd36592e2012-12-20 14:24:27 +080047 self._row[name] = self._unicode_str(value)
Tang Cheng53ca4872012-11-05 14:00:43 +080048
49 def add_row(self):
50 if not self._row:
51 raise ValueError('Row has no values')
52 self._row_data.append(self._row)
53 self._row = {}
54 return len(self._row_data)
55
56 def append_row(self, row):
57 if not self._col_names:
58 for k, v in row.iteritems():
59 self._col_names.append(k)
60 self._row_data.append(row)
61 else:
62 new_row = dict([(v, row.get(v, None)) for v in self._col_names])
63 self._row_data.append(new_row)
64
65 def _normalize(self):
66 colcnt = len(self._col_names)
67 rowcnt = len(self._row_data)
68 self._attr["colcnt"] = colcnt
69 self._attr["rowcnt"] = rowcnt
70 if colcnt > 0:
71 self._attr["colname"] = self._col_names
72 self._attr["coldesc"] = self._col_names
73
74 if rowcnt > 0 and colcnt <= 0:
75 raise ValueError(u'数据没有列值')
76
77 if rowcnt > 0:
78 self._attr["rowdata"] = [[row.get(colname, u"") for colname in self._col_names]
79 for row in self._row_data]
80 self._frozen = True
81
82 def serialize(self):
83 """ 返回 unicode utf-8编码
84 """
85 if not self._frozen:
86 self._normalize()
Tang Chengd36592e2012-12-20 14:24:27 +080087 seri = json.dumps(self._attr, ensure_ascii=False, encoding=SERVICE_ENCODING)
Tang Cheng53ca4872012-11-05 14:00:43 +080088 return seri
89
90 def root(self):
91 if not self._frozen:
92 self._normalize()
93 return self._attr
94
95
96class message_reader:
97 """ 后台消息读接口
98 """
99 def __init__(self):
100 self.clear()
101
Tang Chengdf8e9942012-12-21 10:23:57 +0800102 def _unicode_str(self, value):
Tang Chengd36592e2012-12-20 14:24:27 +0800103 if isinstance(value, str):
104 return value.decode(SERVICE_ENCODING)
105 elif isinstance(value, unicode):
106 return value
107 else:
108 return unicode(value)
109
Tang Cheng53ca4872012-11-05 14:00:43 +0800110 def clear(self):
111 """ 清空数据
112 """
113 self._attr = {}
114 self._row_data = None
115 self._col_names = []
116 self._col_desc = []
117 self._row_no = -1
118 self._frozen = False
119
120 def unserialize(self, message):
121 """ 解析报文
122 """
123 self.clear()
124 try:
Tang Chengd36592e2012-12-20 14:24:27 +0800125 message = self._unicode_str(message)
Tang Cheng53ca4872012-11-05 14:00:43 +0800126 obj = json.loads(message)
127 #obj = json.loads(msg.replace('\\',"\\\\"))
128 except Exception, ex:
129 traceback.print_exc()
130 raise ValueError(u'解析报文错误,' + ex.message)
131
132 if u"colname" in obj:
133 colname = obj[u"colname"]
134 colcnt = obj[u"colcnt"]
135 rowcnt = obj[u"rowcnt"]
136
137 if colcnt != len(colname):
138 raise ValueError(u'记录列数定义不符')
139
140 rowdata = obj[u"rowdata"]
141 if rowcnt != len(rowdata):
142 raise ValueError(u'记录行数定义不符')
143
144 self._row_data = [dict(zip(colname, row)) for row in rowdata]
145 self._col_names = colname
146 self._col_desc = obj["coldesc"]
147 else:
148 pass
149
150 for n, v in obj.iteritems():
151 if n in (u"colname", u"colcnt", u"rowcnt", u"coldesc", u"rowdata"):
152 continue
153 self._attr[n] = v
154 self._frozen = True
155 #print self._attr
156
157 def attr(self, name):
158 """ 获取属性值,如果没有改属性返回空字符串
159 """
160 assert self._frozen == True
161 if name not in self._attr:
162 return ""
163 return self._attr[name]
164
165 def has_more_row(self):
166 """ 判断是否有后续行
167 """
168 assert self._frozen == True
169 if not self._row_data:
170 return False
Tang Chengbee49e42012-11-19 10:56:07 +0800171 if (self._row_no + 1) < len(self._row_data):
Tang Cheng53ca4872012-11-05 14:00:43 +0800172 return True
173 return False
174
175 def next_row(self):
176 """ 将读取指针移到下一行
177 """
178 assert self._frozen == True
179 assert self.has_more_row()
180 self._row_no += 1
181
182 _ARG_DEFAULT = []
183
184 def col(self, name, default=[], strip=True):
185 """ 获取当前行的字段值
186 """
187 assert self._row_no >= 0
188 arg = self._row_data[self._row_no].get(name, None)
Tang Cheng3e7feba2012-11-09 16:51:27 +0800189 if arg is None:
Tang Cheng53ca4872012-11-05 14:00:43 +0800190 if strip and default == message_reader._ARG_DEFAULT:
191 raise IndexError(u'no such column %s' % name)
192 return default
193 return arg
194
195 def is_eof(self):
196 """判断是否到记录尾
197 """
198 if self._row_no >= len(self._row_data):
199 return True
200 return False
201
202 def fetch_rows(self):
203 """ 读取所有行记录
204 """
205 if not self.has_more_row():
206 return
207 self._row_no = 0
208 for row in self._row_data:
209 self._row_no += 1
210 yield row