Ejemplo n.º 1
0
    def update_fields(self):
        """
        Update the QLineEdit widgets with data from the current settings (.ini and registry).
        """
        # If app is not running with administrator privileges, cannot edit windows registry,
        # so disable name and pass fields, and hide user/password.
        if not is_admin():
            self.user.setEnabled(False)
            self.password.setEnabled(False)
            msg = 'Admin privileges required.'
            self.user.setText(None)
            for widget in [self.user, self.password]:
                widget.setPlaceholderText(msg)
                widget.setToolTip(
                    'Please restart the app in Administrator Mode to edit this setting.'
                )
        else:
            self.reg_user = Settings.Service.HeliumDB.user
            self.reg_pass = Settings.Service.HeliumDB.password
            self.user.setText(self.reg_user)
            self.password.setText(self.reg_pass)

        # Check if host and db name are already in the settings.ini, and if so add them to the fields
        self.settings_host = Settings.Service.HeliumDB.host
        self.settings_db = Settings.Service.HeliumDB.name

        if self.settings_host:
            self.host.setText(self.settings_host)

        if self.settings_db:
            self.db.setText(self.settings_db)
Ejemplo n.º 2
0
    def new_settings(self):
        """
        Make the labels of LineEdits that were modified bold, and enables the Apply button, and OK submit functionality,
        if at least one setting has been changed.
        """
        any_setting_changed = False
        settings_to_check = [
            (self.host.text() != self.settings_host, self.host_label, False),
            (self.db.text() != self.settings_db, self.db_label, False),
            (self.user.text() != self.reg_user, self.user_label, True),
            (self.password.text() != self.reg_pass, self.password_label, True)
        ]

        for setting_changed, label, admin_req in settings_to_check:
            if not (admin_req is True and is_admin() is False):
                any_setting_changed |= setting_changed
            if not admin_req or is_admin():
                make_bold(label, setting_changed)

        # If at least one field was updated, enable the apply button.
        self.apply_btn.setEnabled(any_setting_changed)
Ejemplo n.º 3
0
    def save_new_settings(self):
        Settings.Service.HeliumDB.host = self.host.text()
        Settings.Service.HeliumDB.name = self.db.text()

        if is_admin():
            try:
                Settings.Service.HeliumDB.user = self.user.text()
                Settings.Service.HeliumDB.password = self.password.text()

                registry_user = Settings.Service.HeliumDB.user
                registry_pass = Settings.Service.HeliumDB.password

                if registry_user == self.user.text(
                ) and registry_pass == self.password.text():
                    set_colored_text(label=self.message,
                                     text='Updated DB configuration.',
                                     color=QColor('green'))
                else:
                    set_colored_text(
                        label=self.message,
                        text=
                        'User/Password could not be updated.\nPlease verify the '
                        'service is found.',
                        color=QColor('red'))
            except Exception as e:
                set_colored_text(label=self.message,
                                 text=f'{e}',
                                 color=QColor('red'))

        else:
            set_colored_text(label=self.message,
                             text='Updated DB configuration.',
                             color=QColor('green'))

        self.reset_styles()

        # Establish new DB connection and get result
        connected = Settings.Service.connect_to_db()
        if connected is True:
            set_colored_text(label=self.message,
                             text=f'{self.message.text()}\nConnected to DB.',
                             color=QColor('green'))
        elif connected is False:
            set_colored_text(
                label=self.message,
                text=
                f'{self.message.text()}\nCould not establish DB connection, please check log for details.',
                color=QColor('red'))
        self.update_db_connection_status.emit()
Ejemplo n.º 4
0
    def update_status(self):
        # Get service details
        try:
            service = psutil.win_service_get(SERVICE_NAME)
        except psutil.NoSuchProcess as e:
            manager_logger.warning(e)
            self.update_status_title.emit(f"Service {SERVICE_NAME} not found")
            self.update_status_style.emit(f"background-color: {self.status_color[None]}; padding: 20px;")
            self.update_service_details.emit(defaultdict(lambda: None))
            self.stop()
            if is_admin():
                self.update_service_control_btns.emit(SERVICE_NOT_FOUND)
            return

        service_info = service.as_dict()
        status = service_info['status']

        self.update_status_title.emit(f"{service_info['display_name']} is {status.upper()}")
        self.update_status_style.emit(f"background-color: {self.status_color[status]}; padding: 20px;")

        self.update_service_details.emit(service_info)

        if is_admin():
            self.update_service_control_btns.emit(status)
Ejemplo n.º 5
0
    def __init__(self):
        super(UIMainWindow, self).__init__()
        uic.loadUi(main_window_ui, self)

        # Update title if app running with admin privileges
        if is_admin():
            self.setWindowTitle(self.windowTitle() + ' (Administrator)')

        # region External windows
        self.about_w = UIAbout()  # "About" dialogue window
        self.db_settings_w = UIDBSettings()  # "DB Settings" dialogue window
        self.general_settings_w = UIGeneralSettings(
        )  # "General Settings" dialogue window
        self.ca_settings_w = UICASettings()  # "Channel Access" dialogue window
        self.service_dir_path_w = UIServicePathDialog(
        )  # "Service Directory" dialogue window
        self.config_entry_w = UIConfigEntryDialog(
        )  # Add/Edit Configuration Entry dialogue window
        # endregion

        # region External windows setup
        self.db_settings_w.update_db_connection_status.connect(
            self.update_fields)
        self.service_dir_path_w.service_updated.connect(self.update_service)
        self.service_dir_path_w.service_updated.connect(self.update_fields)
        self.config_entry_w.config_updated.connect(self.refresh_config)
        # endregion

        # region Attributes
        self.table_expanded = False  # For toggling table expansion ("Expand Table"/"Service Info")
        self.pv_config_data = [
        ]  # Store the PV configuration data to be displayed in the config. table
        self.expand_table_btn_text = EXPAND_CONFIG_TABLE_BTN
        # endregion

        # region Menu actions & signals
        self.about_action.triggered.connect(
            lambda _: self.trigger_window(self.about_w))
        self.manager_log_action.triggered.connect(
            lambda _: os.startfile(MANAGER_LOGS_FILE))
        self.manager_settings_action.triggered.connect(
            lambda _: os.startfile(MANAGER_SETTINGS_FILE))
        self.manager_settings_dir_action.triggered.connect(
            lambda _: os.startfile(MANAGER_SETTINGS_DIR))
        self.show_service_log.triggered.connect(self.open_service_log)
        self.show_service_dir.triggered.connect(self.trigger_open_service_dir)
        self.show_service_settings.triggered.connect(
            lambda _: os.startfile(Settings.Service.settings_path))
        self.db_settings_action.triggered.connect(
            lambda _: self.trigger_window(self.db_settings_w))
        self.general_settings_action.triggered.connect(
            lambda _: self.trigger_window(self.general_settings_w))
        self.ca_settings_action.triggered.connect(
            lambda _: self.trigger_window(self.ca_settings_w))
        self.service_directory_action.triggered.connect(
            self.trigger_service_directory)
        self.open_pv_config_action.triggered.connect(
            self.trigger_open_pv_config)
        # endregion

        # region Setup widgets
        btn_conf = [(self.btn_service_start, 'start.svg'),
                    (self.btn_service_stop, 'stop.svg'),
                    (self.btn_service_restart, 'restart.svg'),
                    (self.db_connection_refresh_btn, 'refresh.svg'),
                    (self.expand_table_btn, None),
                    (self.refresh_btn, 'refresh_config.svg'),
                    (self.show_filter_btn, 'filter.svg'),
                    (self.new_config_btn, 'add.svg'),
                    (self.edit_config_btn, 'edit.svg'),
                    (self.delete_config_btn, 'delete.svg')]
        for btn in btn_conf:
            setup_button(btn[0], btn[1])

        if not is_admin():
            for btn in [
                    self.btn_service_start, self.btn_service_stop,
                    self.btn_service_restart
            ]:
                btn.setEnabled(False)
                btn.setToolTip(
                    btn.toolTip() +
                    '\nRun the manager as administrator to start/stop/restart the service.'
                )

        # Filter/Search Frame Setup
        self.filter_frame.setVisible(False)

        # Save the table header names, to be used for the Filters columns combo box
        column_names = [
            self.config_table.horizontalHeaderItem(index).text()
            for index in range(self.config_table.columnCount())
        ]
        self.filter_columns_cb.insertItems(0, ['All columns', *column_names])
        # endregion

        # region Signals to Slots
        self.btn_service_start.clicked.connect(
            lambda _: self.call_on_service(win32serviceutil.StartService))
        self.btn_service_stop.clicked.connect(
            lambda _: self.call_on_service(win32serviceutil.StopService))
        self.btn_service_restart.clicked.connect(
            lambda _: self.call_on_service(win32serviceutil.RestartService))

        self.db_connection_refresh_btn.clicked.connect(
            self.refresh_db_connection)

        self.config_table.itemSelectionChanged.connect(
            self.enable_or_disable_edit_and_delete_buttons)
        self.expand_table_btn.clicked.connect(self.expand_table_btn_clicked)
        self.refresh_btn.clicked.connect(self.refresh_config)
        self.show_filter_btn.clicked.connect(self.show_filter_btn_clicked)
        self.new_config_btn.clicked.connect(self.new_config_btn_clicked)
        self.edit_config_btn.clicked.connect(self.edit_config_btn_clicked)
        self.delete_config_btn.clicked.connect(self.delete_config_btn_clicked)
        # Table Filters
        self.apply_filter_btn.clicked.connect(self.apply_filters)
        self.filter_bar.returnPressed.connect(self.apply_filters)
        self.clear_filter_btn.clicked.connect(self.clear_filters)
        # endregion

        # region Threads
        # region Service Status Thread
        # noinspection PyTypeChecker
        self.thread_service_status = ServiceStatusCheckThread()
        self.thread_service_status.update_status_title.connect(
            self.service_status_title.setText)
        self.thread_service_status.update_status_style.connect(
            self.service_status_title.setStyleSheet)
        self.thread_service_status.update_service_details.connect(
            self.update_service_details)
        self.thread_service_status.update_service_control_btns.connect(
            self.update_service_control_btns)
        self.thread_service_status.start()
        # endregion

        # region Service Log Thread
        # noinspection PyTypeChecker
        self.thread_service_log = ServiceLogUpdaterThread(
            self.service_log_show_lines_spinbox.value())
        self.thread_service_log.log_fetched.connect(self.update_service_log)
        self.thread_service_log.file_not_found.connect(self.clear_service_log)
        self.thread_service_log.enable_or_disable_buttons.connect(
            self.update_service_log_btns)
        self.thread_service_log.start()
        # endregion

        # QThreads graceful exit on app close
        QApplication.instance().aboutToQuit.connect(
            self.thread_service_status.stop)
        QApplication.instance().aboutToQuit.connect(
            self.thread_service_log.stop)
        # endregion

        # region Service Log Widgets
        self.service_log_file_open_btn.clicked.connect(self.open_service_log)
        self.service_log_scroll_down_btn.clicked.connect(
            self.log_scroll_to_bottom)

        # Emit spinner valueChanged only on return key pressed, focus lost, and widget arrow keys clicked
        self.service_log_show_lines_spinbox.setKeyboardTracking(False)

        self.service_log_font_size.currentTextChanged.connect(
            self.update_log_font_size)
        self.service_log_show_lines_spinbox.valueChanged.connect(
            self.thread_service_log.set_displayed_lines_no)