(self)
| 532 | self.base.after(100, self._force_focus) |
| 533 | |
| 534 | def generate_graph(self): |
| 535 | log.info("generate_graph: option=%s to=%s from=%s", self.option.get(), self.to_ip.get(), self.from_ip.get()) |
| 536 | if self.details_fetch == 0: |
| 537 | t, _ = self._run_in_thread(communication_details_fetch.TrafficDetailsFetch, "sock") |
| 538 | t1, _ = self._run_in_thread(device_details_fetch.FetchDeviceDetails("ieee").fetch_info) |
| 539 | self._spin_start("Resolving hosts") |
| 540 | self._poll_thread(t) |
| 541 | self._poll_thread(t1) |
| 542 | self._spin_stop("✓ Hosts resolved") |
| 543 | |
| 544 | self.details_fetch = 1 |
| 545 | rpt = report_generator.ReportGenerator(self.destination_report.get(), self.filename) |
| 546 | threading.Thread(target=rpt.communicationDetailsReport, daemon=True).start() |
| 547 | threading.Thread(target=rpt.deviceDetailsReport, daemon=True).start() |
| 548 | |
| 549 | options = (self.option.get() + "_" + self.to_ip.get().replace(".", "-") |
| 550 | + "_" + self.from_ip.get().replace(".", "-")) |
| 551 | self.image_file = os.path.join(self.destination_report.get(), "Report", self.filename + "_" + options + ".png") |
| 552 | if not os.path.exists(self.image_file): |
| 553 | t1, exc_box = self._run_in_thread( |
| 554 | plot_lan_network.PlotLan, |
| 555 | self.filename, self.destination_report.get(), |
| 556 | self.option.get(), self.to_ip.get(), self.from_ip.get() |
| 557 | ) |
| 558 | self._spin_start("Rendering graph") |
| 559 | self._poll_thread(t1) |
| 560 | if exc_box: |
| 561 | self._spin_stop("✗ Render failed", ok=False) |
| 562 | log.error("Graph generation failed: %s", exc_box[0]) |
| 563 | mb.showerror("Graph Error", f"Graph generation failed:\n{exc_box[0]}") |
| 564 | return |
| 565 | self._spin_stop("✓ Graph ready") |
| 566 | self.label.grid_forget() |
| 567 | self.load_image() |
| 568 | else: |
| 569 | self.label.grid_forget() |
| 570 | self.load_image() |
| 571 | self._populate_packet_table() |
| 572 | # Both graph buttons become available once a graph exists |
| 573 | self.ibutton['state'] = 'normal' |
| 574 | self.browser_button['state'] = 'normal' |
| 575 | |
| 576 | def gimmick(self): |
| 577 | import interactive_gui |
no test coverage detected