models.py 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. #encoding=utf-8
  2. from xml.dom import minidom
  3. import collections
  4. import time
  5. def kv2element(key, value, doc):
  6. ele = doc.createElement(key)
  7. if isinstance(value, str) or isinstance(value, unicode):
  8. data = doc.createCDATASection(value)
  9. ele.appendChild(data)
  10. else:
  11. text = doc.createTextNode(str(value))
  12. ele.appendChild(text)
  13. return ele
  14. def fields2elements(tupleObj, enclose_tag=None, doc=None):
  15. if enclose_tag:
  16. xml = doc.createElement(enclose_tag)
  17. for key in tupleObj._fields:
  18. ele = kv2element(key, getattr(tupleObj, key), doc)
  19. xml.appendChild(ele)
  20. return xml
  21. else:
  22. return [kv2element(key, getattr(tupleObj, key), doc)
  23. for key in tupleObj._fields]
  24. class WxRequest(object):
  25. def __init__(self, xml=None):
  26. if not xml:
  27. return
  28. doc = minidom.parseString(xml)
  29. params = [ele for ele in doc.childNodes[0].childNodes
  30. if isinstance(ele, minidom.Element)]
  31. for param in params:
  32. if param.childNodes:
  33. text = param.childNodes[0]
  34. self.__dict__.update({param.tagName: text.data})
  35. else:
  36. self.__dict__.update({param.tagName: ''})
  37. class WxResponse(object):
  38. def __init__(self, request):
  39. self.CreateTime = long(time.time())
  40. self.ToUserName = request.FromUserName
  41. self.FromUserName = request.ToUserName
  42. self.Extra = {}
  43. def as_xml(self):
  44. doc = minidom.Document()
  45. xml = doc.createElement('xml')
  46. doc.appendChild(xml)
  47. xml.appendChild(kv2element('ToUserName', self.ToUserName, doc))
  48. xml.appendChild(kv2element('FromUserName', self.FromUserName, doc))
  49. xml.appendChild(kv2element('CreateTime', self.CreateTime, doc))
  50. xml.appendChild(kv2element('MsgType', self.MsgType, doc))
  51. contents = self.content_nodes(doc)
  52. if isinstance(contents, list) or isinstance(contents, tuple):
  53. for content in contents:
  54. xml.appendChild(content)
  55. else:
  56. xml.appendChild(contents)
  57. if self.Extra:
  58. for key, value in self.Extra.iteritems():
  59. xml.appendChild(kv2element(key, value, doc))
  60. return doc.toxml()
  61. WxMusic = collections.namedtuple('WxMusic',
  62. 'Title Description MusicUrl HQMusicUrl')
  63. WxArticle = collections.namedtuple('WxArticle',
  64. 'Title Description PicUrl Url')
  65. WxImage = collections.namedtuple('WxImage', 'MediaId')
  66. WxVoice = collections.namedtuple('WxVoice', 'MediaId')
  67. WxVideo = collections.namedtuple('WxVideo',
  68. 'MediaId Title Description')
  69. WxLink = collections.namedtuple('WxLink', 'Title Description Url')
  70. class WxEmptyResponse(WxResponse):
  71. def __init__(self):
  72. pass
  73. def as_xml(self):
  74. return ''
  75. class WxTextResponse(WxResponse):
  76. MsgType = 'text'
  77. def __init__(self, text, request):
  78. super(WxTextResponse, self).__init__(request)
  79. self.text = text
  80. def content_nodes(self, doc):
  81. return kv2element('Content', self.text, doc)
  82. class WxCompoundResponse(WxResponse):
  83. MsgType = ''
  84. Tag = ''
  85. def __init__(self, data, request):
  86. super(WxCompoundResponse, self).__init__(request)
  87. self.data = data
  88. def content_nodes(self, doc):
  89. return fields2elements(self.data, self.Tag, doc)
  90. class WxImageResponse(WxCompoundResponse):
  91. MsgType = 'image'
  92. Tag = 'Image'
  93. class WxVoiceResponse(WxCompoundResponse):
  94. MsgType = 'voice'
  95. Tag = 'Voice'
  96. class WxVideoResponse(WxCompoundResponse):
  97. MsgType = 'video'
  98. Tag = 'Video'
  99. class WxMusicResponse(WxResponse):
  100. MsgType = 'music'
  101. Tag = 'Music'
  102. class WxNewsResponse(WxResponse):
  103. MsgType = 'news'
  104. def __init__(self, articles, request):
  105. super(WxNewsResponse, self).__init__(request)
  106. if isinstance(articles, list) or isinstance(articles, tuple):
  107. self.articles = articles
  108. else:
  109. self.articles = [articles]
  110. def content_nodes(self, doc):
  111. count = kv2element('ArticleCount', len(self.articles), doc)
  112. articles = doc.createElement('Articles')
  113. for article in self.articles:
  114. articles.appendChild(fields2elements(article, 'item', doc))
  115. return count, articles
  116. class APIError(object):
  117. def __init__(self, code, msg):
  118. self.code = code
  119. self.message = msg