def slot_pbutton_ap_leases_refresh_clicked(self): def cb_dnsmasq_leases_content(content): self.pbutton_ap_leases_refresh.setText('Refresh') self.pbutton_ap_leases_refresh.setEnabled(True) self.tview_ap_leases.setEnabled(True) leases_lines = content.splitlines() leases_model = QStandardItemModel(0, 3, self) leases_model.setHorizontalHeaderItem(0, QStandardItem("Hostname")) leases_model.setHorizontalHeaderItem(1, QStandardItem("MAC")) leases_model.setHorizontalHeaderItem(2, QStandardItem("IP")) leases_model.setHorizontalHeaderItem(3, QStandardItem("Expiration")) for i, l in enumerate(leases_lines): l_split = l.strip().split(' ') if len(l_split) != 5: continue for j in range(0, len(l_split)): if j == 4: continue if j == 0: #FIXME: fromTime_t is obsolete: https://doc.qt.io/qt-5/qdatetime-obsolete.html#toTime_t leases_model.setItem(i, 3, QStandardItem(QDateTime.fromTime_t(int(l_split[j])).toString('yyyy-MM-dd HH:mm:ss'))) elif j == 3: leases_model.setItem(i, 0, QStandardItem(l_split[j])) else: leases_model.setItem(i, j, QStandardItem(l_split[j])) self.tview_ap_leases.setModel(leases_model) self.tview_ap_leases.setColumnWidth(0, DEFAULT_TVIEW_HOST_NAME_HEADER_WIDTH) self.tview_ap_leases.setColumnWidth(1, DEFAULT_TVIEW_MAC_HEADER_WIDTH) self.tview_ap_leases.setColumnWidth(2, DEFAULT_TVIEW_IP_HEADER_WIDTH) self.tview_ap_leases.setColumnWidth(3, DEFAULT_TVIEW_EXPIRATION_HEADER_WIDTH) def cb_dnsmasq_leases_error(kind, error): self.pbutton_ap_leases_refresh.setText('Refresh') self.pbutton_ap_leases_refresh.setEnabled(True) kind_text = { TextFile.ERROR_KIND_OPEN: 'opening', TextFile.ERROR_KIND_READ: 'reading', TextFile.ERROR_KIND_UTF8: 'decoding' } QMessageBox.critical(get_main_window(), 'Settings | Access Point', 'Error {0} dnsmasq leases file:\n\n{1}'.format(kind_text[kind], error)) self.pbutton_ap_leases_refresh.setText('Refreshing...') self.pbutton_ap_leases_refresh.setEnabled(False) TextFile.read_async(self.session, DNSMASQ_LEASES_FILE, cb_dnsmasq_leases_content, cb_dnsmasq_leases_error)
def slot_pbutton_ap_leases_refresh_clicked(self): def cb_dnsmasq_leases_content(content): self.pbutton_ap_leases_refresh.setText('Refresh') self.pbutton_ap_leases_refresh.setEnabled(True) self.tview_ap_leases.setEnabled(True) leases_lines = content.splitlines() leases_model = QtGui.QStandardItemModel(0, 3, self) leases_model.setHorizontalHeaderItem(0, QtGui.QStandardItem("Hostname")) leases_model.setHorizontalHeaderItem(1, QtGui.QStandardItem("MAC")) leases_model.setHorizontalHeaderItem(2, QtGui.QStandardItem("IP")) leases_model.setHorizontalHeaderItem(3, QtGui.QStandardItem("Expiration")) for i, l in enumerate(leases_lines): l_split = l.strip().split(' ') if len(l_split) != 5: continue for j in range(0, len(l_split)): if j == 4: continue if j == 0: leases_model.setItem(i, 3, QtGui.QStandardItem(QtCore.QDateTime.fromTime_t(int(l_split[j])).toString('yyyy-MM-dd HH:mm:ss'))) elif j == 3: leases_model.setItem(i, 0, QtGui.QStandardItem(l_split[j])) else: leases_model.setItem(i, j, QtGui.QStandardItem(l_split[j])) self.tview_ap_leases.setModel(leases_model) self.tview_ap_leases.setColumnWidth(0, DEFAULT_TVIEW_HOST_NAME_HEADER_WIDTH) self.tview_ap_leases.setColumnWidth(1, DEFAULT_TVIEW_MAC_HEADER_WIDTH) self.tview_ap_leases.setColumnWidth(2, DEFAULT_TVIEW_IP_HEADER_WIDTH) self.tview_ap_leases.setColumnWidth(3, DEFAULT_TVIEW_EXPIRATION_HEADER_WIDTH) def cb_dnsmasq_leases_error(kind, error): self.pbutton_ap_leases_refresh.setText('Refresh') self.pbutton_ap_leases_refresh.setEnabled(True) kind_text = { TextFile.ERROR_KIND_OPEN: 'opening', TextFile.ERROR_KIND_READ: 'reading', TextFile.ERROR_KIND_UTF8: 'decoding' } QtGui.QMessageBox.critical(get_main_window(), 'Settings | Access Point', 'Error {0} dnsmasq leases file:\n\n{1}'.format(kind_text[kind], error)) self.pbutton_ap_leases_refresh.setText('Refreshing...') self.pbutton_ap_leases_refresh.setEnabled(False) TextFile.read_async(self.session, DNSMASQ_LEASES_FILE, cb_dnsmasq_leases_content, cb_dnsmasq_leases_error)
def read_config_files(self): def cb_hostapd_conf_content(content): if not self.is_tab_on_focus or len(content) == 0: return def cb_settings_ap_get_interfaces(result): if not self.is_tab_on_focus: return if not report_script_result( result, 'Settings | Access Point', 'Error getting access point interfaces:'): return ap_mode_interfaces = json.loads(result.stdout) if len(ap_mode_interfaces) <= 0: self.label_ap_status.setText( 'Inactive - No wireless interface available') self.cbox_ap_interface.clear() self.pbutton_ap_save.setEnabled(False) self.update_ui_state() return self.pbutton_ap_save.setEnabled(True) self.cbox_ap_interface.clear() self.cbox_ap_interface.currentIndexChanged.disconnect() for intf in ap_mode_interfaces: self.cbox_ap_interface.addItem(intf) current_item_index = self.cbox_ap_interface.count() - 1 if ap_mode_interfaces[intf]['ip']: self.cbox_ap_interface.setItemData( current_item_index, ap_mode_interfaces[intf]['ip'], AP_INTERFACE_IP_USER_ROLE) else: self.cbox_ap_interface.setItemData( current_item_index, '192.168.42.1', AP_INTERFACE_IP_USER_ROLE) if ap_mode_interfaces[intf]['mask']: self.cbox_ap_interface.setItemData( current_item_index, ap_mode_interfaces[intf]['mask'], AP_INTERFACE_MASK_USER_ROLE) else: self.cbox_ap_interface.setItemData( current_item_index, '255.255.255.0', AP_INTERFACE_MASK_USER_ROLE) self.cbox_ap_interface.setCurrentIndex(-1) self.cbox_ap_interface.currentIndexChanged.connect( self.slot_cbox_ap_interface_current_index_changed) if not interface: self.cbox_ap_interface.setCurrentIndex(0) elif not interface and self.cbox_ap_interface.count() > 0: self.cbox_ap_interface.setCurrentIndex(0) else: broke = False for i in range(0, self.cbox_ap_interface.count()): if self.cbox_ap_interface.itemText(i) == interface: self.cbox_ap_interface.setCurrentIndex(i) broke = True break if not broke: self.cbox_ap_interface.setCurrentIndex(0) self.update_ui_state() try: lines = content.splitlines() interface = '' ssid = '' channel = 1 ssid_hidden = '0' wpa_key = '' for l in lines: l_split = l.strip().split('=') if len(l_split) != 2: continue if l_split[0].strip(' ') == 'interface': interface = l_split[1].strip(' ') elif l_split[0].strip(' ') == 'ssid': ssid = l_split[1].strip(' ') elif l_split[0].strip(' ') == 'channel': channel = l_split[1].strip(' ') elif l_split[0].strip(' ') == 'ignore_broadcast_ssid': ssid_hidden = l_split[1].strip(' ') elif l_split[0].strip(' ') == 'wpa_passphrase': wpa_key = l_split[1] self.script_manager.execute_script( 'settings_ap_get_interfaces', cb_settings_ap_get_interfaces) self.ledit_ap_ssid.setText(ssid) self.chkbox_ap_ssid_hidden.setChecked(ssid_hidden != '0') self.sbox_ap_channel.setValue(int(channel)) self.ledit_ap_wpa_key.setText(wpa_key) except Exception as e: QMessageBox.critical( get_main_window(), 'Settings | Access Point', 'Error parsing hostapd.conf file:\n\n{0}'.format(e)) self.update_ui_state() def cb_dnsmasq_conf_content(content): if not self.is_tab_on_focus or len(content) == 0: return try: lines = content.splitlines() dns_dhcp_enabled = True dhcp_range_start = '192.168.42.50' dhcp_range_end = '192.168.42.254' domain = 'red-brick-ap' dhcp_option_netmask = '255.255.255.0' for l in lines: if l.strip().strip(' ') == '#Enabled': dns_dhcp_enabled = True elif l.strip().strip(' ') == '#Disabled': dns_dhcp_enabled = False l_split = l.strip().split('=') if len(l_split) != 2: continue if l_split[0].strip(' ') == 'dhcp-range': dhcp_range = l_split[1].strip(' ').split(',') dhcp_range_start = dhcp_range[0] dhcp_range_end = dhcp_range[1] elif l_split[0].strip(' ') == 'domain': domain = l_split[1].strip(' ') elif l_split[0].strip(' ') == 'dhcp-option': dhcp_option = l_split[1].strip(' ').split(',') if len(dhcp_option) == 2: if dhcp_option[0].strip(' ') == 'option:netmask': dhcp_option_netmask = dhcp_option[1] self.chkbox_ap_enable_dns_dhcp.setChecked(dns_dhcp_enabled) if domain: self.ledit_ap_domain.setText(domain) dhcp_range_start_list = dhcp_range_start.split('.') dhcp_range_end_list = dhcp_range_end.split('.') dhcp_option_netmask_list = dhcp_option_netmask.split('.') self.sbox_ap_pool_start1.setValue(int( dhcp_range_start_list[0])) self.sbox_ap_pool_start2.setValue(int( dhcp_range_start_list[1])) self.sbox_ap_pool_start3.setValue(int( dhcp_range_start_list[2])) self.sbox_ap_pool_start4.setValue(int( dhcp_range_start_list[3])) self.sbox_ap_pool_end1.setValue(int(dhcp_range_end_list[0])) self.sbox_ap_pool_end2.setValue(int(dhcp_range_end_list[1])) self.sbox_ap_pool_end3.setValue(int(dhcp_range_end_list[2])) self.sbox_ap_pool_end4.setValue(int(dhcp_range_end_list[3])) self.sbox_ap_pool_mask1.setValue( int(dhcp_option_netmask_list[0])) self.sbox_ap_pool_mask2.setValue( int(dhcp_option_netmask_list[1])) self.sbox_ap_pool_mask3.setValue( int(dhcp_option_netmask_list[2])) self.sbox_ap_pool_mask4.setValue( int(dhcp_option_netmask_list[3])) except Exception as e: QMessageBox.critical( get_main_window(), 'Settings | Access Point', 'Error parsing dnsmasq.conf file:\n\n{0}'.format(e)) self.update_ui_state() def cb_text_file_error(title, kind, error): self.update_ui_state() kind_text = { TextFile.ERROR_KIND_OPEN: 'opening', TextFile.ERROR_KIND_READ: 'reading', TextFile.ERROR_KIND_UTF8: 'decoding' } QMessageBox.critical( get_main_window(), 'Settings | Access Point', 'Error {0} {1} file:\n\n{2}'.format(kind_text[kind], title, error)) TextFile.read_async( self.session, HOSTAPD_CONF_PATH, cb_hostapd_conf_content, lambda kind, error: cb_text_file_error( 'hostapd.conf', kind, error)) TextFile.read_async( self.session, DNSMASQ_CONF_PATH, cb_dnsmasq_conf_content, lambda kind, error: cb_text_file_error( 'dnsmasq.conf', kind, error))
def read_config_files(self): def cb_hostapd_conf_content(content): if not self.is_tab_on_focus or len(content) == 0: return def cb_settings_ap_get_interfaces(result): if not self.is_tab_on_focus: return if result and not result.stderr and result.exit_code == 0: ap_mode_interfaces = json.loads(result.stdout) if len(ap_mode_interfaces) <= 0: self.label_ap_status.setText('Inactive - No wireless interface available') self.cbox_ap_interface.clear() self.pbutton_ap_save.setEnabled(False) self.update_ui_state() return self.pbutton_ap_save.setEnabled(True) self.cbox_ap_interface.clear() self.cbox_ap_interface.currentIndexChanged.disconnect() for intf in ap_mode_interfaces: self.cbox_ap_interface.addItem(intf) current_item_index = self.cbox_ap_interface.count() - 1 if ap_mode_interfaces[intf]['ip']: self.cbox_ap_interface.setItemData(current_item_index, ap_mode_interfaces[intf]['ip'], AP_INTERFACE_IP_USER_ROLE) else: self.cbox_ap_interface.setItemData(current_item_index, '192.168.42.1', AP_INTERFACE_IP_USER_ROLE) if ap_mode_interfaces[intf]['mask']: self.cbox_ap_interface.setItemData(current_item_index, ap_mode_interfaces[intf]['mask'], AP_INTERFACE_MASK_USER_ROLE) else: self.cbox_ap_interface.setItemData(current_item_index, '255.255.255.0', AP_INTERFACE_MASK_USER_ROLE) self.cbox_ap_interface.setCurrentIndex(-1) self.cbox_ap_interface.currentIndexChanged.connect(self.slot_cbox_ap_interface_current_index_changed) if not interface: self.cbox_ap_interface.setCurrentIndex(0) elif not interface and self.cbox_ap_interface.count() > 0: self.cbox_ap_interface.setCurrentIndex(0) else: broke = False for i in range(0, self.cbox_ap_interface.count()): if self.cbox_ap_interface.itemText(i) == interface: self.cbox_ap_interface.setCurrentIndex(i) broke = True break if not broke: self.cbox_ap_interface.setCurrentIndex(0) else: QtGui.QMessageBox.critical(get_main_window(), 'Settings | Access Point', 'Error getting access point interfaces:\n\n' + result.stderr) self.update_ui_state() try: lines = content.splitlines() interface = '' ssid = '' channel = 1 ssid_hidden = '0' wpa_key = '' for l in lines: l_split = l.strip().split('=') if len(l_split) != 2: continue if l_split[0].strip(' ') == 'interface': interface = l_split[1].strip(' ') elif l_split[0].strip(' ') == 'ssid': ssid = l_split[1].strip(' ') elif l_split[0].strip(' ') == 'channel': channel = l_split[1].strip(' ') elif l_split[0].strip(' ') == 'ignore_broadcast_ssid': ssid_hidden = l_split[1].strip(' ') elif l_split[0].strip(' ') == 'wpa_passphrase': wpa_key = l_split[1] self.script_manager.execute_script('settings_ap_get_interfaces', cb_settings_ap_get_interfaces) self.ledit_ap_ssid.setText(ssid) self.chkbox_ap_ssid_hidden.setChecked(ssid_hidden != '0') self.sbox_ap_channel.setValue(int(channel)) self.ledit_ap_wpa_key.setText(wpa_key) except Exception as e: QtGui.QMessageBox.critical(get_main_window(), 'Settings | Access Point', 'Error parsing hostapd.conf file:\n\n{0}'.format(e)) self.update_ui_state() def cb_dnsmasq_conf_content(content): if not self.is_tab_on_focus or len(content) == 0: return try: lines = content.splitlines() dns_dhcp_enabled = True dhcp_range_start = '192.168.42.50' dhcp_range_end = '192.168.42.254' domain = 'red-brick-ap' dhcp_option_netmask = '255.255.255.0' for l in lines: if l.strip().strip(' ') == '#Enabled': dns_dhcp_enabled = True elif l.strip().strip(' ') == '#Disabled': dns_dhcp_enabled = False l_split = l.strip().split('=') if len(l_split) != 2: continue if l_split[0].strip(' ') == 'dhcp-range': dhcp_range = l_split[1].strip(' ').split(',') dhcp_range_start = dhcp_range[0] dhcp_range_end = dhcp_range[1] elif l_split[0].strip(' ') == 'domain': domain= l_split[1].strip(' ') elif l_split[0].strip(' ') == 'dhcp-option': dhcp_option = l_split[1].strip(' ').split(',') if len(dhcp_option) == 2: if dhcp_option[0].strip(' ') == 'option:netmask': dhcp_option_netmask = dhcp_option[1] self.chkbox_ap_enable_dns_dhcp.setChecked(dns_dhcp_enabled) if domain: self.ledit_ap_domain.setText(domain) dhcp_range_start_list = dhcp_range_start.split('.') dhcp_range_end_list = dhcp_range_end.split('.') dhcp_option_netmask_list = dhcp_option_netmask.split('.') self.sbox_ap_pool_start1.setValue(int(dhcp_range_start_list[0])) self.sbox_ap_pool_start2.setValue(int(dhcp_range_start_list[1])) self.sbox_ap_pool_start3.setValue(int(dhcp_range_start_list[2])) self.sbox_ap_pool_start4.setValue(int(dhcp_range_start_list[3])) self.sbox_ap_pool_end1.setValue(int(dhcp_range_end_list[0])) self.sbox_ap_pool_end2.setValue(int(dhcp_range_end_list[1])) self.sbox_ap_pool_end3.setValue(int(dhcp_range_end_list[2])) self.sbox_ap_pool_end4.setValue(int(dhcp_range_end_list[3])) self.sbox_ap_pool_mask1.setValue(int(dhcp_option_netmask_list[0])) self.sbox_ap_pool_mask2.setValue(int(dhcp_option_netmask_list[1])) self.sbox_ap_pool_mask3.setValue(int(dhcp_option_netmask_list[2])) self.sbox_ap_pool_mask4.setValue(int(dhcp_option_netmask_list[3])) except Exception as e: QtGui.QMessageBox.critical(get_main_window(), 'Settings | Access Point', 'Error parsing dnsmasq.conf file:\n\n{0}'.format(e)) self.update_ui_state() def cb_text_file_error(title, kind, error): self.update_ui_state() kind_text = { TextFile.ERROR_KIND_OPEN: 'opening', TextFile.ERROR_KIND_READ: 'reading', TextFile.ERROR_KIND_UTF8: 'decoding' } QtGui.QMessageBox.critical(get_main_window(), 'Settings | Access Point', 'Error {0} {1} file:\n\n{2}'.format(kind_text[kind], title, error)) TextFile.read_async(self.session, HOSTAPD_CONF_PATH, cb_hostapd_conf_content, lambda kind, error: cb_text_file_error('hostapd.conf', kind, error)) TextFile.read_async(self.session, DNSMASQ_CONF_PATH, cb_dnsmasq_conf_content, lambda kind, error: cb_text_file_error('hostapd.conf', kind, error))