add initialize
diff --git a/supwisdom/__init__.py b/supwisdom/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/supwisdom/__init__.py
diff --git a/supwisdom/protocol/__init__.py b/supwisdom/protocol/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/supwisdom/protocol/__init__.py
diff --git a/supwisdom/protocol/nettrans.py b/supwisdom/protocol/nettrans.py
new file mode 100644
index 0000000..98099f7
--- /dev/null
+++ b/supwisdom/protocol/nettrans.py
@@ -0,0 +1,195 @@
+# -*- coding: utf-8 -*-

+""" 一卡通后台通讯协议包封装

+所有数据都是 unicode  utf-8 编码

+"""

+import traceback

+import simplejson as json

+

+

+def _unicode_str(value):

+    if isinstance(value, str):

+        return value.decode('utf-8')

+    elif isinstance(value, unicode):

+        return value

+    else:

+        return unicode(value)

+

+

+class message_writer:

+    """ 后台消息写接口

+    """

+    def __init__(self):

+        self.clear()

+

+    def clear(self):

+        self._attr = {}

+        self._row_data = []

+        self._col_names = []

+        self._row = {}

+        self._frozen = False

+

+    def attr(self, name, value):

+        if name in self._attr:

+            raise ValueError('Attribute [%s] already exists' % name)

+        self._attr[name] = _unicode_str(value)

+        return self

+

+    def row(self, name, value):

+        if not (name in self._col_names):

+            self._col_names.append(name)

+        self._row[name] = _unicode_str(value)

+

+    def add_row(self):

+        if not self._row:

+            raise ValueError('Row has no values')

+        self._row_data.append(self._row)

+        self._row = {}

+        return len(self._row_data)

+

+    def append_row(self, row):

+        if not self._col_names:

+            for k, v in row.iteritems():

+                self._col_names.append(k)

+            self._row_data.append(row)

+        else:

+            new_row = dict([(v, row.get(v, None)) for v in self._col_names])

+            self._row_data.append(new_row)

+

+    def _normalize(self):

+        colcnt = len(self._col_names)

+        rowcnt = len(self._row_data)

+        self._attr["colcnt"] = colcnt

+        self._attr["rowcnt"] = rowcnt

+        if colcnt > 0:

+            self._attr["colname"] = self._col_names

+            self._attr["coldesc"] = self._col_names

+

+        if rowcnt > 0 and colcnt <= 0:

+            raise ValueError(u'数据没有列值')

+

+        if rowcnt > 0:

+            self._attr["rowdata"] = [[row.get(colname, u"") for colname in self._col_names]

+                for row in self._row_data]

+        self._frozen = True

+

+    def serialize(self):

+        """ 返回 unicode utf-8编码

+        """

+        if not self._frozen:

+            self._normalize()

+        seri = json.dumps(self._attr, ensure_ascii=False, encoding='utf-8')

+        return seri

+

+    def root(self):

+        if not self._frozen:

+            self._normalize()

+        return self._attr

+

+

+class message_reader:

+    """ 后台消息读接口

+    """

+    def __init__(self):

+        self.clear()

+

+    def clear(self):

+        """ 清空数据

+        """

+        self._attr = {}

+        self._row_data = None

+        self._col_names = []

+        self._col_desc = []

+        self._row_no = -1

+        self._frozen = False

+

+    def unserialize(self, message):

+        """ 解析报文

+        """

+        self.clear()

+        try:

+            message = _unicode_str(message)

+            obj = json.loads(message)

+            #obj = json.loads(msg.replace('\\',"\\\\"))

+        except Exception, ex:

+            traceback.print_exc()

+            raise ValueError(u'解析报文错误,' + ex.message)

+

+        if u"colname" in obj:

+            colname = obj[u"colname"]

+            colcnt = obj[u"colcnt"]

+            rowcnt = obj[u"rowcnt"]

+

+            if colcnt != len(colname):

+                raise ValueError(u'记录列数定义不符')

+

+            rowdata = obj[u"rowdata"]

+            if rowcnt != len(rowdata):

+                raise ValueError(u'记录行数定义不符')

+

+            self._row_data = [dict(zip(colname, row)) for row in rowdata]

+            self._col_names = colname

+            self._col_desc = obj["coldesc"]

+        else:

+            pass

+

+        for n, v in obj.iteritems():

+            if n in (u"colname", u"colcnt", u"rowcnt", u"coldesc", u"rowdata"):

+                continue

+            self._attr[n] = v

+        self._frozen = True

+        #print self._attr

+

+    def attr(self, name):

+        """ 获取属性值,如果没有改属性返回空字符串

+        """

+        assert self._frozen == True

+        if name not in self._attr:

+            return ""

+        return self._attr[name]

+

+    def has_more_row(self):

+        """ 判断是否有后续行

+        """

+        assert self._frozen == True

+        if not self._row_data:

+            return False

+        if self._row_no < len(self._row_data):

+            return True

+        return False

+

+    def next_row(self):

+        """ 将读取指针移到下一行

+        """

+        assert self._frozen == True

+        assert self.has_more_row()

+        self._row_no += 1

+

+    _ARG_DEFAULT = []

+

+    def col(self, name, default=[], strip=True):

+        """ 获取当前行的字段值

+        """

+        assert self._row_no >= 0

+        arg = self._row_data[self._row_no].get(name, None)

+        if not arg:

+            if strip and default == message_reader._ARG_DEFAULT:

+                raise IndexError(u'no such column %s' % name)

+            return default

+        return arg

+

+    def is_eof(self):

+        """判断是否到记录尾

+        """

+        if self._row_no >= len(self._row_data):

+            return True

+        return False

+

+    def fetch_rows(self):

+        """ 读取所有行记录

+        """

+        if not self.has_more_row():

+            return

+        self._row_no = 0

+        for row in self._row_data:

+            self._row_no += 1

+            yield row

diff --git a/supwisdom/protocol/webservice.py b/supwisdom/protocol/webservice.py
new file mode 100644
index 0000000..48062b3
--- /dev/null
+++ b/supwisdom/protocol/webservice.py
@@ -0,0 +1,204 @@
+# -*- coding: utf-8

+"""

+一卡通webservice 请求 session 封装

+"""

+import urllib

+from datetime import datetime

+from tornado.httpclient import HTTPClient, HTTPRequest, HTTPError

+import json

+import traceback

+

+

+class SWWebserviceError(BaseException):

+    def __init__(self, code, msg):

+        self.code = code

+        self.msg = msg

+

+    def __str__(self):

+        try:

+            msg = self.msg.encode('utf-8', 'ignore')

+        except:

+            msg = self.msg.encode('gbk', 'ignore')

+        return "%d : %s" % (self.code, msg)

+

+    def __unicode__(self):

+        return u"%d: %s" % (self.code, self.msg)

+

+

+class SWWebserviceSession(object):

+    """

+    webservice session object

+    example

+

+    session = SWWebserviceSession('http://localhost:8080/yktapi/services',

+                '123213','3334df334223',1)

+

+    try:

+        if not session.auth():

+            print u"签到失败"

+    except SWWebserviceError, ex:

+        print "Error : %d , %s" % (ex.code, ex.msg)

+

+    """

+    def __init__(self, service_url, appid, appsecret, termid):

+        self.service_url = service_url

+        self.appid = appid

+        self.appsecret = appsecret

+        if isinstance(termid, int):

+            self.termid = str(termid)

+        elif isinstance(termid, float):

+            self.termid = str(termid)

+        else:

+            self.termid = termid

+        self.access_token = None

+        self.session_key = None

+        self.error_msg = None

+        self.status_code = None

+

+    def auth(self, timeout=10):

+        """

+        签到

+        """

+        if not self._get_access_token(timeout):

+            return False

+        if not self._get_session_key(timeout):

+            return False

+        return True

+

+    def logoff(self):

+        """

+        签退

+        """

+        self.access_token = None

+        self.session_key = None

+

+    def is_logon(self):

+        """

+        是否签到成功

+        """

+        return self.session_key != None

+

+    def _get_access_token(self, timeout):

+        url = ''.join((self.service_url, '/authservice/getauth/',

+              self.appid, '/getaccesstoken?term_id=', self.termid))

+        http_client = HTTPClient()

+        try:

+            response = http_client.fetch(url, connect_timeout=timeout,

+                request_timeout=timeout)

+            try:

+                result = json.loads(response.body)

+                self.access_token = result.get('access_token', None)

+                if not self.access_token:

+                    raise SWWebserviceError(501, u"系统返回值正确")

+                return True

+            except:

+                raise SWWebserviceError(500, u"无法解析返回值")

+        except HTTPError, ex:

+            if not ex.response:

+                self.error_msg = u"检查与服务器的连接"

+                return False

+            self.status_code = ex.response.code

+            self.error_msg = ex.response.body

+            return False

+

+    def _sign_data(self, key, data):

+        import hmac

+        import hashlib

+        h = hmac.new(key, digestmod=hashlib.sha1)

+        h.update(data)

+        return (h.hexdigest(), 'HMAC')

+

+    def _get_session_key(self, timeout):

+        timestamp = self.nonce()

+        sign, sign_meth = self._sign_data(self.appsecret,

+            self.access_token + timestamp)

+        r = (self.service_url, '/authservice/getauth/', self.appid,

+            '?access_token=', self.access_token, '&term_id=', self.termid,

+            "&sign_method=", sign_meth, "&sign=", sign, "&timestamp=",

+            timestamp, "&v=1")

+        url = ''.join(r)

+

+        http_client = HTTPClient()

+        try:

+            response = http_client.fetch(url, connect_timeout=timeout,

+                request_timeout=timeout)

+            try:

+                result = json.loads(response.body)

+                self.session_key = result.get('session_key', None)

+                if not self.session_key:

+                    raise SWWebserviceError(501, u"系统返回值正确")

+                return True

+            except:

+                raise SWWebserviceError(500, u"无法解析返回值")

+        except HTTPError, ex:

+            self.status_code = ex.response.code

+            self.error_msg = ex.response.body

+            return False

+

+    def nonce(self):

+        return datetime.now().strftime('%Y%m%d%H%M%S')

+

+    def gen_request_token(self):

+        """

+        生成请求 token

+        """

+        timestamp = self.nonce()

+        token = ''.join((self.appid, self.termid,

+                self.session_key, timestamp))

+        sign, sign_meth = self._sign_data(self.appsecret, token)

+        #        params = urllib.urlencode(dict(app_id=appinfo.get('appid'),

+        #            term_id=appinfo.get('termid'),

+        #            sign_method="HMAC",

+        #            timestamp=timestamp,

+        #            sign=sign))

+        return dict(timestamp=timestamp, sign=sign,

+            app_id=self.appid, term_id=self.termid,

+            sign_method=sign_meth)

+

+    def request_token_urlencode(self, token):

+        """

+        将 gen_request_token 返回的数据编码成请求url

+        """

+        return urllib.urlencode(token)

+

+

+class SWRequest(object):

+    def __init__(self, session):

+        self.session = session

+        self.service_url = self.session.service_url + '/ecardservice/ecardapi'

+        self.error_msg = None

+

+    def request(self, request, response, timeout=10.0):

+        if not self.session.is_logon():

+            raise SWWebserviceError(u"session无效")

+        client = HTTPClient()

+        try:

+            http_request = HTTPRequest(url=self.service_url, method='POST',

+                headers={'Content-Type': 'application/json'},

+                connect_timeout=timeout,

+                body=self._pack_body(request))

+            http_resp = client.fetch(http_request)

+        except HTTPError, ex:

+            http_resp = ex.response

+        except:

+            traceback.print_exc()

+            return False

+

+        if not http_resp:

+            return False

+        self.status_code = http_resp.code

+        if http_resp.code != 200:

+            self.error_msg = '%d : %s' % (self.status_code, http_resp.body)

+            self.error_msg = self.error_msg.decode('utf-8', 'ignore')

+        else:

+            try:

+                response.unserialize(http_resp.body)

+                return True

+            except:

+                return False

+

+    def _pack_body(self, request):

+        funcdata = request.serialize()

+        request_token = self.session.gen_request_token()

+        request_token['funcdata'] = funcdata.decode('utf-8', 'ignore')

+        return json.dumps(request_token, ensure_ascii=False)