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