class TestCase(DefaultTestFixture): def setUp(self): DefaultTestFixture.setUp(self) self.formatter = SGMLFormatter() return def test_complete_output(self): self.formatter.open_tag('html') self.formatter.open_tag('title') self.formatter.add_text('title text') self.formatter.close_tag() self.formatter.open_tag('body') self.formatter.add_text('body text') self.formatter.single_tag('br') self.formatter.open_close_tag('img', src='image_source', x='image_x', y='image_y') self.formatter.close_tag('body') output = self.formatter.output_complete() self.failUnless(output == _html, 'output = %r\n\nhtml = %r' % (output, _html)) def test_partial_output(self): self.formatter.open_tag('html') self.formatter.open_tag('title') self.formatter.add_text('title text') self.formatter.close_tag() output = self.formatter.output() self.failUnless(output == _html[0:35], 'output = %r\n\nhtml = %r' % (output, _html[0:35])) self.formatter.open_tag('body') output = self.formatter.output() self.failUnless(output == _html[35:43], 'output = %r\n\nhtml = %r' % (output, _html[35:43])) self.formatter.add_text('body text') self.formatter.single_tag('br') self.formatter.open_close_tag('img', src='image_source', x='image_x', y='image_y') self.formatter.close_tag('body') self.formatter.close_tag() output = self.formatter.output() self.failUnless(output == _html[43:], 'output = %r\n\nhtml = %r' % (output, _html[43:]))
class TestCase(DefaultTestFixture): def setUp(self): DefaultTestFixture.setUp(self) self.formatter = SGMLFormatter() return def test_complete_output(self): self.formatter.open_tag('html') self.formatter.open_tag('title') self.formatter.add_text('title text') self.formatter.close_tag() self.formatter.open_tag('body') self.formatter.add_text('body text') self.formatter.single_tag('br') self.formatter.open_close_tag('img', src='image_source', x='image_x', y='image_y') self.formatter.close_tag('body') output = self.formatter.output_complete() self.failUnless(output == _html, 'output = %r\n\nhtml = %r' % (output, _html)) def test_partial_output(self): self.formatter.open_tag('html') self.formatter.open_tag('title') self.formatter.add_text('title text') self.formatter.close_tag() output = self.formatter.output() self.failUnless(output == _html[0:35], 'output = %r\n\nhtml = %r' % (output, _html[0:35])) self.formatter.open_tag('body') output = self.formatter.output() self.failUnless(output == _html[35:43], 'output = %r\n\nhtml = %r' % (output, _html[35:43])) self.formatter.add_text('body text') self.formatter.single_tag('br') self.formatter.open_close_tag('img', src='image_source', x='image_x', y='image_y') self.formatter.close_tag('body') self.formatter.close_tag() output = self.formatter.output() self.failUnless(output == _html[43:], 'output = %r\n\nhtml = %r' % (output, _html[43:]))
def output(self, type='all', application='all', sort_order='descending', records='25'): self._header() self._table_values(type, application, sort_order, records) children = self._flatten_children() self.open_tag('tr') self.open_tag('td', width=1, Class='header_row') self.add_text('Seq') self.close_tag('td') self.open_tag('td', width=self.row_1_width, Class='header_row') self.add_text('Timestamp') self.close_tag('td') self.open_tag('td', width=self.row_2_width, Class='header_row') self.add_text('Application') self.close_tag('td') self.open_tag('td', width=self.row_3_width, Class='header_row') self.add_text('Type') self.close_tag('td') self.open_tag('td', width=self.row_4_width, Class='header_row') self.add_text('Message') self.close_tag('td') self.close_tag('tr') even_row = 0 for child in children: if type == 'all' and application == 'all': self._wrap_child(child, even_row) if even_row: even_row = 0 else: even_row = 1 elif type == 'all' and application != 'all': if re.match(application, child.application): self._wrap_child(child, even_row) if even_row: even_row = 0 else: even_row = 1 elif application == 'all' and type != 'all': if child.type == type: self._wrap_child(child, even_row) if even_row: even_row = 0 else: even_row = 1 elif application != 'all' and type != 'all': if child.type == type and re.match(application, child.application): self._wrap_child(child, even_row) if even_row: even_row = 0 else: even_row = 1 self._footer() return SGMLFormatter.output(self)
def output(self, type = 'all',application = 'all', sort_order='descending',records='25'): self._header() self._table_values(type,application,sort_order,records) children = self._flatten_children() self.open_tag('tr') self.open_tag('td',width=1,Class='header_row') self.add_text('Seq') self.close_tag('td') self.open_tag('td',width=self.row_1_width,Class='header_row') self.add_text('Timestamp') self.close_tag('td') self.open_tag('td',width=self.row_2_width,Class='header_row') self.add_text('Application') self.close_tag('td') self.open_tag('td',width=self.row_3_width,Class='header_row') self.add_text('Type') self.close_tag('td') self.open_tag('td',width=self.row_4_width,Class='header_row') self.add_text('Message') self.close_tag('td') self.close_tag('tr') even_row = 0 for child in children: if type == 'all' and application == 'all': self._wrap_child(child,even_row) if even_row: even_row = 0 else: even_row = 1 elif type =='all' and application != 'all': if re.match(application, child.application): self._wrap_child(child,even_row) if even_row: even_row = 0 else: even_row = 1 elif application == 'all' and type != 'all': if child.type == type: self._wrap_child(child,even_row) if even_row: even_row = 0 else: even_row = 1 elif application != 'all' and type != 'all': if child.type == type and re.match(application,child.application): self._wrap_child(child,even_row) if even_row: even_row = 0 else: even_row = 1 self._footer() return SGMLFormatter.output(self)
def format(self, data, pretty_format=None): # Organize all log data (list of time-based dicts) into a dict of # point-based lists. (Dict of lists could get REALLY large; may # need to do only one point at a time... # self._channels:K=col_name,V=col_dict # col_dict:K='column_node':,'values':list_of_2tuples # list_of_2tuples: [(timestamp,value),] # Only want records for preceding self.capture_period-hr period: end_time = time.time() start_time = self.parent.last_time() # ASSUME that parent is a periodic exporter... # Comment out line below, in favor of line above, because FSG tends to # disable their FTP server (effectively) for days at a time, but still # want all the data gathered during those blackout periods to go to the # FTP server when the server reappears with respect to the Mediator. # This change means that the FTP server recvs table-formatted data all # the way back to the last successful export, regardless of the # actual size of that data: #start_time = end_time - (self.capture_period * 3600.0) data_to_send = 0 data = data[:] self.debug_print('Data: %s' % data,None,1) removed_channels = [] for log_rec_dict in data: timestamp = log_rec_dict['timestamp'] if (timestamp < start_time) \ or (timestamp > end_time): continue for channel_name in log_rec_dict.keys(): if channel_name == 'timestamp': continue if not self._channels.has_key(channel_name): if not channel_name in removed_channels: msglog.log('fsg:xml_formatter',msglog.types.ERR, \ 'Channel %s has been removed from the configuration.' \ % channel_name) removed_channels.append(channel_name) continue data_to_send = 1 self._channels[channel_name]['values'].append((timestamp,log_rec_dict[channel_name],)) channel_names = self._channels.keys() # it's a list # Organize all data from exception log, if any: exception_dicts = {} # K:trigger name, V:time-sorted list of 2tuples # (timestamp, message) if not self._exception_log is None: if self._PDO.exception_log_last_time > start_time: start_time = self._PDO.exception_log_last_time + 0.00001 # do not re-send already-sent data exception_data = self._exception_log.get_range('timestamp',start_time,end_time) for log_rec_dict in exception_data: trigger_node_url = log_rec_dict['trigger_node_url'] trigger_node = as_node(trigger_node_url) assert isinstance(trigger_node, FsgComparisonTrigger), \ 'Node %s should be FsgComparisonTrigger, is %s' \ % (trigger_node.name, trigger_node.__class__) timestamp = log_rec_dict['timestamp'] trigger_node_msg = log_rec_dict['trigger_node_msg'] if not exception_dicts.has_key(trigger_node_url): exception_dicts[trigger_node_url] = {'trigger_node_url':trigger_node_url,'timestamps':[(timestamp,trigger_node_msg,)]} else: exception_dicts[trigger_node_url]['timestamps'].append((timestamp,trigger_node_msg,)) self._PDO.exception_log_last_time = timestamp self._PDO.save() if (data_to_send == 0) and (len(exception_dicts) == 0): msglog.log('fsg:xml_formatter',msglog.types.INFO,'No data or exceptions to send.') return None # nothing to send # Create an output stream to minimize the combined size of the XML # file and the remaining point_dicts contents during formatting: stream = StreamWithCallback(self.output_callback) stream.set_meta('channel_names',channel_names) stream.set_meta('exception_data',exception_dicts.values()) # pass in a list of "values" (dicts), to allow easy iteration stream.set_meta('index',0) # number of point time-value lists written to XML output stream formatter = SGMLFormatter() # Write opening tags: formatter.open_tag('data', info=self.location_info, key=self.location_key ) formatter.open_tag('device', info=self.panel_info, key=self.panel_key ) output = formatter.output() self.debug_print(output,None,1) stream.write(output) stream.set_meta('formatter',formatter) stream.set_meta('remaining', '') data_mode = 'channels' if data_to_send == 0: data_mode = 'exceptions' # no data for channels, so skip 'em stream.set_meta('data_mode',data_mode) return stream