class ServerConfigurationDialog(QtGui.QDialog): def __init__(self, editable, url, conf, parent=None): QtGui.QDialog.__init__(self, parent) self.ui = Ui_serverConfigurationDialog() self.ui.setupUi(self) self.editable = editable self.ui.addServerUrl.setText(url) self.conf = conf timezones = QtCore.QStringList(pytz.all_timezones) self.ui.timezoneList.addItems(timezones) self.ui.timezoneList.setCurrentIndex(timezones.indexOf(self.conf.get_timezone(self.server_url()))) if not editable: self.auto_load() self.connect(self.ui.loadUrlButton, QtCore.SIGNAL("clicked()"), self.fetch_data) def auto_load(self): self.ui.addServerUrl.setReadOnly(True) self.ui.loadUrlButton.setEnabled(False) self.fetch_data() def fetch_data(self): self.ui.loadUrlButton.setEnabled(False) self.event = BackgroundEvent(self.load_projects, self) self.connect(self.event, QtCore.SIGNAL('complete'), lambda data: self.load_data(data)) self.event.start() def load_projects(self): self.project_loader = ProjectLoader(self.server_url(), self.conf.timeout) return self.project_loader.get_data() def load_data(self, server): self.ui.loadUrlButton.setEnabled(self.editable) excluded_projects = self.conf.get_project_excludes(self.server_url()) projects_model = QtGui.QStandardItemModel() for project in server.projects: item = QtGui.QStandardItem(project.name) item.setCheckable(True) check = Qt.Unchecked if project.name in excluded_projects else Qt.Checked item.setCheckState(check) projects_model.appendRow(item) self.ui.projectsList.setModel(projects_model) def server_url(self): return str(self.ui.addServerUrl.text()) def save(self): projects_model = self.ui.projectsList.model() if projects_model is None: return self.server_url() excluded_projects = [str(projects_model.index(index, 0).data().toString()) for index in range(projects_model.rowCount()) if projects_model.index(index, 0).data(Qt.CheckStateRole) == Qt.Unchecked] self.conf.set_project_excludes(self.server_url(), excluded_projects) self.conf.set_project_timezone(self.server_url(), self.ui.timezoneList.currentText()) return self.server_url()
def test_should_respond_even_if_things_fail(self): class MockConnection(object): def __init__(self): pass def connect(self, server, timeout): raise Exception("something went wrong") response = ProjectLoader(ServerConfig('url', [], '', '', '', ''), 10, MockConnection()).get_data() projects = response.server.get_projects() self.assertEquals(0, len(projects)) self.assertEquals(True, response.server.unavailable)
def test_should_set_display_prefix(self): connection = MockConnection(lambda: StringIO("""<?xml version="1.0" encoding="UTF-8"?> <Projects> <Project name="project" activity="Sleeping" lastBuildStatus="Success" lastBuildTime="2009-06-12T06:54:35" webUrl="http://local/url"/> </Projects>""")) response = ProjectLoader(ServerConfig('url', [], '', 'RELEASE', '', ''), 10, connection).get_data() projects = response.server.get_projects() self.assertEquals(1, len(projects)) self.assertEquals("[RELEASE] project", projects[0].label())
def test_should_load_feed(self): connection = MockConnection(lambda: StringIO("""<?xml version="1.0" encoding="UTF-8"?> <Projects> <Project name="project" activity="Sleeping" lastBuildStatus="Success" lastBuildTime="2009-06-12T06:54:35" webUrl="http://local/url"/> </Projects>""")) response = ProjectLoader(ServerConfig('url', [], '', '', '', ''), 10, connection).get_data() projects = response.server.get_projects() self.assertEquals(1, len(projects)) self.assertEquals("project", projects[0].name) self.assertEquals("Sleeping", projects[0].activity) self.assertEquals("Success", projects[0].status) self.assertEquals(False, response.server.unavailable)
def load_projects(self): self.project_loader = ProjectLoader(self.server_url(), self.conf.timeout) return self.project_loader.get_data()
class ServerConfigurationDialog(QtGui.QDialog): def __init__(self, editable, url, conf, parent=None): QtGui.QDialog.__init__(self, parent) self.ui = Ui_serverConfigurationDialog() self.ui.setupUi(self) self.editable = editable self.ui.addServerUrl.setText(url) self.conf = conf self.parent = QtGui.QStandardItem("All") timezones = QtCore.QStringList(pytz.all_timezones) self.ui.timezoneList.addItems(timezones) self.ui.timezoneList.setCurrentIndex(timezones.indexOf(self.conf.get_timezone(self.server_url()))) if not editable: self.auto_load() self.connect(self.ui.loadUrlButton, QtCore.SIGNAL("clicked()"), self.fetch_data) def auto_load(self): self.ui.addServerUrl.setReadOnly(True) self.ui.loadUrlButton.setEnabled(False) self.fetch_data() def fetch_data(self): self.ui.loadUrlButton.setEnabled(False) self.event = BackgroundEvent(self.load_projects, self) self.connect(self.event, QtCore.SIGNAL('complete'), lambda data: self.load_data(data)) self.event.start() def load_projects(self): self.project_loader = ProjectLoader(self.server_url(), self.conf.timeout) return self.project_loader.get_data() def load_data(self, server): self.ui.loadUrlButton.setEnabled(self.editable) excluded_projects = self.conf.get_project_excludes(self.server_url()) projects_model = QtGui.QStandardItemModel() self.parent.setCheckable(True) projects_model.itemChanged.connect(self.project_checked) projects_model.setHorizontalHeaderLabels(['Select Projects']) for project in server.projects: item = QtGui.QStandardItem(project.name) item.setCheckable(True) check = Qt.Unchecked if project.name in excluded_projects else Qt.Checked item.setCheckState(check) self.parent.appendRow(item) projects_model.appendRow(self.parent) self.ui.projectsList.setModel(projects_model) self.ui.projectsList.expandToDepth(1) self.ui.projectsList.setItemsExpandable(False) self.ui.projectsList.setRootIsDecorated(False) def project_checked(self, item): if item == self.parent: [self.parent.child(index, 0).setCheckState(self.parent.checkState()) for index in range(self.parent.rowCount())] def server_url(self): return str(self.ui.addServerUrl.text()) def save(self): projects_model = self.ui.projectsList.model() if projects_model is None: return self.server_url() excluded_projects = [str(projects_model.index(index, 0, self.parent.index()).data().toString()) for index in range(self.parent.rowCount()) if projects_model.index(index, 0, self.parent.index()).data(Qt.CheckStateRole) == Qt.Unchecked] self.conf.set_project_excludes(self.server_url(), excluded_projects) self.conf.set_project_timezone(self.server_url(), self.ui.timezoneList.currentText()) return self.server_url()
def load_projects(self) -> Response: config = self.get_server_config() self.project_loader = ProjectLoader(config, self.conf.timeout) return self.project_loader.get_data()
class ServerConfigurationDialog(QDialog): def __init__(self, url: Optional[str], conf: Config, parent: QWidget = None): QDialog.__init__(self, parent) self.ui = Ui_serverConfigurationDialog() self.ui.setupUi(self) self.conf = conf self.projects_list = QtGui.QStandardItem("All") all_timezones = [Config.NONE_TIMEZONE] all_timezones.extend(pytz.all_timezones) self.ui.timezoneList.addItems(all_timezones) if url is not None: self.ui.addServerUrl.setText(url) self.server = conf.get_server_config(url) self.ui.timezoneList.setCurrentIndex( all_timezones.index(self.server.timezone)) self.ui.displayPrefix.setText(self.server.prefix) self.ui.username.setText(self.server.username) self.ui.password.setText(self.server.password) self.ui.authentication_type.setCurrentIndex( self.server.authentication_type) self.ui.usernameLabel.setVisible( self.server.authentication_type == self.server.AUTH_USERNAME_PASSWORD) self.ui.username.setVisible(self.server.authentication_type == self.server.AUTH_USERNAME_PASSWORD) else: self.server = ServerConfig('', [], '', '', '', '') self.ui.loadUrlButton.clicked.connect(self.fetch_data) if not Keystore.is_available(): self.ui.authenticationSettings.setTitle( 'Authentication (keyring dependency missing)') self.ui.authentication_type.setEnabled(False) self.ui.username.setEnabled(False) self.ui.password.setEnabled(False) self.ui.authentication_type.currentIndexChanged.connect( self.set_authentication_type) self.ui.backButton.clicked.connect( lambda: self.ui.stackedWidget.setCurrentIndex(0)) self.skip_ssl_verification = False def set_authentication_type(self, index: int): self.ui.username.setText('') self.ui.password.setText('') if ServerConfig.AUTH_USERNAME_PASSWORD == index: # Username/password selected self.ui.username.setVisible(True) self.ui.usernameLabel.setVisible(True) self.ui.passwordLabel.setText('Password') self.ui.password.setPlaceholderText(None) elif ServerConfig.AUTH_BEARER_TOKEN == index: # Bearer token selected self.ui.username.setVisible(False) self.ui.usernameLabel.setVisible(False) self.ui.passwordLabel.setText('Bearer token') self.ui.password.setPlaceholderText( "Do not include the 'Bearer' keyword") else: raise NotImplemented( 'Unsupported value: "%s". An implementation is missing.' % self.ui.authentication_type.currentText()) def fetch_data(self): if '' == self.ui.addServerUrl.text(): QMessageBox.critical(self, "Invalid input", "Path field cannot be empty.") return self.ui.loadUrlButton.setEnabled(False) self.event = BackgroundEvent(self.load_projects, self) self.event.completed.connect(self.load_data) self.event.start() def load_projects(self) -> Response: config = self.get_server_config() self.project_loader = ProjectLoader(config, self.conf.timeout) return self.project_loader.get_data() def load_data(self, response: Response): self.ui.loadUrlButton.setEnabled(True) if response.failed(): self.handle_errors(response) return self.ui.stackedWidget.setCurrentIndex(1) projects_model = QtGui.QStandardItemModel() projects_model.itemChanged.connect( self.project_checked) # type: ignore projects_model.setHorizontalHeaderLabels(['Select Projects']) self.projects_list = QtGui.QStandardItem("All") self.projects_list.setCheckable(True) for project in response.server.projects: item = QtGui.QStandardItem(project.name) item.setCheckable(True) check = Qt.Unchecked if project.name in self.server.excluded_projects else Qt.Checked item.setCheckState(check) self.projects_list.appendRow(item) projects_model.appendRow(self.projects_list) self.ui.projectsList.setModel(projects_model) self.ui.projectsList.expandToDepth(1) self.ui.projectsList.setItemsExpandable(False) self.ui.projectsList.setRootIsDecorated(False) def qtText(self, txt: str) -> str: return Qt.convertFromPlainText(txt) # type: ignore def handle_errors(self, response: Response): if response.ssl_error(): reply = QMessageBox.question( self, "Failed to fetch projects", "<b>SSL error, retry without verification?:</b> %s" % self.qtText(str(response.error)), QMessageBox.Yes, QMessageBox.No) if reply == QMessageBox.Yes: self.skip_ssl_verification = True self.fetch_data() return if response.failed(): QMessageBox.critical( self, "Failed to fetch projects", "<b>Error:</b> %s" % self.qtText(str(response.error))) def project_checked(self, item: QStandardItem): if item.hasChildren(): for index in range(item.rowCount()): item.child(index, 0).setCheckState(item.checkState()) def server_url(self) -> str: return str(self.ui.addServerUrl.text()) def get_server_config(self) -> ServerConfig: projects_model = self.ui.projectsList.model() def project(i, model): return model.index(i, 0, self.projects_list.index()) excluded_projects = [ project(i, projects_model).data() for i in range(self.projects_list.rowCount()) if project( i, projects_model).data(Qt.CheckStateRole) == Qt.Unchecked ] return ServerConfig(self.server_url(), excluded_projects, str(self.ui.timezoneList.currentText()), str(self.ui.displayPrefix.text()), str(self.ui.username.text()), str(self.ui.password.text()), self.skip_ssl_verification, int(self.ui.authentication_type.currentIndex())) def open(self) -> Optional[ServerConfig]: # type: ignore if self.exec_() == QDialog.Accepted: return self.get_server_config() return None
def load_projects(self): self.project_loader = ProjectLoader(self.get_server_config(), self.conf.timeout) return self.project_loader.get_data()
class ServerConfigurationDialog(QDialog): def __init__(self, url, conf, parent=None): QDialog.__init__(self, parent) self.ui = Ui_serverConfigurationDialog() self.ui.setupUi(self) self.ui.addServerUrl.setText(url) self.conf = conf self.parent = QtGui.QStandardItem("All") all_timezones = [Config.NONE_TIMEZONE] all_timezones.extend(pytz.all_timezones) self.ui.timezoneList.addItems(all_timezones) self.server = conf.get_server_config(url) self.ui.timezoneList.setCurrentIndex( all_timezones.index(self.server.timezone)) self.ui.displayPrefix.setText(self.server.prefix) self.ui.loadUrlButton.clicked.connect(self.fetch_data) self.ui.username.setText(self.server.username) self.ui.password.setText(self.server.password) if not Keystore.isAvailable(): self.ui.authenticationSettings.setTitle( 'Authentication (keyring dependency missing)') self.ui.username.setEnabled(False) self.ui.password.setEnabled(False) self.ui.backButton.clicked.connect( lambda: self.ui.stackedWidget.setCurrentIndex(0)) self.skip_ssl_verification = False def fetch_data(self): self.ui.loadUrlButton.setEnabled(False) self.event = BackgroundEvent(self.load_projects, self) self.event.completed.connect(self.load_data) self.event.start() def load_projects(self): self.project_loader = ProjectLoader(self.get_server_config(), self.conf.timeout) return self.project_loader.get_data() def load_data(self, response): self.ui.loadUrlButton.setEnabled(True) if response.failed(): self.handle_errors(response) return self.ui.stackedWidget.setCurrentIndex(1) projects_model = QtGui.QStandardItemModel() projects_model.itemChanged.connect(self.project_checked) projects_model.setHorizontalHeaderLabels(['Select Projects']) self.parent = QtGui.QStandardItem("All") self.parent.setCheckable(True) for project in response.server.projects: item = QtGui.QStandardItem(project.name) item.setCheckable(True) check = Qt.Unchecked if project.name in self.server.excluded_projects else Qt.Checked item.setCheckState(check) self.parent.appendRow(item) projects_model.appendRow(self.parent) self.ui.projectsList.setModel(projects_model) self.ui.projectsList.expandToDepth(1) self.ui.projectsList.setItemsExpandable(False) self.ui.projectsList.setRootIsDecorated(False) def handle_errors(self, response): if response.ssl_error(): reply = QMessageBox.question( self, "Failed to fetch projects", "<b>SSL error, retry without verification?:</b> %s" % Qt.convertFromPlainText(str(response.error)), QMessageBox.Yes, QMessageBox.No) if reply == QMessageBox.Yes: self.skip_ssl_verification = True self.fetch_data() return if response.failed(): QMessageBox.critical( self, "Failed to fetch projects", "<b>Error:</b> %s" % Qt.convertFromPlainText(str(response.error))) def project_checked(self, item): if item.hasChildren(): for index in range(item.rowCount()): item.child(index, 0).setCheckState(item.checkState()) def server_url(self): return str(self.ui.addServerUrl.text()) def get_server_config(self): projects_model = self.ui.projectsList.model() def project(i, model): return model.index(i, 0, self.parent.index()) excluded_projects = [ project(i, projects_model).data().encode('utf-8') for i in range(self.parent.rowCount()) if project( i, projects_model).data(Qt.CheckStateRole) == Qt.Unchecked ] return ServerConfig(self.server_url(), excluded_projects, str(self.ui.timezoneList.currentText()), self.ui.displayPrefix.text().encode('utf-8'), str(self.ui.username.text()), str(self.ui.password.text()), self.skip_ssl_verification) def open(self): if self.exec_() == QDialog.Accepted: return self.get_server_config()