class FileField(BaseFieldMixin, QHBoxLayout): def __init__(self, tab, config_path): self.name_field = QLineEdit() self.name_field.setEnabled(False) self.file_button = QPushButton("Select") self.file_button.clicked.connect(self.on_select_clicked) super().__init__(tab, config_path) self.addWidget(self.name_field) self.addWidget(self.file_button) def on_select_clicked(self): if self.main_window.config.path: config_dir = os.path.dirname(self.main_window.config.path) else: config_dir = os.getcwd() file_path = QFileDialog.getSaveFileName( self.tab, caption="Select a file...", dir=config_dir, options=QFileDialog.DontConfirmOverwrite, )[0] if file_path: self.name_field.setText(os.path.relpath(file_path, config_dir)) @property def change_signal(self): return self.name_field.textChanged def on_change(self, t): self.main_window.set_working_value(self.config_path, t) def update_ui_from_config(self, config): new_value = config.get_template_resolved_value(self.config_path, "") if new_value != self.name_field.text: self.name_field.setText(new_value) def show(self): self.file_button.show() self.name_field.show() def hide(self): self.file_button.hide() self.name_field.hide()
class Controls(QWidget): def __init__(self, parent, init_label, mainfunction, quitfunction): super().__init__(parent) self.button = QPushButton(init_label) self.button.clicked.connect(mainfunction) self.button.setAutoDefault(True) quitbutton = QPushButton('終わる') quitbutton.setStyleSheet('background-color: #c00; color: white;') quitbutton.clicked.connect(quitfunction) layout = QHBoxLayout() layout.addWidget(self.button) layout.addWidget(quitbutton) self.setLayout(layout) def set_button(self, label): self.button.setText(label) def hide_button(self): self.button.hide()
class Pryme2(QWidget): notify_request = Signal(str) def __init__(self, parent=None): super(Pryme2, self).__init__(parent) self.timer_instances = (SimpleTimer(), AlarmClock(), PomoTimer()) self.timer_selection = QComboBox(self) for t in self.timer_instances: self.timer_selection.addItem(t.name) self.timer = self.timer_instances[0] self.commitment_textbox = QLineEdit(self) self.commitment_textbox.setPlaceholderText( 'What do you want to commit?') self.commitment_textbox.setClearButtonEnabled(True) self.commit_done_btn = QPushButton('&Done', self) self.start_btn = QPushButton('&Start', self) self.abort_btn = QPushButton('&Abort', self) self.abort_btn.hide() self.pause_btn = QPushButton('&Pause', self) self.pause_btn.hide() self.resume_btn = QPushButton('&Resume', self) self.resume_btn.hide() self.tray = QSystemTrayIcon(self) self.tray.setIcon(QIcon('pryme-logo.svg')) self.tray.show() self.set_ui() self.set_connection() self.show() def set_ui(self): self.hlayout = QHBoxLayout() self.hlayout.addWidget(self.commitment_textbox) self.hlayout.addWidget(self.commit_done_btn) self.commit_group = QGroupBox('Commitment') self.commit_group.setLayout(self.hlayout) self.vlayout = QVBoxLayout() self.vlayout.addWidget(self.commit_group) self.vlayout.addWidget(self.timer_selection) self.vlayout.addWidget(self.timer) self.bottom_hlayout = QHBoxLayout() self.bottom_hlayout.addWidget(self.start_btn) self.bottom_hlayout.addWidget(self.abort_btn) self.bottom_hlayout.addWidget(self.pause_btn) self.bottom_hlayout.addWidget(self.resume_btn) self.vlayout.addLayout(self.bottom_hlayout) self.setLayout(self.vlayout) def set_connection(self): self.timer_selection.currentIndexChanged.connect(self.change_timer) self.connect_timer() def connect_timer(self): self.start_btn.clicked.connect(self.timer.start) self.abort_btn.clicked.connect(self.timer.abort) self.timer.finished.connect(self.notify) self.timer.started.connect(self.set_timer_active_ui) self.timer.aborted.connect(self.set_timer_deactive_ui) self.timer.finished.connect(self.set_timer_deactive_ui) if hasattr(self.timer, 'pause'): self.pause_btn.clicked.connect(self.timer.pause) self.resume_btn.clicked.connect(self.timer.resume) self.timer.paused.connect(self.activate_resume_button) def disconnect_timer(self): self.timer.disconnect(self) self.start_btn.disconnect(self.timer) self.abort_btn.disconnect(self.timer) self.resume_btn.disconnect(self.timer) def notify(self): title = self.commitment_textbox.text() if not title: title = 'Time up!' message = self.timer.get_notify_message() if not message: print(message) message = 'Time up!' self.tray.showMessage(title, message) subprocess.Popen(cmd.split()) def set_ui_enabled(self, enable: bool): self.timer_selection.setEnabled(enable) self.commitment_textbox.setEnabled(enable) def set_timer_active_ui(self): self.activate_start_button(False) self.set_ui_enabled(False) def set_timer_deactive_ui(self): self.activate_start_button(True) self.set_ui_enabled(True) def activate_start_button(self, activate: bool): if activate: # active start button self.start_btn.show() self.abort_btn.hide() self.pause_btn.hide() self.resume_btn.hide() else: self.abort_btn.show() self.start_btn.hide() if hasattr(self.timer, 'pause'): self.pause_btn.show() self.resume_btn.hide() def activate_resume_button(self): self.pause_btn.hide() self.resume_btn.show() @Slot(int) def change_timer(self, index): self.disconnect_timer() self.timer.hide() self.vlayout.replaceWidget(self.timer, self.timer_instances[index]) self.timer = self.timer_instances[index] self.connect_timer() self.timer.show()
class JobsWindow(QWidget): def __init__(self): super().__init__() self.quit_button = QPushButton("Quit", self) self.update_button = QPushButton("Update Data", self) self.enter_data = QPushButton("Enter Data", self) self.data_button = QPushButton("Run Data Visualization", self) self.back_button = QPushButton("Back", self) self.text_visualization_button = QPushButton("Text Visualization", self) self.map_visualization = QPushButton("Map Visualization", self) self.order_selector_text = QComboBox(self) self.data_selector_map = QComboBox(self) self.data_visualization_label = QLabel("Welcome to data visualization!", self) self.welcome_label = QLabel("Welcome to Jobs data Visualization.", self) self.list_control = None self.update_label_01 = QLabel("", self) self.update_label_02 = QLabel("", self) self.update_label_03 = QLabel("", self) self.update_label_04 = QLabel("", self) self.update_label_05 = QLabel("", self) self.update_label_06 = QLabel("", self) self.update_label_07 = QLabel("", self) self.update_label_08 = QLabel("", self) self.excel_label = QLabel("Excel Spreadsheet:", self) self.update_information = QLabel( "If you would like to update a single entry please select the table and enter all of its information.\n" "If you would like to import from a spreadsheet type it into the box on the right and select the table.\n" "When you are ready with which ever function press Enter Data.\n" "For any data you want to append make sure the id is None.\n" "Also only work from one method at a time and make sure he other is empty.", self) self.table_selection = QComboBox(self) self.update_box_01 = QLineEdit(self) self.update_box_02 = QLineEdit(self) self.update_box_03 = QLineEdit(self) self.update_box_04 = QLineEdit(self) self.update_box_05 = QLineEdit(self) self.update_box_06 = QLineEdit(self) self.update_box_07 = QLineEdit(self) self.update_box_08 = QLineEdit(self) self.update_excel_selection = QLineEdit(self) self.list_control = None self.setup_window() def setup_window(self): self.setWindowTitle("Jobs Window") display_list = QListWidget(self) self.list_control = display_list display_list.resize(500, 350) self.setGeometry(50, 50, 500, 500) self.quit_button.clicked.connect(QApplication.instance().quit) self.quit_button.resize(self.quit_button.sizeHint()) self.quit_button.move(415, 450) self.update_button.clicked.connect(self.update_data) self.update_button.move(200, 200) self.data_button.clicked.connect(self.run_data_visualization) self.data_button.move(175, 250) self.back_button.clicked.connect(self.go_back) self.back_button.move(25, 450) self.data_visualization_label.move(20, 400) self.text_visualization_button.move(400 - self.text_visualization_button.width(), 600) self.order_selector_text.move(self.text_visualization_button.x(), self.text_visualization_button.y()+self.text_visualization_button.height()+10) self.text_visualization_button.clicked.connect(self.text_visualization) self.map_visualization.move(self.text_visualization_button.x() + self.text_visualization_button.width(), self.text_visualization_button.y()) self.data_selector_map.move(self.map_visualization.x(), self.map_visualization.y()+self.map_visualization.height()+10) self.map_visualization.clicked.connect(self.run_map_visualization) self.welcome_label.move(150, 150) self.update_box_01.move(150, 30) self.update_box_02.move(150, 60) self.update_box_03.move(150, 90) self.update_box_04.move(150, 120) self.update_box_05.move(150, 150) self.update_box_06.move(150, 180) self.update_box_07.move(150, 210) self.update_box_08.move(150, 240) self.excel_label.move(340, 70) self.update_excel_selection.move(340, 90) self.update_information.move(25, 325) self.update_label_01.setGeometry(5, 30, 145, 20) self.update_label_02.setGeometry(5, 60, 145, 20) self.update_label_03.setGeometry(5, 90, 145, 20) self.update_label_04.setGeometry(5, 120, 145, 20) self.update_label_05.setGeometry(5, 150, 145, 20) self.update_label_06.setGeometry(5, 180, 145, 20) self.update_label_07.setGeometry(5, 210, 145, 20) self.update_label_08.setGeometry(5, 240, 145, 20) self.table_selection.setGeometry(10, 10, 145, 20) self.enter_data.move(10, 260) self.enter_data.clicked.connect(self.import_data) self.table_selection.addItem("---") self.table_selection.addItem("Schools") self.table_selection.addItem("Jobs") self.order_selector_text.addItem("---") self.order_selector_text.addItem("ASC") self.order_selector_text.addItem("DESC") self.data_selector_map.addItem("---") self.data_selector_map.addItem("Employment to Graduates") self.data_selector_map.addItem("Average Salary to Average Declining Balance Percent") self.table_selection.currentIndexChanged.connect(self.update_selection) self.hidden_at_start() self.show() def hidden_at_start(self): self.hide_update_boxes() self.list_control.hide() self.update_information.hide() self.map_visualization.hide() self.text_visualization_button.hide() self.data_visualization_label.hide() self.back_button.hide() self.table_selection.hide() self.enter_data.hide() self.update_excel_selection.hide() self.excel_label.hide() self.data_selector_map.hide() self.order_selector_text.hide() def hide_update_boxes(self): self.update_box_01.hide() self.update_box_02.hide() self.update_box_03.hide() self.update_box_04.hide() self.update_box_05.hide() self.update_box_06.hide() self.update_box_07.hide() self.update_box_08.hide() self.update_label_01.setText("") self.update_label_02.setText("") self.update_label_03.setText("") self.update_label_04.setText("") self.update_label_05.setText("") self.update_label_06.setText("") self.update_label_07.setText("") self.update_label_08.setText("") def update_data(self): self.update_button.hide() self.data_button.hide() self.back_button.show() self.welcome_label.hide() self.table_selection.show() self.enter_data.show() self.update_information.show() self.update_excel_selection.show() self.excel_label.show() def update_selection(self): self.hide_update_boxes() if self.table_selection.currentText() == "Jobs": self.update_box_01.show() self.update_label_01.setText("jobs_id") self.update_box_02.show() self.update_label_02.setText("state_name") self.update_box_03.show() self.update_label_03.setText("occupation_code") self.update_box_04.show() self.update_label_04.setText("tittle") self.update_box_05.show() self.update_label_05.setText("employment") self.update_box_06.show() self.update_label_06.setText("salary_25th_percentile") elif self.table_selection.currentText() == "Schools": self.update_box_01.show() self.update_label_01.setText("school_id") self.update_box_02.show() self.update_label_02.setText("name") self.update_box_03.show() self.update_label_03.setText("state_abrev") self.update_box_04.show() self.update_label_04.setText("size_2017") self.update_box_05.show() self.update_label_05.setText("size_2018") self.update_box_06.show() self.update_label_06.setText("earnings") self.update_box_07.show() self.update_label_07.setText("repayment_overall") self.update_box_08.show() self.update_label_08.setText("repayment_cohort") def import_data(self): if self.update_excel_selection.text() == "": if self.table_selection.currentText() == "Jobs": information_to_update = [self.update_box_01.text(), self.update_box_02.text(), self.update_box_03.text(), self.update_box_04.text(), self.update_box_05.text(), self.update_box_06.text()] jobs.update_data_from_list(information_to_update, "Jobs", "jobs_db.sqlite") elif self.table_selection.currentText() == "Schools": information_to_update = [self.update_box_01.text(), self.update_box_02.text(), self.update_box_03.text(), self.update_box_04.text(), self.update_box_05.text(), self.update_box_06.text(), self.update_box_07.text(), self.update_box_08.text()] jobs.update_data_from_list(information_to_update, "Schools", "jobs_db.sqlite") else: if self.table_selection.currentText() == "Jobs": jobs.update_data_from_excel(self.update_excel_selection.text(), "Jobs", "jobs_db.sqlite") elif self.table_selection.currentText() == "Schools": jobs.update_data_from_excel(self.update_excel_selection.text(), "Jobs", "jobs_db.sqlite") def run_data_visualization(self): self.update_button.hide() self.data_button.hide() self.data_visualization_label.show() self.back_button.show() self.setGeometry(50, 50, 800, 800) self.back_button.move(25, 750) self.quit_button.move(715, 750) self.welcome_label.hide() self.map_visualization.show() self.text_visualization_button.show() self.data_selector_map.show() self.order_selector_text.show() def go_back(self): self.back_button.hide() self.update_button.show() self.data_button.show() self.data_visualization_label.hide() self.setGeometry(50, 50, 500, 500) self.back_button.move(25, 450) self.quit_button.move(415, 450) self.welcome_label.show() self.hidden_at_start() def text_visualization(self): self.list_control.clear() conn, cursor = jobs.open_db("jobs_db.sqlite") if self.order_selector_text.currentText() == "ASC": data_visualization_per_state = jobs.query_run('''SELECT state_abrev, state_name, ''' + ''' total(jobs.employment) as employment, total(school.size_2018/4), round(avg(school.repayment_cohort),3) as repayment_cohort, round(avg(jobs.salary_25th_percentile)) as averge_entry_salary FROM school JOIN states using(state_abrev) JOIN jobs using(state_name) GROUP BY state_name ORDER BY employment ASC;''', cursor) elif self.order_selector_text.currentText() == "DESC": data_visualization_per_state = jobs.query_run('''SELECT state_abrev, state_name, ''' + ''' total(jobs.employment) as employment, total(school.size_2018/4), round(avg(school.repayment_cohort),3) as repayment_cohort, round(avg(jobs.salary_25th_percentile)) as averge_entry_salary FROM school JOIN states using(state_abrev) JOIN jobs using(state_name) GROUP BY state_name ORDER BY employment DESC;''', cursor) else: data_visualization_per_state = jobs.query_run('''SELECT state_abrev, state_name, ''' + ''' total(jobs.employment) as employment, total(school.size_2018/4), round(avg(school.repayment_cohort),3) as repayment_cohort, round(avg(jobs.salary_25th_percentile)) as averge_entry_salary FROM school JOIN states using(state_abrev) JOIN jobs using(state_name) GROUP BY state_name ;''', cursor) QListWidgetItem("State", listview=self.list_control) for state in data_visualization_per_state: state_display_data = f"{state[0]}, {state[1]}" grad_employ_data = f"Employment/Graduates: {state[2]/state[3]}" repayment_data = f"Average Entry Salary/Average Declining Balance Percent: {state[5]/state[4]}" state_item = QListWidgetItem(state_display_data, listview=self.list_control) grad_item = QListWidgetItem(grad_employ_data, listview=self.list_control) repayment_item = QListWidgetItem(repayment_data, listview=self.list_control) grad_item.setForeground(Qt.darkGreen) repayment_item.setForeground(Qt.blue) state_item.setForeground(Qt.white) state_item.setBackground(Qt.black) self.list_control.show() jobs.close_db(conn) def run_map_visualization(self): conn, cursor = jobs.open_db("jobs_db.sqlite") data_visualization_per_state = jobs.query_run('''SELECT state_abrev, state_name, ''' + ''' total(jobs.employment) as employment, total(school.size_2018/4), round(avg(school.repayment_cohort),3) as repayment_cohort, round(avg(jobs.salary_25th_percentile)) as averge_entry_salary FROM school JOIN states using(state_abrev) JOIN jobs using(state_name) GROUP BY state_name ;''', cursor) state_abrev = [] state_grads = [] state_repayment = [] for state in data_visualization_per_state: state_abrev.append(state[0]) state_grads.append(state[2]/state[3]) state_repayment.append(state[5]/state[4]) if self.data_selector_map.currentText() == "Graduates to Employment": us_map = px.Figure(data=px.Choropleth(locations=state_abrev, z=state_grads, locationmode='USA-states', colorbar_title="Employment/Graduates" )) us_map.update_layout(geo_scope='usa', title_text='Employment VS Graduates By State') us_map.show() elif self.data_selector_map.currentText() == "Average Declining Balance Percent": us_map = px.Figure(data=px.Choropleth(locations=state_abrev, z=state_repayment, locationmode='USA-states', colorbar_title="Salary/Average Percent" )) us_map.update_layout(geo_scope='usa', title_text='Average Salary VS Average ' 'Percent of People with Declining Loans') us_map.show() else: us_map = px.Figure(data=px.Choropleth(locations=state_abrev, z=state_grads, locationmode='USA-states', colorbar_title="Graduates" )) us_map.update_layout(geo_scope='usa', title_text='Graduates By State') us_map.show() jobs.close_db(conn) self.list_control.hide()
class ConfigTab(QWidget): show_all_updated = Signal(bool) def __init__(self, parent, root_config_path, force_all_fields=False): super().__init__(parent=parent) self.root_config_path = root_config_path self.force_all_fields = force_all_fields self.show_all_fields = force_all_fields self.main_window = parent self.layout = QVBoxLayout(self) # setup mapping config self.layout.addWidget(MappingGroupBox(self, root_config_path)) # setup extractor config self.layout.addWidget( DynamicClassFormBlock( self, "Extractor", f"{root_config_path}.extractor", CONNECTOR_CLASSES, ) ) # setup loader config self.layout.addWidget( DynamicClassFormBlock( self, "Loader", f"{root_config_path}.loader", CONNECTOR_CLASSES ) ) # add runner config self.layout.addWidget( DynamicClassFormBlock( self, "Runner", f"{root_config_path}.runner", RUNNER_CLASSES, default_class=PandasRunner, ) ) # if we dont force all the fields to be shown and a template is set, # add a toggle button to show/hide if not force_all_fields: self.toggle_all_fields_button = QPushButton("Show all fields") self.toggle_all_fields_button.clicked.connect( self.toggle_all_fields ) self.update_show_field_toggle_button_visibility( self.main_window.config ) self.main_window.config_changed.connect( self.update_show_field_toggle_button_visibility ) self.layout.addWidget(self.toggle_all_fields_button) else: self.toggle_all_fields_button = None # Add a spacer to push all the fields up when fields are hidden self.layout.addStretch() self.main_window.running_changed.connect( lambda b: self.setEnabled(not b) ) def toggle_all_fields(self): self.show_all_fields = not self.show_all_fields self.toggle_all_fields_button.text = ( "Show all fields" if not self.show_all_fields else "Hide template fields" ) self.show_all_updated.emit(self.show_all_fields) def update_show_field_toggle_button_visibility(self, config): if self.main_window.config.has_template: self.toggle_all_fields_button.show() else: self.toggle_all_fields_button.hide()
class TriageView(QScrollArea, View): def __init__(self, parent, data): QScrollArea.__init__(self, parent) View.__init__(self) View.setBinaryDataNavigable(self, True) self.setupView(self) self.data = data self.currentOffset = 0 self.byteView = None self.fullAnalysisButton = None self.importsWidget = None container = QWidget(self) layout = QVBoxLayout() entropyGroup = QGroupBox("Entropy", container) entropyLayout = QVBoxLayout() entropyLayout.addWidget( entropy.EntropyWidget(entropyGroup, self, self.data)) entropyGroup.setLayout(entropyLayout) layout.addWidget(entropyGroup) hdr = None try: if self.data.view_type == "PE": hdr = headers.PEHeaders(self.data) elif self.data.view_type != "Raw": hdr = headers.GenericHeaders(self.data) except: log.log_error(traceback.format_exc()) if hdr is not None: headerGroup = QGroupBox("Headers", container) headerLayout = QVBoxLayout() headerWidget = headers.HeaderWidget(headerGroup, hdr) headerLayout.addWidget(headerWidget) headerGroup.setLayout(headerLayout) layout.addWidget(headerGroup) if self.data.executable: importExportSplitter = QSplitter(Qt.Horizontal) importGroup = QGroupBox("Imports", container) importLayout = QVBoxLayout() self.importsWidget = imports.ImportsWidget(importGroup, self, self.data) importLayout.addWidget(self.importsWidget) importGroup.setLayout(importLayout) importExportSplitter.addWidget(importGroup) exportGroup = QGroupBox("Exports", container) exportLayout = QVBoxLayout() exportLayout.addWidget( exports.ExportsWidget(exportGroup, self, self.data)) exportGroup.setLayout(exportLayout) importExportSplitter.addWidget(exportGroup) layout.addWidget(importExportSplitter) if self.data.view_type != "PE": segmentsGroup = QGroupBox("Segments", container) segmentsLayout = QVBoxLayout() segmentsWidget = sections.SegmentsWidget( segmentsGroup, self.data) segmentsLayout.addWidget(segmentsWidget) segmentsGroup.setLayout(segmentsLayout) layout.addWidget(segmentsGroup) if len(segmentsWidget.segments) == 0: segmentsGroup.hide() sectionsGroup = QGroupBox("Sections", container) sectionsLayout = QVBoxLayout() sectionsWidget = sections.SectionsWidget(sectionsGroup, self.data) sectionsLayout.addWidget(sectionsWidget) sectionsGroup.setLayout(sectionsLayout) layout.addWidget(sectionsGroup) if len(sectionsWidget.sections) == 0: sectionsGroup.hide() buttonLayout = QHBoxLayout() buttonLayout.addStretch(1) self.loadDynamicButton = QPushButton("Load Dynamic Imports") self.loadDynamicButton.clicked.connect( self.importsWidget.scanDynamic) buttonLayout.addWidget(self.loadDynamicButton) self.fullAnalysisButton = QPushButton("Start Full Analysis") self.fullAnalysisButton.clicked.connect(self.startFullAnalysis) buttonLayout.addWidget(self.fullAnalysisButton) layout.addLayout(buttonLayout) layout.addStretch(1) else: self.byteView = byte.ByteView(self, self.data) layout.addWidget(self.byteView, 1) container.setLayout(layout) self.setWidgetResizable(True) self.setWidget(container) if self.fullAnalysisButton is not None and Settings().get_string( "analysis.mode", data) == "full": self.fullAnalysisButton.hide() def getData(self): return self.data def getCurrentOffset(self): if self.byteView is not None: return self.byteView.getCurrentOffset() return self.currentOffset def getSelectionOffsets(self): if self.byteView is not None: return self.byteView.getSelectionOffsets() return (self.currentOffset, self.currentOffset) def setCurrentOffset(self, offset): self.currentOffset = offset UIContext.updateStatus(True) def getFont(self): return binaryninjaui.getMonospaceFont(self) def navigate(self, addr): if self.byteView: return self.byteView.navigate(addr) return False def startFullAnalysis(self): Settings().set_string("analysis.mode", "full", self.data) for f in self.data.functions: if f.analysis_skipped: f.reanalyze() self.data.update_analysis() self.fullAnalysisButton.hide() def navigateToFileOffset(self, offset): if self.byteView is None: addr = self.data.get_address_for_data_offset(offset) view_frame = ViewFrame.viewFrameForWidget(self) if view_frame is None: return if addr is None: view_frame.navigate("Hex:Raw", offset) else: view_frame.navigate( "Linear:" + view_frame.getCurrentDataType(), addr) else: if self.data == self.data.file.raw: addr = offset else: addr = self.data.get_address_for_data_offset(offset) if addr is None: view_frame = ViewFrame.viewFrameForWidget(self) if view_frame is not None: view_frame.navigate("Hex:Raw", offset) else: self.byteView.navigate(addr) self.byteView.setFocus(Qt.OtherFocusReason) def focusInEvent(self, event): if self.byteView is not None: self.byteView.setFocus(Qt.OtherFocusReason)