coding utf-8 from xml dom minidom import parseString import xml sax de

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
# -*- coding: utf-8 -*-
from xml.dom.minidom import parseString
import xml.sax
def _urllib_fetch(url, action, body):
import urllib2
"""
A wrapper around default urllib2 library.
"""
headers = {'Content-Type': 'text/xml',
'SOAPAction':'"http://gamespy.net/sake/%s"' % action}
try:
req = urllib2.Request(url, body, headers)
return urllib2.urlopen(req).read()
except urllib2.HTTPError, e:
return e.read()
class WebServiceError(Exception):
def __init__(self, msg):
Exception.__init__(self, msg)
def _CreateSOAPRequest(action, *args, **kwargs):
soap_doc = '<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://gamespy.net/sake"><SOAP-ENV:Body/></SOAP-ENV:Envelope>'
doc = parseString(soap_doc)
body = doc.createElement(action)
doc.documentElement.firstChild.appendChild(body)
for (a, b) in kwargs.iteritems():
if b is None:
continue
i = doc.createElement(a)
if isinstance(b, tuple) or isinstance (b, list):
for z in b:
if isinstance(z, int):
tp = 'int'
elif isinstance(z, str):
tp = 'string'
x = doc.createElement(tp)
x.appendChild(doc.createTextNode(str(z)))
i.appendChild(x)
else:
i.appendChild(doc.createTextNode(str(b)))
body.appendChild(i)
return doc.toxml('utf-8')
class Result:
def __init__(self, doc, fields):
self._data = []
self.cached = False
self._count = 0
xml.sax.parseString(doc, _SFRParser(fields, self._data))
def next(self):
if self._count >= len(self._data):
self._count = 0
raise StopIteration
else:
c = self._count
self._count = c + 1
return self._data[c]
def __getitem__(self, n):
return self._data[n]
def __iter__(self):
return self
class _SFRParser(xml.sax.handler.ContentHandler):
def __init__(self, fields, result):
xml.sax.handler.ContentHandler.__init__(self)
self._fields = fields
self.result = result
#initializing flags
self._SFRResult = False
self._faultstring = False
self._AORV = False
self._RV = False
self._val = False
self._arrayCount = 0
self._fieldCount = 0
def startElement (self, name, attrs):
if name == 'value' and self._RV:
self._val = True
self._valText = u''
elif name == 'RecordValue':
self._RV = True
elif name == 'ArrayOfRecordValue':
self._array = []
self._AORV = True
elif name == 'SearchForRecordsResult':
self._SFRResult = True
self._SFRRtext = u''
elif name == 'faultstring':
self._faultstring = True
self._fsText = u''
def endElement(self, name):
if name == 'value' and self._RV: #ячейка кончилась
self._val = False
self._array.append((self._fields[self._fieldCount], self._valText))
elif name == 'RecordValue': #столбец кончился
self._RV = False
self._fieldCount += 1 #следующий столбец
elif name == 'ArrayOfRecordValue': #строка кончилась
self._arrayCount += 1 #следующая строка
self._fieldCount = 0 #сбрасываем показатель столбца
self._AORV = False
self.result.append(self._array)
elif name == 'SearchForRecordsResult':
if self._SFRRtext != 'Success':
raise WebServiceError(self._SFRRtext)
self._SFRResult = False
elif name == 'faultstring':
self._faultstring = False
raise WebServiceError(self._fsText)
def characters(self, content):
if self._val:
self._valText += content
elif self._SFRResult:
self._SFRRtext += content
elif self._faultstring:
self._fsText += content
class SakeStorage:
def __init__(self, url, gameid, tableid, ticket, cacheFlag=0, opener=_urllib_fetch):
self.url = url
self.gameid = gameid
self.tableid = tableid
self.ticket = ticket
self.cacheFlag = cacheFlag
self.opener = opener
def CreateRecord(self, *args, **kwargs):
raise NotImplementedError
def DeleteRecord(self, *args, **kwargs):
raise NotImplementedError
def GetMyRecords(self, *args, **kwargs):
raise NotImplementedError
def GetRandomRecords(self, *args, **kwargs):
raise NotImplementedError
def GetRecordCount(self, *args, **kwargs):
raise NotImplementedError
def GetRecordLimit(self, *args, **kwargs):
raise NotImplementedError
def GetSpecificRecords(self, *args, **kwargs):
raise NotImplementedError
def RateRecords(self, *args, **kwargs):
raise NotImplementedError
def UpdateRecords(self, *args, **kwargs):
raise NotImplementedError
# everything above actually isn't needed to be implemented
def SearchForRecords(self, fields, filter, sort, offset, ownerids, max):
action = 'SearchForRecords'
payload = _CreateSOAPRequest(action, gameid=self.gameid,
tableid=self.tableid, cacheFlag=self.cacheFlag,
loginTicket=self.ticket, fields=fields,
filter=filter, sort=sort,
offset=offset, max=max,
ownerids=ownerids)
res = _urllib_fetch(self.url, action, payload)
return Result(res, fields)