class ProgressThread(QtCore.QThread): conclude_op = QtCore.pyqtSignal() def __init__(self, file_in, install): QtCore.QThread.__init__(self) self.op_progress = None self.cache = apt.Cache(self.op_progress) self.cache.open() self.file_in = file_in self.isDone = False self.logger = logging.getLogger(__name__) self.logger.setLevel(logging.DEBUG) handler = logging.FileHandler('/var/log/resetter/resetter.log') handler.setLevel(logging.DEBUG) formatter = logging.Formatter( '%(asctime)s - %(name)s - %(funcName)s - %(levelname)s - %(message)s' ) handler.setFormatter(formatter) self.logger.addHandler(handler) self.install = install self.aprogress = UIAcquireProgress(False) self.thread1 = QtCore.QThread() self.aprogress.moveToThread(self.thread1) self.thread1.started.connect( lambda: self.aprogress.play(0.0, False, "")) self.aprogress.finished.connect(self.thread1.quit) self.iprogress = UIInstallProgress() self.thread2 = QtCore.QThread() self.iprogress.moveToThread(self.thread2) self.thread2.started.connect(lambda: self.iprogress.play(0.0, "")) self.iprogress.finished.connect(self.thread2.quit) self.broken_list = [] def lineCount(self, file_path): x = open(file_path).readlines() line_count = len(x) return line_count def run(self): if self.lineCount(self.file_in) != 0: loading = 0 x = float(100) / self.lineCount(self.file_in) with open(self.file_in) as packages: for pkg_name in packages: try: loading += x self.pkg = self.cache[pkg_name.strip()] self.pkg.mark_delete(True, True) self.emit( QtCore.SIGNAL('updateProgressBar(int, bool)'), loading, self.isDone) except (KeyError, SystemError) as error: self.logger.error("{}".format(error)) if self.pkg.is_inst_broken or self.pkg.is_now_broken: self.broken_list.append(self.pkg.fullname) self.logger.critical("{}".format(error)) continue else: text = "Error loading apps" error2 = "Problems trying to remove: {}\n{}".format( self.pkg.fullname, error.message) self.logger.critical("{} {}".format(error, error2, exc_info=True)) self.emit( QtCore.SIGNAL('showError(QString, QString)'), error2, text) break self.thread1.start() self.thread2.start() self.removePackages() self.conclude_op.emit() else: print "All removable packages are already removed" self.emit(QtCore.SIGNAL('updateProgressBar(int, bool)'), 100, True) def removePackages(self): self.logger.info("Removing Programs") try: package = self.cache['snapd'] package.mark_delete(True, True) self.logger.info("Keep Count before commit: {}".format( self.cache.keep_count)) self.logger.info("Delete Count before commit: {}".format( self.cache.delete_count)) self.logger.info("Broken Count before commit: {}".format( self.cache.broken_count)) self.cache.commit(self.aprogress, self.iprogress) self.logger.info("Broken Count after commit: {}".format( self.cache.broken_count)) except Exception as e: self.logger.error("Error: [{}]".format(e, exc_info=True)) error = "Problems trying to remove: {}\n{}".format( self.pkg.fullname, e.message) text = "Package removal failed" self.emit(QtCore.SIGNAL('showError(QString, QString)'), error, text)
class ProgressThread(QtCore.QThread): end_of_threads = QtCore.pyqtSignal() start_op = QtCore.pyqtSignal(str, str) # Error string transmitter start_op1 = QtCore.pyqtSignal(int, bool) # Loading progress transmitter def __init__(self, file_in, install): QtCore.QThread.__init__(self) self.cache = apt.Cache(None) self.cache.open() self.file_in = file_in self.install = install self.isDone = False self.logger = logging.getLogger(__name__) self.logger.setLevel(logging.DEBUG) handler = logging.FileHandler('/var/log/resetter/resetter.log') handler.setLevel(logging.DEBUG) formatter = logging.Formatter('%(asctime)s - %(name)s - %(funcName)s - %(levelname)s - %(message)s') handler.setFormatter(formatter) self.logger.addHandler(handler) self.resolver = apt.cache.ProblemResolver(self.cache) self.aprogress = UIAcquireProgress(False) self.thread1 = QtCore.QThread() self.aprogress.moveToThread(self.thread1) self.thread1.started.connect(lambda: self.aprogress.play(0.0, False, "")) self.aprogress.finished.connect(self.thread1.quit) self.thread2 = QtCore.QThread() self.iprogress = UIInstallProgress() self.iprogress.moveToThread(self.thread2) self.thread2.started.connect(lambda: self.iprogress.play(0.0, "")) self.iprogress.finished.connect(self.thread2.quit) self.broken_list = [] def run(self): lc = UsefulTools().lineCount(self.file_in) if lc > 0: loading = 0 x = float(100) / lc with open(self.file_in) as packages: for pkg_name in packages: try: loading += x self.pkg = self.cache[pkg_name.strip()] if not self.install: self.pkg.mark_delete(True, True) print ("{} will be removed".format(self.pkg)) else: self.pkg.mark_install() print ("{} will be installed ".format(self.pkg.shortname)) self.start_op1.emit(loading, self.isDone) except (KeyError, SystemError) as error: # if resolver cannot find a way to cleanly install packages, move it to the broken list if self.pkg.is_inst_broken: self.broken_list.append(self.pkg.fullname) self.logger.critical("{}".format(error), exc_info=True) continue else: text = "Error loading apps" error2 = "Problems trying to install: {}\n{}".format(self.pkg.fullname, error.message) self.logger.critical("{} {}".format(error, error2, exc_info=True)) self.start_op.emit(error2, text) break self.thread1.start() self.thread2.start() self.installPackages() self.end_of_threads.emit() else: print ("All removable packages are already removed") self.start_op1.emit(100, True) def installPackages(self): try: self.logger.info("treating Packages") self.cache.commit(self.aprogress, self.iprogress) except Exception as e: self.logger.error("Action on package failed. Error: [{}]".format(e, exc_info=True)) error = str(e) if self.install: text = "Package install failed" self.start_op.emit(error, text) else: text = "Package removal failed" self.start_op.emit(error, text)
class EasyPPAInstall(QtGui.QDialog): def __init__(self, parent=None): super(EasyPPAInstall, self).__init__(parent) self.setWindowTitle("Easy PPA Install") self.searchEditText = QtGui.QLineEdit() self.searchEditText.setPlaceholderText("Search for applications") self.searchEditText.setMaximumWidth(200) self.searchbutton = QtGui.QPushButton() self.error_msg = QtGui.QMessageBox() self.error_msg.setIcon(QtGui.QMessageBox.Critical) self.error_msg.setWindowTitle("Error") self.closebutton = QtGui.QPushButton() self.closebutton = QtGui.QPushButton() self.closebutton.setText('Close') self.closebutton.setMaximumWidth(150) self.closebutton.clicked.connect(self.close) self.searchbutton.setText("Search") self.searchbutton.setMaximumWidth(100) self.progressbar = QtGui.QProgressBar() self.lbl1 = QtGui.QLabel() self.buttonRefresh = QtGui.QPushButton() self.buttonRefresh.setText("Refresh sources") self.isWrittenTo = False self.table = QtGui.QTableWidget() self.configureTable(self.table) self.searchbutton.clicked.connect( lambda: self.searchForPPA(self.table)) self.buttonRefresh.clicked.connect(self.updateSources) self.table.verticalHeader().hide() self.horizontalLayout = QtGui.QHBoxLayout() self.horizontalLayout.addWidget(self.searchEditText) self.horizontalLayout.addWidget(self.searchbutton) self.horizontalLayout.setAlignment(QtCore.Qt.AlignRight) self.horizontalLayout2 = QtGui.QHBoxLayout() self.horizontalLayout2.setAlignment(QtCore.Qt.AlignRight) self.horizontalLayout2.addWidget(self.progressbar) self.horizontalLayout2.addWidget(self.buttonRefresh) self.horizontalLayout2.addWidget(self.closebutton) self.verticalLayout = QtGui.QVBoxLayout(self) self.verticalLayout.addLayout(self.horizontalLayout) self.verticalLayout.addWidget(self.table) self.verticalLayout.addWidget(self.lbl1) self.verticalLayout.addLayout(self.horizontalLayout2) self.os_info = lsb_release.get_distro_information() self.sources = sourceslist.SourcesList() self.aprogress = UIAcquireProgress(True) self.thread1 = QtCore.QThread() self.aprogress.moveToThread(self.thread1) self.thread1.started.connect( lambda: self.aprogress.play(0.0, False, "")) self.aprogress.finished.connect(self.thread1.quit) self.connect(self.aprogress, QtCore.SIGNAL("updateProgressBar2(int, bool, QString)"), self.updateProgressBar2) self.ppa = [] self.table_data = [] def updateProgressBar2(self, percent, isdone, status): self.lbl1.setText(status) self.progressbar.setValue(percent) if isdone: self.installProgress.end_of_threads.connect(self.finished) self.labels[(2, 1)].setPixmap(self.pixmap2) self.close() def configureTable(self, table): table.setColumnCount(4) table.setHorizontalHeaderItem(0, QtGui.QTableWidgetItem("Description")) table.setHorizontalHeaderItem(1, QtGui.QTableWidgetItem("PPA")) table.setHorizontalHeaderItem( 2, QtGui.QTableWidgetItem("View Packages within this ppa")) table.setHorizontalHeaderItem( 3, QtGui.QTableWidgetItem("Add this PPA to your sources")) table.setMinimumHeight(200) table.setMinimumWidth(700) header = table.horizontalHeader() header.setResizeMode(1, QtGui.QHeaderView.ResizeToContents) header.setResizeMode(2, QtGui.QHeaderView.ResizeToContents) table.horizontalHeader().setStretchLastSection(True) def searchForPPA(self, table): if self.isThereInternet() is False: self.close() else: QtGui.QApplication.setOverrideCursor(QtCore.Qt.WaitCursor) self.searchbutton.setEnabled(False) del self.ppa[:] del self.table_data[:] browser = mechanize.Browser() browser.set_handle_robots(False) browser.open('https://launchpad.net/') browser.addheaders = [("User-agent", "Mozilla/5.0")] browser.select_form(nr=0) search_string = self.searchEditText.text() found_links = [] browser[ 'field.text'] = search_string # use the proper input type=text name browser.submit() match = "+archive" exclude = (["+packages", "+build", "+sourcepub"]) for link in browser.links(): if not any(s in link.url for s in exclude) and match in link.url: found_links.append(link) QtGui.qApp.processEvents() r = len(found_links) if r == 0: self.lbl1.setText("No results found") else: self.lbl1.setText("Found {} results".format(r)) table.setRowCount(r) self.displayLinks(found_links, table, browser) QtGui.QApplication.restoreOverrideCursor() self.searchbutton.setEnabled(True) def updateSources(self): self.buttonRefresh.setEnabled(False) cache = apt.Cache() cache.update(self.aprogress) self.buttonRefresh.setEnabled(True) self.lbl1.setText("Update Complete!") cache.close() def displayLinks(self, found_links, table, browser): loading = 0 x = float(100) / len(found_links) if len(found_links) != 0 else 0 try: for i, link in enumerate(found_links): desc = QtGui.QTableWidgetItem() ppa = QtGui.QTableWidgetItem() buttonAddPPA = QtGui.QPushButton() buttonAddPPA.setText("Install this PPA") buttonAddPPA.clicked.connect(lambda: self.addPPA(self.ppa)) buttonPackageDetails = QtGui.QPushButton() buttonPackageDetails.setText("View packages") buttonPackageDetails.setEnabled(True) buttonPackageDetails.clicked.connect( lambda: self.showPackages(self.table_data)) htmltext = browser.open(link.url).read() soup = BeautifulSoup(htmltext, 'html.parser') ppaTag = soup.find('strong', attrs={'class': 'ppa-reference'}) if ppaTag is not None: ppa_name = ppaTag.text.strip() ppa.setText(ppa_name) b = QtCore.QByteArray.fromPercentEncoding(link.text) text = b.data().decode('utf8') desc.setText(textwrap.fill(text, 20)) table.setItem(i, 0, desc) QtGui.qApp.processEvents() table.setItem(i, 1, ppa) QtGui.qApp.processEvents() table.setCellWidget(i, 2, buttonPackageDetails) QtGui.qApp.processEvents() table.setCellWidget(i, 3, buttonAddPPA) QtGui.qApp.processEvents() repo = soup.find('pre', attrs={'class': 'wrap'}) if repo is not None: repo_name = repo.text.strip() raw = soup.find('code') if raw is not None: raw_key = raw.text.strip() select_node = soup.findAll( 'select', attrs={'name': 'field.series_filter'}) if select_node is not None: self.isCompatible(select_node, repo_name, raw_key) sauce = soup.find('table', attrs={'class': 'listing sortable'}) if sauce is not None: self.getTableData(sauce) loading += x self.progressbar.setValue(int(loading)) QtGui.qApp.processEvents() except Exception as e: QtGui.QApplication.restoreOverrideCursor() self.error_msg.setText("Error, please try again.") self.error_msg.setDetailedText( "If this keeps happening, it means easy repo stumbled upon an empty or " "forbidden link. You might need to change your search string") self.error_msg.exec_() def isThereInternet(self): try: mechanize.urlopen('http://google.com', timeout=1) except mechanize.URLError as e: print "There is no internet: {}".format(e) self.error_msg.setText("You are not connected to the internet") self.error_msg.setDetailedText( "This feature will not work without an internet connection. ") self.error_msg.exec_() return False else: return True def codeName(self): xenial_fam = (['serena', 'sarah', 'loki', 'sonya', 'sylvia']) if self.os_info['CODENAME'] == 'rosa': return 'trusty' elif self.os_info['CODENAME'] in xenial_fam: return 'xenial' else: return self.os_info['CODENAME'] def isCompatible(self, node, repo, raw): options = [] compatible = bool signing_key = str(raw[6:]).split('<', 1)[0] if node: for option in node[0].findAll('option'): option = option.text.strip().lower() options.append(option) if self.codeName() in options: compatible = True else: compatible = False result = (repo, compatible, signing_key) self.ppa.append(result) def addPPA(self, ppa): button = QtGui.qApp.focusWidget() index = self.table.indexAt(button.pos()) if index.isValid() and ppa[index.row()][1]: try: QtGui.QApplication.setOverrideCursor(QtCore.Qt.WaitCursor) x = str(ppa[index.row()]) y = str(x[7:]).split(' ', 1)[0] entry = ('deb', y, self.codeName(), ['main']) self.sources.add(*entry) self.sources.save() p = subprocess.check_output([ 'apt-key', 'adv', '--keyserver', 'keyserver.ubuntu.com', '--recv-keys', ppa[index.row()][2] ]) print p QtGui.QApplication.restoreOverrideCursor() except Exception as e: QtGui.QApplication.restoreOverrideCursor() UsefulTools().showMessage("Unable to fetch PPA key", "Error: {}".format(e), QtGui.QMessageBox.Critical) else: UsefulTools().showMessage( "PPA added", "This ppa has been successfully added to your sources list", QtGui.QMessageBox.Information) else: UsefulTools().showMessage( "PPA not compatible", "This PPA is not compatible with your system because it's " "not available for {}".format(self.os_info['DESCRIPTION']), QtGui.QMessageBox.Information) def getTableData(self, sauce): pasta = [] for i in sauce.select('tr'): data = i.select('td') if data: package = data[0].text.strip() version = ' '.join(data[1].text.strip().split()) pasta_sauce = "{}: {}".format(package, version) pasta.append(pasta_sauce) self.table_data.append(pasta) def showPackages(self, sauce): QtGui.QApplication.setOverrideCursor(QtCore.Qt.WaitCursor) button = QtGui.qApp.focusWidget() index = self.table.indexAt(button.pos()) if index.isValid(): available = AppView(self) text = "These packages are available from the selected ppa" if len(sauce) >= index.row(): available.showView(sauce[index.row()], "PPA Packages", text, False) available.show() QtGui.QApplication.restoreOverrideCursor()
class ProgressThread(QtCore.QThread): start_op = QtCore.pyqtSignal(str, str) # Error string transmitter start_op1 = QtCore.pyqtSignal(int, bool) # Loading progress transmitter conclude_op = QtCore.pyqtSignal() start_op2 = QtCore.pyqtSignal(bool) def __init__(self, file_in, install): QtCore.QThread.__init__(self) self.cache = apt.Cache(None) self.cache.open() self.file_in = file_in self.isDone = False self.error_msg = QMessageBox() self.error_msg.setIcon(QMessageBox.Critical) self.error_msg.setWindowTitle("Error") self.logger = logging.getLogger(__name__) self.logger.setLevel(logging.DEBUG) handler = logging.FileHandler('/var/log/resetter/resetter.log') handler.setLevel(logging.DEBUG) formatter = logging.Formatter('%(asctime)s - %(name)s - %(funcName)s - %(levelname)s - %(message)s') handler.setFormatter(formatter) self.logger.addHandler(handler) self.install = install self.aprogress = UIAcquireProgress(False) self.thread1 = QtCore.QThread() self.aprogress.moveToThread(self.thread1) self.thread1.started.connect(lambda: self.aprogress.play(0.0, False, "")) self.aprogress.finished.connect(self.thread1.quit) self.iprogress = UIInstallProgress() self.thread2 = QtCore.QThread() self.iprogress.moveToThread(self.thread2) self.thread2.started.connect(lambda: self.iprogress.play(0.0, "")) self.iprogress.finished.connect(self.thread2.quit) self.broken_list = [] def lineCount(self, file_path): x = open(file_path).readlines() line_count = len(x) return line_count def run(self): if self.lineCount(self.file_in) != 0: loading = 0 x = float(100) / (self.lineCount(self.file_in)+1) with open(self.file_in) as packages: for pkg_name in packages: try: loading += x self.pkg = self.cache[pkg_name.strip()] self.pkg.mark_delete(True, True) self.start_op1.emit(loading, self.isDone) except (KeyError, SystemError) as error: self.logger.error("{}".format(error)) if self.pkg.is_inst_broken or self.pkg.is_now_broken: self.broken_list.append(self.pkg.fullname) self.logger.critical("{}".format(error)) continue else: text = "Error loading apps" error2 = "Problems trying to remove: {}\n{}".format(self.pkg.fullname, str(error)) self.logger.critical("{} {}".format(error, error2, exc_info=True)) self.start_op.emit(error2, text) break self.thread1.start() self.thread2.start() self.removePackages() self.removeSystemDirs() self.start_op2.emit(False) self.fixBroken() self.conclude_op.emit() else: print ("All removable packages are already removed") self.start_op1.emit(100, True) def removePackages(self): self.logger.info("Removing Programs") try: package = self.cache['snapd'] package.mark_delete(True, True) self.logger.info("Keep Count before commit: {}".format(self.cache.keep_count)) self.logger.info("Delete Count before commit: {}".format(self.cache.delete_count)) self.logger.info("Broken Count before commit: {}".format(self.cache.broken_count)) self.cache.commit(self.aprogress, self.iprogress) self.logger.info("Broken Count after commit: {}".format(self.cache.broken_count)) except Exception as e: self.logger.error("Error: [{}]".format(e, exc_info=True)) error = "Problems trying to remove: {}\n{}".format(self.pkg.fullname, str(e)) text = "Package removal failed" self.start_op.emit(error, text) def removeSystemDirs(self): self.logger.info("Removing Dirs") self.logger.critical("aaaaaa") try: p = subprocess.check_output(['bash', '/usr/lib/resetter/data/scripts/reset-dirs.sh']) print ("ccalled") self.start_op1.emit(100, self.isDone) except subprocess.CalledProcessError as e: self.logger.error("unable to add user Error: {}".format(e.output)) else: self.logger.info("Default user added")
class ProgressThread(QtCore.QThread): conclude_op = QtCore.pyqtSignal() def __init__(self, file_in, install): QtCore.QThread.__init__(self) self.op_progress = None self.cache = apt.Cache(self.op_progress) self.cache.open() self.file_in = file_in self.isDone = False self.error_msg = QtGui.QMessageBox() self.error_msg.setIcon(QtGui.QMessageBox.Critical) self.error_msg.setWindowTitle("Error") self.logger = logging.getLogger(__name__) self.logger.setLevel(logging.DEBUG) handler = logging.FileHandler('/var/log/resetter/resetter.log') handler.setLevel(logging.DEBUG) formatter = logging.Formatter('%(asctime)s - %(name)s - %(funcName)s - %(levelname)s - %(message)s') handler.setFormatter(formatter) self.logger.addHandler(handler) self.install = install self.aprogress = UIAcquireProgress(False) self.thread1 = QtCore.QThread() self.aprogress.moveToThread(self.thread1) self.thread1.started.connect(lambda: self.aprogress.play(0.0, False, "")) self.aprogress.finished.connect(self.thread1.quit) self.iprogress = UIInstallProgress() self.thread2 = QtCore.QThread() self.iprogress.moveToThread(self.thread2) self.thread2.started.connect(lambda: self.iprogress.play(0.0, "")) self.iprogress.finished.connect(self.thread2.quit) self.broken_list = [] def lineCount(self, appfile): try: p = subprocess.Popen(['wc', '-l', appfile], stdout=subprocess.PIPE, stderr=subprocess.PIPE) result, err = p.communicate() return int(result.strip().split()[0]) except subprocess.CalledProcessError: pass def removePackages(self): self.logger.info("Removing Programs") try: self.logger.info("Keep Count before commit: {}".format(self.cache.keep_count)) self.logger.info("Delete Count before commit: {}".format(self.cache.delete_count)) self.logger.info("Broken Count before commit: {}".format(self.cache.broken_count)) self.cache.commit(self.aprogress, self.iprogress) self.logger.info("Broken Count after commit: {}".format(self.cache.broken_count)) except Exception as e: self.logger.error("Error: [{}]".format(e, exc_info=True)) error = e.message text = "Package removal failed" self.emit(QtCore.SIGNAL('showError(QString, QString)'), error, text) def run(self): if self.lineCount(self.file_in) != 0: loading = 0 x = float(100) / self.lineCount(self.file_in) with open(self.file_in) as packages: for pkg_name in packages: try: loading += x self.pkg = self.cache[pkg_name.strip()] self.pkg.mark_delete(True, True) self.emit(QtCore.SIGNAL('updateProgressBar(int, bool)'), loading, self.isDone) except (KeyError, SystemError) as error: self.logger.error("{}".format(error)) if self.pkg.is_inst_broken or self.pkg.is_now_broken: self.broken_list.append(self.pkg.fullname) self.logger.critical("{}".format(error)) continue self.thread1.start() self.thread2.start() self.removePackages() self.conclude_op.emit() else: print "All removable packages are already removed" self.emit(QtCore.SIGNAL('updateProgressBar(int, bool)'), 100, True)
class ProgressThread(QtCore.QThread): conclude_op = QtCore.pyqtSignal() def __init__(self, file_in, install): QtCore.QThread.__init__(self) self.op_progress = None self.cache = apt.Cache(self.op_progress) self.cache.open() self.file_in = file_in self.isDone = False self.logger = logging.getLogger(__name__) self.logger.setLevel(logging.DEBUG) handler = logging.FileHandler('/var/log/resetter/resetter.log') handler.setLevel(logging.DEBUG) formatter = logging.Formatter('%(asctime)s - %(name)s - %(funcName)s - %(levelname)s - %(message)s') handler.setFormatter(formatter) self.logger.addHandler(handler) self.install = install self.aprogress = UIAcquireProgress(False) self.thread1 = QtCore.QThread() self.aprogress.moveToThread(self.thread1) self.thread1.started.connect(lambda: self.aprogress.play(0.0, False, "")) self.aprogress.finished.connect(self.thread1.quit) self.iprogress = UIInstallProgress() self.thread2 = QtCore.QThread() self.iprogress.moveToThread(self.thread2) self.thread2.started.connect(lambda: self.iprogress.play(0.0, "")) self.iprogress.finished.connect(self.thread2.quit) self.broken_list = [] def lineCount(self, file_path): x = open(file_path).readlines() line_count = len(x) return line_count def run(self): if self.lineCount(self.file_in) != 0: loading = 0 x = float(100) / self.lineCount(self.file_in) with open(self.file_in) as packages: for pkg_name in packages: try: loading += x self.pkg = self.cache[pkg_name.strip()] self.pkg.mark_delete(True, True) self.emit(QtCore.SIGNAL('updateProgressBar(int, bool)'), loading, self.isDone) except (KeyError, SystemError) as error: self.logger.error("{}".format(error)) if self.pkg.is_inst_broken or self.pkg.is_now_broken: self.broken_list.append(self.pkg.fullname) self.logger.critical("{}".format(error)) continue else: text = "Error loading apps" error2 = "Problems trying to remove: {}\n{}".format(self.pkg.fullname, error.message) self.logger.critical("{} {}".format(error, error2, exc_info=True)) self.emit(QtCore.SIGNAL('showError(QString, QString)'), error2, text) break self.thread1.start() self.thread2.start() self.removePackages() self.conclude_op.emit() else: print "All removable packages are already removed" self.emit(QtCore.SIGNAL('updateProgressBar(int, bool)'), 100, True) def removePackages(self): self.logger.info("Removing Programs") try: package = self.cache['snapd'] package.mark_delete(True, True) self.logger.info("Keep Count before commit: {}".format(self.cache.keep_count)) self.logger.info("Delete Count before commit: {}".format(self.cache.delete_count)) self.logger.info("Broken Count before commit: {}".format(self.cache.broken_count)) self.cache.commit(self.aprogress, self.iprogress) self.logger.info("Broken Count after commit: {}".format(self.cache.broken_count)) except Exception as e: self.logger.error("Error: [{}]".format(e, exc_info=True)) error = "Problems trying to remove: {}\n{}".format(self.pkg.fullname, e.message) text = "Package removal failed" self.emit(QtCore.SIGNAL('showError(QString, QString)'), error, text)
class ProgressThread(QtCore.QThread): end_of_threads = QtCore.pyqtSignal() def __init__(self, file_in, install): QtCore.QThread.__init__(self) self.cache = apt.Cache(None) self.cache.open() self.file_in = file_in self.install = install self.isDone = False self.logger = logging.getLogger(__name__) self.logger.setLevel(logging.DEBUG) handler = logging.FileHandler('/var/log/resetter/resetter.log') handler.setLevel(logging.DEBUG) formatter = logging.Formatter('%(asctime)s - %(name)s - %(funcName)s - %(levelname)s - %(message)s') handler.setFormatter(formatter) self.logger.addHandler(handler) self.resolver = apt.cache.ProblemResolver(self.cache) self.aprogress = UIAcquireProgress(False) self.thread1 = QtCore.QThread() self.aprogress.moveToThread(self.thread1) self.thread1.started.connect(lambda: self.aprogress.play(0.0, False, "")) self.aprogress.finished.connect(self.thread1.quit) self.error_msg = QtGui.QMessageBox() self.error_msg.setIcon(QtGui.QMessageBox.Critical) self.error_msg.setWindowTitle("Error") self.thread2 = QtCore.QThread() self.iprogress = UIInstallProgress() self.iprogress.moveToThread(self.thread2) self.thread2.started.connect(lambda: self.iprogress.play(0.0, "")) self.iprogress.finished.connect(self.thread2.quit) self.broken_list = [] def lineCount(self): try: p = subprocess.Popen(['wc', '-l', self.file_in], stdout=subprocess.PIPE, stderr=subprocess.PIPE) result, err = p.communicate() return int(result.strip().split()[0]) except subprocess.CalledProcessError: pass def run(self): if self.lineCount() > 0: loading = 0 x = float(100) / self.lineCount() with open(self.file_in) as packages: for pkg_name in packages: try: loading += x self.pkg = self.cache[pkg_name.strip()] if not self.install: self.pkg.mark_delete(True, True) print "{} will be removed".format(self.pkg) else: self.pkg.mark_install() print "{} will be installed ".format(self.pkg.shortname) self.emit(QtCore.SIGNAL('updateProgressBar(int, bool)'), loading, self.isDone) except (KeyError, SystemError) as error: # if resolver cannot find a way to cleanly install packages, move it to the broken list if self.pkg.is_inst_broken: self.broken_list.append(self.pkg.fullname) self.logger.critical("{}".format(error), exc_info=True) continue self.thread1.start() self.thread2.start() self.installPackages() self.end_of_threads.emit() else: print "All removable packages are already removed" self.emit(QtCore.SIGNAL('updateProgressBar(int, bool)'), 100, True) def installPackages(self): try: self.logger.info("treating Packages") self.cache.commit(self.aprogress, self.iprogress) except Exception as e: self.logger.error("Action on package failed. Error: [{}]".format(e, exc_info=True)) error = e.message if self.install: text = "Package install failed" self.emit(QtCore.SIGNAL('showError(QString, QString)'), error, text) else: text = "Package removal failed" self.emit(QtCore.SIGNAL('showError(QString, QString)'), error, text)
class EasyPPAInstall(QtGui.QDialog): def __init__(self, parent=None): super(EasyPPAInstall, self).__init__(parent) self.setWindowTitle("Easy PPA Install") self.searchEditText = QtGui.QLineEdit() self.searchEditText.setPlaceholderText("Search for applications") self.searchEditText.setMaximumWidth(200) self.searchbutton = QtGui.QPushButton() self.error_msg = QtGui.QMessageBox() self.error_msg.setIcon(QtGui.QMessageBox.Critical) self.error_msg.setWindowTitle("Error") self.closebutton = QtGui.QPushButton() self.closebutton = QtGui.QPushButton() self.closebutton.setText('Close') self.closebutton.setMaximumWidth(150) self.closebutton.clicked.connect(self.close) self.searchbutton.setText("Search") self.searchbutton.setMaximumWidth(100) self.progressbar = QtGui.QProgressBar() self.lbl1 = QtGui.QLabel() self.buttonRefresh = QtGui.QPushButton() self.buttonRefresh.setText("Refresh sources") self.isWrittenTo = False self.table = QtGui.QTableWidget() self.configureTable(self.table) self.searchbutton.clicked.connect(lambda: self.searchForPPA(self.table)) self.buttonRefresh.clicked.connect(self.updateSources) self.table.verticalHeader().hide() self.horizontalLayout = QtGui.QHBoxLayout() self.horizontalLayout.addWidget(self.searchEditText) self.horizontalLayout.addWidget(self.searchbutton) self.horizontalLayout.setAlignment(QtCore.Qt.AlignRight) self.horizontalLayout2 = QtGui.QHBoxLayout() self.horizontalLayout2.setAlignment(QtCore.Qt.AlignRight) self.horizontalLayout2.addWidget(self.progressbar) self.horizontalLayout2.addWidget(self.buttonRefresh) self.horizontalLayout2.addWidget(self.closebutton) self.verticalLayout = QtGui.QVBoxLayout(self) self.verticalLayout.addLayout(self.horizontalLayout) self.verticalLayout.addWidget(self.table) self.verticalLayout.addWidget(self.lbl1) self.verticalLayout.addLayout(self.horizontalLayout2) self.os_info = lsb_release.get_lsb_information() self.sources = sourceslist.SourcesList() self.aprogress = UIAcquireProgress(True) self.thread1 = QtCore.QThread() self.aprogress.moveToThread(self.thread1) self.thread1.started.connect(lambda: self.aprogress.play(0.0, False, "")) self.aprogress.finished.connect(self.thread1.quit) self.connect(self.aprogress, QtCore.SIGNAL("updateProgressBar2(int, bool, QString)"), self.updateProgressBar2) self.ppa = [] self.table_data = [] def updateProgressBar2(self, percent, isdone, status): self.lbl1.setText(status) self.progressbar.setValue(percent) if isdone: self.installProgress.end_of_threads.connect(self.finished) self.labels[(2, 1)].setPixmap(self.pixmap2) #time.sleep(2) self.close() def configureTable(self, table): table.setColumnCount(4) table.setHorizontalHeaderItem(0, QtGui.QTableWidgetItem("Description")) table.setHorizontalHeaderItem(1, QtGui.QTableWidgetItem("PPA")) table.setHorizontalHeaderItem(2, QtGui.QTableWidgetItem("View Packages within this ppa")) table.setHorizontalHeaderItem(3, QtGui.QTableWidgetItem("Add this PPA to your sources")) table.setMinimumHeight(200) table.setMinimumWidth(700) header = table.horizontalHeader() header.setResizeMode(1, QtGui.QHeaderView.ResizeToContents) header.setResizeMode(2, QtGui.QHeaderView.ResizeToContents) table.horizontalHeader().setStretchLastSection(True) def searchForPPA(self, table): if self.isThereInternet() is False: self.close() else: QtGui.QApplication.setOverrideCursor(QtCore.Qt.WaitCursor) del self.ppa[:] del self.table_data[:] browser = mechanize.Browser() browser.open('https://launchpad.net/') browser.addheaders = [("User-agent", "Mozilla/5.0")] browser.select_form(nr=0) search_string = self.searchEditText.text() found_links = [] browser['field.text'] = search_string # use the proper input type=text name browser.submit() match = "+archive" exclude = ["+packages", "+build", "+sourcepub"] for link in browser.links(): if not any(s in link.url for s in exclude) and match in link.url: found_links.append(link) QtGui.qApp.processEvents() if len(found_links) == 0: self.lbl1.setText("No results found") else: self.lbl1.clear() table.setRowCount(len(found_links)) self.displayLinks(found_links, table, browser) QtGui.QApplication.restoreOverrideCursor() def updateSources(self): self.buttonRefresh.setEnabled(False) cache = apt.Cache() cache.update(self.aprogress) self.buttonRefresh.setEnabled(True) def displayLinks(self, found_links, table, browser): try: for i, link in enumerate(found_links): desc = QtGui.QTableWidgetItem() ppa = QtGui.QTableWidgetItem() buttonAddPPA = QtGui.QPushButton() buttonAddPPA.setText("Install this PPA") buttonAddPPA.clicked.connect(lambda: self.addPPA(self.ppa)) buttonPackageDetails = QtGui.QPushButton() buttonPackageDetails.setText("View packages") buttonPackageDetails.setEnabled(True) buttonPackageDetails.clicked.connect(lambda: self.showPackages(self.table_data)) htmltext = browser.open(link.url).read() soup = BeautifulSoup(htmltext, 'html.parser') ppaTag = soup.find('strong', attrs={'class': 'ppa-reference'}) if ppaTag is not None: ppa_name = ppaTag.text.strip() # strip() is used to remove starting and trailing ppa.setText(ppa_name) b = QtCore.QByteArray.fromPercentEncoding(link.text) text = b.data().decode("utf8") desc.setText(textwrap.fill(text, 20)) table.setItem(i, 0, desc) QtGui.qApp.processEvents() table.setItem(i, 1, ppa) QtGui.qApp.processEvents() table.setCellWidget(i, 2, buttonPackageDetails) QtGui.qApp.processEvents() table.setCellWidget(i, 3, buttonAddPPA) QtGui.qApp.processEvents() repo = soup.find('pre', attrs={'class': 'wrap'}) if repo is not None: repo_name = repo.text.strip() raw = soup.find('code') if raw is not None: raw_key = raw.text.strip() select_node = soup.findAll('select', attrs={'name': 'field.series_filter'}) if select_node is not None: self.isCompatible(select_node, repo_name, raw_key) sauce = soup.find('table', attrs={'class': 'listing sortable'}) if sauce is not None: self.getTableData(sauce) # strip() is used to remove starting and trailing print link.text, link.url QtGui.qApp.processEvents() except Exception as e: self.error_msg.setText("Error, please try again.") self.error_msg.setDetailedText("If this keeps happening, it means easy repo stumbled upon a " "forbidden link. You might need to change your search string") self.error_msg.exec_() def isThereInternet(self): try: mechanize.urlopen('http://github.com', timeout=1) return True except mechanize.URLError as e: print "There is no internet {}".format(e) self.error_msg.setText("You are not connected to the internet") self.error_msg.setDetailedText("This feature will not work without an internet connection. ") self.error_msg.exec_() return False def codeName(self): xenial_fam = (['serena', 'sarah', 'loki']) if self.os_info['CODENAME'] == 'rosa': return "trusty" elif self.os_info['CODENAME'] in xenial_fam: return "xenial" else: return self.os_info['CODENAME'] def isCompatible(self, node, repo, raw): options = [] compatible = bool signing_key = str(raw[6:]).split('<', 1)[0] if node: for option in node[0].findAll('option'): option = option.text.strip().lower() options.append(option) if self.codeName() in options: compatible = True else: compatible = False result = [repo, compatible, signing_key] self.ppa.append(result) def addPPA(self, ppa): button = QtGui.qApp.focusWidget() index = self.table.indexAt(button.pos()) if index.isValid() and ppa[index.row()][1]: try: QtGui.QApplication.setOverrideCursor(QtCore.Qt.WaitCursor) x = str(ppa[index.row()]) y = str(x[7:]).split(' ', 1)[0] entry = ('deb', y, self.codeName(), ['main']) self.sources.add(*entry) self.sources.save() p = subprocess.check_output( ['apt-key', 'adv', '--keyserver', 'keyserver.ubuntu.com', '--recv-keys', ppa[index.row()][2]] ) print p QtGui.QApplication.restoreOverrideCursor() except Exception as e: QtGui.QApplication.restoreOverrideCursor() self.error_msg.setIcon(QtGui.QMessageBox.Critical) self.error_msg.setText("Unable fetch PPA key") self.error_msg.setDetailedText("Error: {}".format(e)) self.error_msg.exec_() else: self.successMessage() else: self.showMessage() def getTableData(self, sauce): pasta = [] for i in sauce.select('tr'): data = i.select('td') if data: package = data[0].text.strip() version = ' '.join(data[1].text.strip().split()) pasta_sauce = "{}: {}".format(package, version) pasta.append(pasta_sauce) self.table_data.append(pasta) def showPackages(self, sauce): QtGui.QApplication.setOverrideCursor(QtCore.Qt.WaitCursor) button = QtGui.qApp.focusWidget() index = self.table.indexAt(button.pos()) if index.isValid(): available = AppView(self) text = "These packages are available from the selected ppa" if len(sauce) >= index.row(): available.showView(sauce[index.row()], "PPA Packages", text, False) available.show() QtGui.QApplication.restoreOverrideCursor() def showMessage(self): msg = QtGui.QMessageBox(self) msg.setWindowTitle("PPA not compatible") msg.setIcon(QtGui.QMessageBox.Information) msg.setText("This PPA is not compatible with your system because it's " "not available for {}".format(self.os_info['DESCRIPTION'])) msg.exec_() def successMessage(self): msg = QtGui.QMessageBox(self) msg.setWindowTitle("PPA added") msg.setIcon(QtGui.QMessageBox.Information) msg.setText("This ppa has been successfully added to your sources list") msg.exec_()