class DiffWindow(gtk.Window): def __init__(self, scans): """scans in the format: {"scan_title":parsed_scan} """ gtk.Window.__init__(self) self.set_title(_("Compare Results")) self.scans = scans self.umit_conf = UmitConf() self.colors = Colors() # Diff views self.text_view = DiffText(self.colors, self.umit_conf.colored_diff) self.compare_view = DiffTree(self.colors) self.temp_html_file = None self._create_widgets() self._pack_widgets() self._connect_widgets() # Settings if self.umit_conf.diff_mode == "text": self.text_mode.set_active(True) else: self.compare_mode.set_active(True) self.check_color.set_active(self.umit_conf.colored_diff) # Initial Size Request self.initial_size = self.size_request() def _show_help(self, action): webbrowser.open("file://%s" % os.path.join(Path.docs_dir, "help.html"), new=2) def _create_widgets(self): self.main_vbox = HIGVBox() self.hbox_mode = HIGHBox() self.hbox_settings = HIGHBox() self.hbox_buttons = HIGHBox() self.hbox_result = HIGHBox() self.btn_open_browser = HIGButton(_("Open in Browser"), stock=gtk.STOCK_EXECUTE) self.btn_help = HIGButton(stock=gtk.STOCK_HELP) self.btn_close = HIGButton(stock=gtk.STOCK_CLOSE) self.check_color = gtk.CheckButton(_("Enable colored diffies")) self.btn_legend = HIGButton(_("Color Descriptions"), stock=gtk.STOCK_SELECT_COLOR) self.text_mode = gtk.ToggleButton(_("Text Mode")) self.compare_mode = gtk.ToggleButton(_("Compare Mode")) self.vpaned = gtk.VPaned() self.hpaned = gtk.HPaned() self.scan_chooser1 = ScanChooser(self.scans, "1") self.scan_chooser2 = ScanChooser(self.scans, "2") self.scan_buffer1 = self.scan_chooser1.get_buffer() self.scan_buffer2 = self.scan_chooser2.get_buffer() def _pack_widgets(self): self.main_vbox.set_border_width(6) self.vpaned.pack1(self.hpaned, True, False) self.vpaned.pack2(self.hbox_result) self.hpaned.pack1(self.scan_chooser1, True, False) self.hpaned.pack2(self.scan_chooser2, True, False) self.hbox_buttons._pack_expand_fill(self.btn_help) self.hbox_buttons._pack_expand_fill(self.btn_legend) self.hbox_buttons._pack_expand_fill(self.btn_open_browser) self.hbox_buttons._pack_expand_fill(self.btn_close) self.hbox_buttons.set_homogeneous(True) self.hbox_mode.set_homogeneous(True) self.hbox_mode.pack_start(self.text_mode) self.hbox_mode.pack_start(self.compare_mode) self.hbox_settings._pack_noexpand_nofill(self.hbox_mode) self.hbox_settings._pack_expand_fill(self.check_color) self.main_vbox._pack_expand_fill(self.vpaned) self.main_vbox._pack_noexpand_nofill(self.hbox_settings) self.main_vbox._pack_noexpand_nofill(self.hbox_buttons) self.add(self.main_vbox) def _connect_widgets(self): self.connect("delete-event", self.close) self.btn_legend.connect("clicked", self.show_legend_window) self.btn_help.connect("clicked", self._show_help) self.btn_close.connect("clicked", self.close) self.btn_open_browser.connect("clicked", self.open_browser) self.check_color.connect("toggled", self._set_color) self.text_mode.connect("clicked", self._change_to_text) self.compare_mode.connect("clicked", self._change_to_compare) self.scan_chooser1.exp_scan.connect('activate', self.resize_vpane) self.scan_chooser2.exp_scan.connect('activate', self.resize_vpane) self.scan_chooser1.connect('changed', self.refresh_diff) self.scan_chooser2.connect('changed', self.refresh_diff) def open_browser(self, widget): text1 = self.scan_chooser1.nmap_output text2 = self.scan_chooser2.nmap_output if text1 is None or text2 is None: alert = HIGAlertDialog( message_format='<b>'+_('Select Scan')+'</b>', secondary_text=_("You must select two different scans to \ generate diff.")) alert.run() alert.destroy() return False if text1 == '' and text2 == '': alert = HIGAlertDialog( message_format='<b>'+_('No Text Output')+'</b>', secondary_text=_("Neither of the scans you selected has \ any text output. (Scans loaded from plain Nmap XML output files do not contain \ text output.) The HTML diff shows only differences between text output, so \ there is nothing to show.")) alert.run() alert.destroy() return False # True tells splitlines to keep line endings. text1 = text1.splitlines(True) text2 = text2.splitlines(True) if self.temp_html_file is not None: self.temp_html_file.close() # A NamedTemporaryFile is deleted when it is closed. self.temp_html_file = tempfile.NamedTemporaryFile(suffix = ".html", prefix = "zenmap-diff-") if use_html: diff = DiffHtml(text1, text2) diff = diff.generate() self.temp_html_file.write(''.join(diff)) else: diff = Diff(text1, text2) diff = diff.generate () diff.insert(0, '''<pre>(This diff is been shown in pure text \ because you dont have Python 2.4 or higher.)\n''') diff.append('</pre>') self.temp_html_file.writelines(diff) self.temp_html_file.flush() webbrowser.open("file://" + self.temp_html_file.name, autoraise=1) def show_legend_window(self, widget): legend_window = DiffLegendWindow(self.colors) legend_window.run() legend_window.destroy() self.refresh_diff(None) def refresh_diff (self, widget): """This method is called whenever the diff output might have changed, such as when a different scan was selected in one of the choosers.""" if self.compare_mode.get_active(): # Graphical comparison mode. parsed1 = self.scan_chooser1.parsed_scan parsed2 = self.scan_chooser2.parsed_scan if parsed1 is not None and parsed2 is not None: self.compare_view.make_diff(parsed1, parsed2) else: self.compare_view.clear_diff_tree() self.compare_view.activate_color(self.check_color.get_active()) else: # Text comparison mode. text1 = self.scan_chooser1.nmap_output text2 = self.scan_chooser2.nmap_output if text1 is not None and text2 is not None: diff = Diff(text1.split('\n'), text2.split('\n')) self.text_view.set_text('\n'.join(diff.generate_without_banner())) else: self.text_view.clear() self.text_view.activate_color(self.check_color.get_active()) def resize_vpane(self, widget): exp1 = not widget.get_expanded() if widget == self.scan_chooser1.exp_scan: exp2 = self.scan_chooser2.exp_scan.get_expanded() else: exp2 = self.scan_chooser1.exp_scan.get_expanded() if not exp1 and not exp2: self.vpaned.compute_position(-1, 0, 500) self.size_allocate(gtk.gdk.Rectangle(width=self.initial_size[0], height=self.initial_size[1])) self.queue_resize() def _change_to_text(self, widget): if not widget.get_active(): return self.umit_conf.diff_mode = "text" children = self.hbox_result.get_children() if children: self.hbox_result.remove(children[0]) self.compare_view.hide() self.hbox_result._pack_expand_fill(self.text_view) self.text_view.show_all() self.compare_mode.set_active(False) self.refresh_diff(None) def _change_to_compare(self, widget): if not widget.get_active(): return self.umit_conf.diff_mode = "compare" children = self.hbox_result.get_children() if children: self.hbox_result.remove(children[0]) self.text_view.hide() self.hbox_result._pack_expand_fill(self.compare_view) self.compare_view.show_all() self.text_mode.set_active(False) self.refresh_diff(None) def _set_color(self, widget): activate = widget.get_active() self.umit_conf.colored_diff = activate self.compare_view.activate_color(activate) self.text_view.activate_color(activate) def close(self, widget=None, extra=None): if self.temp_html_file is not None: self.temp_html_file.close() self.destroy()