root/projects/2008/pyogp/pyogp.lib.base/trunk/pyogp/lib/base/utilities/helpers.py

Revision 2491, 7.1 kB (checked in by kotler.linden, 5 months ago)

remerge of kotler_tests

Line 
1 # standard python libs
2 from logging import getLogger, CRITICAL, ERROR, WARNING, INFO, DEBUG
3 import time
4 import struct
5
6 # related
7 from indra.base import llsd
8 from eventlet import api
9
10 # pyogp
11 from pyogp.lib.base.exc import DataParsingError, DeserializationFailed
12
13 # initialize loggin
14 logger = getLogger('...utilities.helpers')
15 log = logger.log
16
17 class Helpers(object):
18     """ contains useful helper functions """
19
20     def bytes_to_hex(self, data):
21         """ converts bytes to hex format """
22
23         #from binascii import hexlify
24         #return hex_string
25         #hex_string = hexlify(data)
26         return ''.join(["%02X " % ord(x) for x in data]).strip()
27
28     def bytes_to_ascii(self, data):
29         " converts bytes to ascii format "
30
31         from binascii import b2a_uu
32
33         ascii_string = b2a_uu(data)
34
35         return ascii_string
36
37     def hex_to_ascii(self, data):
38         " converts bytes to ascii format "
39
40         from binascii import unhexlify
41
42         try:
43             ascii_string = unhexlify(data)
44         except TypeError, error:
45             raise DataParsingError('hex_to_ascii failure: \'%s\': processing data: \'%s\'' % (error, data))
46
47         return ascii_string
48
49     def bytes_to_base64(self, data):
50         " converts bytes to ascii format "
51
52         from binascii import b2a_base64
53
54         base64_string = b2a_base64(data)
55
56         return base64_string
57
58     def int_to_bytes(self, data):
59         """
60         converts an int to a string of bytes
61         """
62         return struct.pack('BBBB',
63                            data % 256,
64                            (data >> 8) % 256,
65                            (data >> 16) % 256,
66                            (data >> 24) % 256)
67
68     # ~~~~~~~~~
69     # Callbacks
70     # ~~~~~~~~~
71
72     def log_packet(self, packet, _object):
73         """ default logging function for packets  """
74
75         log(INFO, "Object %s is monitoring packet type %s: \n%s" % (type(_object), packet.name, packet.data()))
76
77     def log_event_queue_data(self, data, _object):
78         """ default logging function for event queue data events  """
79
80         log(INFO, "Object %s is monitoring event queue data event %s: \n%s" % (type(_object), data.name, data.__dict__))
81
82     def null_packet_handler(self, packet, _object):
83         """ just a null event handler for watching aka fully parsing specific packets """
84
85         pass
86
87 class ListLLSDSerializer(object):
88     """adapter for serializing a list to LLSD
89
90     An example:
91     >>> d=['ChatSessionRequest', 'CopyInventoryFromNotecard']
92     >>> serializer = ListLLSDSerializer(d)
93     >>> serializer.serialize()
94     '<?xml version="1.0" ?><llsd><array><string>ChatSessionRequest</string><string>CopyInventoryFromNotecard</string></array></llsd>'
95     >>> serializer.content_type
96     'application/llsd+xml'
97
98     """
99
100     def __init__(self, context):
101         self.context = context
102
103     def serialize(self):
104         """convert the payload to LLSD"""
105         return llsd.format_xml(self.context)
106
107     @property
108     def content_type(self):
109         """return the content type of this serializer"""
110         return "application/llsd+xml"
111
112
113 class DictLLSDSerializer(object):
114     """adapter for serializing a dictionary to LLSD
115
116     An example:
117     >>> d={'foo':'bar', 'test':1234}
118     >>> serializer = DictLLSDSerializer(d)
119     >>> serializer.serialize()
120     '<?xml version="1.0" ?><llsd><map><key>test</key><integer>1234</integer><key>foo</key><string>bar</string></map></llsd>'
121     >>> serializer.content_type
122     'application/llsd+xml'
123
124     """
125
126     def __init__(self, context):
127         self.context = context
128
129     def serialize(self):
130         """convert the payload to LLSD"""
131         return llsd.format_xml(self.context)
132
133     @property
134     def content_type(self):
135         """return the content type of this serializer"""
136         return "application/llsd+xml"
137
138 class LLSDDeserializer(object):
139     """utility for deserializing LLSD data
140
141     The deserialization component is defined as a utility because the input
142     data can be a string or a file. It might be possible to define this as
143     an adapter on a string but a string is too generic for this. So that's
144     why it is a utility.
145
146     You can use it like this:
147
148     >>> s='<?xml version="1.0" ?><llsd><map><key>test</key><integer>1234</integer><key>foo</key><string>bar</string></map></llsd>'
149
150     We use queryUtility because this returns None instead of an exception
151     when a utility is not registered. We use the content type we received
152     as the name of the utility. Another option would of course be to subclas
153     string to some LLSDString class and use an adapter. We then would need some
154     factory for generating the LLSDString class from whatever came back from
155     the HTTP call.
156
157     So here is how you use that utility:
158     >>> deserializer = LLSDDeserializer()
159     >>> llsd = deserializer.deserialize(s)
160     >>> llsd
161     {'test': 1234, 'foo': 'bar'}
162
163     We can also test this with some non-LLSD string:
164
165     >>> llsd = deserializer.deserialize_string('mumpitz')   # this is not LLSD
166     Traceback (most recent call last):
167     ...
168     DeserializationFailed: deserialization failed for 'mumpitz', reason: 'invalid token at index 0: 109'
169
170     >>> llsd = deserializer.deserialize_string('barfoo')
171     Traceback (most recent call last):
172     ...
173     DeserializationFailed: deserialization failed for 'barfoo', reason: 'binary notation not yet supported'
174
175
176     """
177
178     def deserialize(self, data):
179         """ convenience class to handle a variety of inputs """
180
181         if type(data) == str:
182             return self.deserialize_string(data)
183         # won't handle another case until we need to
184
185     def deserialize_string(self, data):
186         """ deserialize a string """
187
188         try:
189             r = llsd.parse(data)
190         except llsd.LLSDParseError, e:
191             raise DeserializationFailed(data, str(e))
192         if r==False:
193             raise DeserializationFailed(data, 'result was False')
194         return r
195
196     def deserialize_file(self, fp):
197         """ deserialize a file """
198         data = fp.read()
199         return self.deserialize_string(data)
200
201 class Wait(object):
202     """ a simple timer that blocks a calling routine for the specified number of seconds
203
204     done since we were writing timing loops in test scripts repeatedly
205     returns True when it's done
206      """
207
208     def __init__(self, duration):
209
210         self.duration = int(duration)
211
212         # let's be nice and enabled a kill switch
213         self.enabled = False
214
215         self.run()
216
217     def run(self):
218
219         now = time.time()
220         start = now
221         self.enabled = True
222
223         while self.enabled and now - start < self.duration:
224
225             api.sleep()
226             now = time.time()
227
228         return True
229
230     def stop(self):
231
232         self.enabled = False
233
234 """
235 Contributors can be viewed at:
236 http://svn.secondlife.com/svn/linden/projects/2008/pyogp/CONTRIBUTORS.txt
237
238 $LicenseInfo:firstyear=2008&license=apachev2$
239
240 Copyright 2009, Linden Research, Inc.
241
242 Licensed under the Apache License, Version 2.0 (the "License").
243 You may obtain a copy of the License at:
244     http://www.apache.org/licenses/LICENSE-2.0
245 or in
246     http://svn.secondlife.com/svn/linden/projects/2008/pyogp/LICENSE.txt
247
248 $/LicenseInfo$
249 """
250
Note: See TracBrowser for help on using the browser.