| Trees | Indices | Help |
|
|---|
|
|
1 ### BITPIM
2 ###
3 ### Copyright (C) 2006 Joe Pham <djpham@bitpim.org>
4 ###
5 ### This program is free software; you can redistribute it and/or modify
6 ### it under the terms of the BitPim license as detailed in the LICENSE file.
7 ###
8 ### $Id: data_recording.py 4624 2008-06-30 03:55:35Z djpham $
9
10 """
11 Handle data recording stuff
12 """
13
14 # System modules
15 import cPickle
16 import struct
17 import threading
18 import time
19
20 # wx modules
21
22 # BitPim modules
23 import common
24 import pubsub
25
26 # constants
27 DR_Version=(0, 0, 1, 0) # 00.10
28 DR_Signature='BitPimDR'
29 DR_Rec_Marker='<-->'
30 DR_Type_All=0xff
31 DR_Type_Note=0x01
32 DR_Type_Write=0x02
33 DR_Type_Read=0x04
34 DR_Type_Read_ATResponse=0x08
35 DR_Type_Read_Some=0x10
36 DR_Type_Read_Until=0x20
37 DR_Type_Data=0x40
38 DR_Type_Name={
39 DR_Type_Note: 'Note',
40 DR_Type_Write: 'Write',
41 DR_Type_Read: 'Read',
42 DR_Type_Read_ATResponse: 'Read ATResponse',
43 DR_Type_Read_Some: 'Read Some',
44 DR_Type_Read_Until: 'Read Until',
45 DR_Type_Data: 'Data',
46 }
47
48 # exceptions
52
53 # global varaibales
54 DR_On=False
55 DR_Play=False
56 _the_recorder=None
57 _the_player=None
58
59 # public routines
60
62 "start a data recording session into the specified file"
63 global DR_On, _the_recorder
64 if DR_On and _the_recorder:
65 _the_recorder.stop()
66 _rec=DR_Rec_File(file_name, append)
67 _rec.start()
68 pubsub.publish(pubsub.DR_RECORD, data=_rec)
69
71 "start a playback session from the specified file"
72 global DR_Play, _the_player
73 if DR_Play and _the_player:
74 _the_player.stop()
75 _player=DR_Read_File(file_name)
76 _player.start()
77 pubsub.publish(pubsub.DR_PLAY, data=_player)
78
80 "stop a recording and/or playback session"
81 global DR_Play, DR_On, _the_recorder, _the_player
82 if DR_On and _the_recorder:
83 _the_recorder.stop()
84 if DR_Play and _the_player:
85 _the_player.stop()
86 pubsub.publish(pubsub.DR_STOP)
87
89 if start_recording:
90 pubsub.subscribe(start_recording, pubsub.DR_RECORD)
91 if start_playback:
92 pubsub.subscribe(start_playback, pubsub.DR_PLAY)
93 if stop:
94 pubsub.subscribe(stop, pubsub.DR_STOP)
95
97 if start_recording:
98 pubsub.unsubscribe(start_recording)
99 if start_playback:
100 pubsub.unsubscribe(start_playback)
101 if stop:
102 pubsub.unsubscribe(stop)
103
105 global DR_Play, _the_player
106 # return the next data packet of the type data_type
107 if DR_Play and _the_player:
108 return _the_player.get_data(data_type)
109 raise DataRecordingError('Data Playback not active')
110
112 # return a list of headers used for setting the start point
113 global DR_Play, _the_player
114 if DR_Play and _the_player:
115 return _the_player.get_headers()
116 raise DataRecordingError('Data Playback not active')
117
119 # set/reset the start point of the recording file
120 global DR_Play, _the_player
121 if DR_Play and _the_player:
122 _the_player.set_start(start)
123 else:
124 raise DataRecordingError('Data Playback not active')
125
127 global DR_On, _the_recorder
128 if DR_On and _the_recorder:
129 _the_recorder.record(dr_type, dr_data, dr_class)
130 elif __debug__:
131 raise DataRecordingError('Data Recording not active')
132
134 "return the current file name being used for recording or playback"
135 if _the_recorder:
136 return _the_recorder._file_name
137 elif _the_player:
138 return _the_player._file_name
139
140 #-------------------------------------------------------------------------------
143 self._type=dr_type
144 self._data=dr_data
145 self._time=time.time()
146 if klass:
147 try:
148 self._class_module=klass.__module__
149 self._class_name=klass.__name__
150 except:
151 klass=klass.__class__
152 self._class_module=klass.__module__
153 self._class_name=klass.__name__
154 else:
155 self._class_module=None
156 self._class_name=None
157
161 self._data=data
163 # return a string rep suitable for log, protocol log, and analyzer
164 # display
165 t=time.localtime(self._time)
166 _s="%d:%02d:%02d.%03d " % (t[3], t[4], t[5],
167 int((self._time-int(self._time))*1000))
168 if self._type==DR_Type_Note:
169 _s+=self._data
170 else:
171 # data
172 _s+=" %s - %d bytes\n" % (DR_Type_Name.get(self._type, 'Data'),
173 len(self._data))
174 if self._class_module and self._class_name:
175 _s+="<#! %s.%s !#>\n" % (self._class_module, self._class_name)
176 _s+=common.datatohexstring(self._data)
177 _s+='\n'
178 return _s
180 # return a summary string of this record
181 global DR_Type_Name
182 t=time.localtime(self._time)
183 _s="%d:%02d:%02d.%03d " % (t[3], t[4], t[5],
184 int((self._time-int(self._time))*1000))
185 if self._type==DR_Type_Note:
186 _s+=self._data
187 else:
188 _s+=DR_Type_Name.get(self._type, '<Unknown>')
189 if len(_s)>80:
190 _s=_s[:75]+'<...>'
191 return _s
192
193 #-------------------------------------------------------------------------------
199
201 # check to ensure that this file has the right header
202 try:
203 return file(self._file_name, 'rb').read(len(DR_Signature))==DR_Signature
204 except IOError:
205 return False
206 except:
207 if __debug__:
208 raise
209 return False
210
215
216 #-------------------------------------------------------------------------------
219 super(DR_Rec_File, self).__init__(file_name)
220 self._pause=None
221 if not append:
222 self._file=file(self._file_name, 'wb')
223 self._write_header()
224 self._valid=True
225 else:
226 if self._check_header():
227 self._file=file(self._file_name, 'ab')
228 self._valid=True
229 else:
230 self._valid=False
231
233 # write the header to this file
234 self._file.write(DR_Signature)
235 _s=''
236 for e in DR_Version:
237 _s+=struct.pack('B', e)
238 self._file.write(_s)
239
242
243
245 if self._pause and (self._pause & dr_type):
246 # not recording this type
247 return
248 if self._file:
249 _t=threading.Thread(target=self._write_record,
250 args=(dr_type, dr_data, dr_class))
251 _t.start()
252
254 _rec=DR_Record(dr_type, dr_data, dr_class)
255 _s=cPickle.dumps(_rec)
256 self._file.write(DR_Rec_Marker+struct.pack('<L', len(_s))+_s)
257
259 global DR_On, _the_recorder
260 self._file.close()
261 self._file=None
262 self._valid=False
263 DR_On=False
264 _the_recorder=None
265
267 global DR_On, _the_recorder
268 if self._file is None and self._file_name:
269 self._file=file(self._file_name, 'ab')
270 self._valid=True
271 DR_On=True
272 _the_recorder=self
273
278
279 #-------------------------------------------------------------------------------
282 super(DR_Read_File, self).__init__(file_name)
283 if self._check_header():
284 self._valid=True
285 self._file=file(self._file_name, 'rb')
286 else:
287 self._valid=False
288 self._data=[]
289 self._read_data()
290 self._start_index=0
291 self._end_index=len(self._data)
292 self._current_index=0
293
295 # read one DR record and return
296 _marker=self._file.read(len(DR_Rec_Marker))
297 if _marker!=DR_Rec_Marker:
298 # marker not found
299 return None
300 try:
301 _slen=self._file.read(struct.calcsize('L'))
302 _data_len=struct.unpack('<L', _slen)[0]
303 _sdata=self._file.read(_data_len)
304 return cPickle.loads(_sdata)
305 except (MemoryError, cPickle.UnpicklingError):
306 return None
307 except:
308 if __debug__:
309 raise
310 return None
311
313 # read from the file and recontruct the data
314 # first,get pass the header
315 self._file.seek(len(DR_Signature)+len(DR_Version))
316 _rec=self._read_rec()
317 while _rec:
318 self._data.append(_rec)
319 _rec=self._read_rec()
320 self._file.close()
321
323 # return all the data as a big string for display purposes
324 _s=''
325 for e in self._data:
326 _s+=`e`
327 return _s
331
335
337 global DR_Play, _the_player
338 self._current_index=self._start_index
339 DR_Play=True
340 _the_player=self
341
346
348 # return the data of the type 'data_type'
349 if self._current_index>=self._end_index:
350 # end of data
351 raise DataRecordingError('No more data available for playback')
352 _idx=self._current_index
353 for i,e in enumerate(self._data[_idx:]):
354 if e._type==data_type:
355 self._current_index+=i+1
356 return e.get()
357 # no such data
358 raise DataRecordingError('Failed to find playback data type')
359
| Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0.1 on Sun Jan 24 16:21:06 2010 | http://epydoc.sourceforge.net |