From 41006b0fd874a862195b918fad17a7ae04f4fe57 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Thu, 2 Feb 2006 11:41:31 +0000 Subject: * added first non-interactive version --- DistUpgrade/DistUpgradeViewNonInteractive.py | 72 ++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 DistUpgrade/DistUpgradeViewNonInteractive.py (limited to 'DistUpgrade/DistUpgradeViewNonInteractive.py') diff --git a/DistUpgrade/DistUpgradeViewNonInteractive.py b/DistUpgrade/DistUpgradeViewNonInteractive.py new file mode 100644 index 00000000..f77d3d43 --- /dev/null +++ b/DistUpgrade/DistUpgradeViewNonInteractive.py @@ -0,0 +1,72 @@ +# DistUpgradeView.py +# +# Copyright (c) 2004,2005 Canonical +# +# Author: Michael Vogt +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +# USA + +class NonInteractiveDistUpgradeView(object): + " non-interactive version of the upgrade view " + def __init__(self): + pass + def getOpCacheProgress(self): + " return a OpProgress() subclass for the given graphic" + return apt.progress.OpProgress() + def getFetchProgress(self): + " return a fetch progress object " + return apt.progress.FetchProgress() + def getInstallProgress(self): + " return a install progress object " + return apt.progress.InstallProgress() + def updateStatus(self, msg): + """ update the current status of the distUpgrade based + on the current view + """ + pass + def setStep(self, step): + """ we have 5 steps current for a upgrade: + 1. Analyzing the system + 2. Updating repository information + 3. Performing the upgrade + 4. Post upgrade stuff + 5. Complete + """ + pass + def confirmChanges(self, summary, changes, downloadSize): + """ display the list of changed packages (apt.Package) and + return if the user confirms them + """ + self.toInstall = [] + self.toUpgrade = [] + self.toRemove = [] + for pkg in changes: + if pkg.markedInstall: self.toInstall.append(pkg.name) + elif pkg.markedUpgrade: self.toUpgrade.append(pkg.name) + elif pkg.markedDelete: self.toRemove.append(pkg.name) + # no downgrades, re-installs + assert(len(self.toInstall)+len(self.toUpgrade)+len(self.toRemove) == len(changes)) + return True + def askYesNoQuestion(self, summary, msg): + " ask a Yes/No question and return True on 'Yes' " + return True + def confirmRestart(self): + " generic ask about the restart, can be overriden " + return False + def error(self, summary, msg, extended_msg=None): + " display a error " + logging.error("%s %s (%s)" % (summary, msg, extended_msg) + -- cgit v1.2.3 From 442066f04db10be923c15455d16155358a6d5321 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Thu, 2 Feb 2006 12:56:26 +0000 Subject: * started to implement a more flexible config file approach --- DistUpgrade/DistUpgrade.cfg | 4 ++++ DistUpgrade/DistUpgradeControler.py | 14 +++++++------- DistUpgrade/DistUpgradeViewNonInteractive.py | 3 +++ 3 files changed, 14 insertions(+), 7 deletions(-) create mode 100644 DistUpgrade/DistUpgrade.cfg (limited to 'DistUpgrade/DistUpgradeViewNonInteractive.py') diff --git a/DistUpgrade/DistUpgrade.cfg b/DistUpgrade/DistUpgrade.cfg new file mode 100644 index 00000000..979d7c0c --- /dev/null +++ b/DistUpgrade/DistUpgrade.cfg @@ -0,0 +1,4 @@ +[Distro] +From=breezy +To=Dapper +ValidOrigin=Ubuntu diff --git a/DistUpgrade/DistUpgradeControler.py b/DistUpgrade/DistUpgradeControler.py index ca43e80c..1ba0f7e0 100644 --- a/DistUpgrade/DistUpgradeControler.py +++ b/DistUpgrade/DistUpgradeControler.py @@ -28,8 +28,8 @@ import subprocess import logging import re import statvfs +import ConfigParser -from UpdateManager.Common.SimpleGladeApp import SimpleGladeApp from SoftwareProperties.aptsources import SourcesList, SourceEntry from gettext import gettext as _ from DistUpgradeCache import MyCache @@ -42,13 +42,13 @@ class DistUpgradeControler(object): self._view.updateStatus(_("Reading cache")) self.cache = None + self.config = ConfigParser.ConfigParser() + self.config.read(['DistUpgrade.cfg']) + # some constants here - #self.fromDist = "hoary" - #self.toDist = "breezy" - self.fromDist = "breezy" - self.toDist = "dapper" - - self.origin = "Ubuntu" + self.fromDist = self.config.get("Distro","From") + self.toDist = self.config.get("Distro","To") + self.origin = self.config.get("Distro","ValidOrigin") # forced obsoletes self.forced_obsoletes = [] diff --git a/DistUpgrade/DistUpgradeViewNonInteractive.py b/DistUpgrade/DistUpgradeViewNonInteractive.py index f77d3d43..e8236565 100644 --- a/DistUpgrade/DistUpgradeViewNonInteractive.py +++ b/DistUpgrade/DistUpgradeViewNonInteractive.py @@ -19,6 +19,9 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 # USA +import apt +import logging + class NonInteractiveDistUpgradeView(object): " non-interactive version of the upgrade view " def __init__(self): -- cgit v1.2.3 From 44745ae2b53b6ee2ba9eca70ff3afb620e34a909 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Thu, 2 Feb 2006 18:04:49 +0000 Subject: * added ivman to forced obsoletes for kubuntu --- DistUpgrade/DistUpgrade.cfg | 3 ++- DistUpgrade/DistUpgradeViewNonInteractive.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'DistUpgrade/DistUpgradeViewNonInteractive.py') diff --git a/DistUpgrade/DistUpgrade.cfg b/DistUpgrade/DistUpgrade.cfg index cf97d16f..fdc70150 100644 --- a/DistUpgrade/DistUpgrade.cfg +++ b/DistUpgrade/DistUpgrade.cfg @@ -15,6 +15,7 @@ ForcedObsoletes=xscreensaver [kubuntu-desktop] KeyDependencies=kdm, kicker, kubuntu-artwork-usplash +ForcedObsoletes=ivman [edubuntu-desktop] KeyDependencies=edubuntu-artwork, tuxpaint @@ -30,4 +31,4 @@ BackupExt=distUpgrade From=breezy To=dapper ValidOrigin=Ubuntu -ValidMirrors = http://archive.ubuntu.com/ubuntu, http://security.ubuntu.com/ubuntu, http://archive.distrosprint/ubuntu/ \ No newline at end of file +ValidMirrors = http://archive.ubuntu.com/ubuntu, http://security.ubuntu.com/ubuntu, http://archive.distrosprint/ubuntu/ diff --git a/DistUpgrade/DistUpgradeViewNonInteractive.py b/DistUpgrade/DistUpgradeViewNonInteractive.py index e8236565..07eea2ac 100644 --- a/DistUpgrade/DistUpgradeViewNonInteractive.py +++ b/DistUpgrade/DistUpgradeViewNonInteractive.py @@ -71,5 +71,5 @@ class NonInteractiveDistUpgradeView(object): return False def error(self, summary, msg, extended_msg=None): " display a error " - logging.error("%s %s (%s)" % (summary, msg, extended_msg) + logging.error("%s %s (%s)" % (summary, msg, extended_msg)) -- cgit v1.2.3 From 831d64d85bf9ae977b388ecbe2417a0453489975 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Thu, 2 Feb 2006 19:49:42 +0000 Subject: * non-interactive code enhanced --- DistUpgrade/DistUpgradeViewNonInteractive.py | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) (limited to 'DistUpgrade/DistUpgradeViewNonInteractive.py') diff --git a/DistUpgrade/DistUpgradeViewNonInteractive.py b/DistUpgrade/DistUpgradeViewNonInteractive.py index 07eea2ac..78e8d376 100644 --- a/DistUpgrade/DistUpgradeViewNonInteractive.py +++ b/DistUpgrade/DistUpgradeViewNonInteractive.py @@ -22,6 +22,12 @@ import apt import logging +class NonInteractiveInstallProgress(InstallProgress): + def error(self, pkg, errormsg): + logging.error("got a error from dpkg for pkg: '%s': '%s'" % (pkg, errormsg)) + def conffile(self, current, new): + logging.debug("got a conffile-prompt from dpkg for file: '%s'" % current) + class NonInteractiveDistUpgradeView(object): " non-interactive version of the upgrade view " def __init__(self): @@ -34,7 +40,7 @@ class NonInteractiveDistUpgradeView(object): return apt.progress.FetchProgress() def getInstallProgress(self): " return a install progress object " - return apt.progress.InstallProgress() + return NonInteractiveInstallProgress() def updateStatus(self, msg): """ update the current status of the distUpgrade based on the current view @@ -50,18 +56,10 @@ class NonInteractiveDistUpgradeView(object): """ pass def confirmChanges(self, summary, changes, downloadSize): - """ display the list of changed packages (apt.Package) and - return if the user confirms them - """ - self.toInstall = [] - self.toUpgrade = [] - self.toRemove = [] - for pkg in changes: - if pkg.markedInstall: self.toInstall.append(pkg.name) - elif pkg.markedUpgrade: self.toUpgrade.append(pkg.name) - elif pkg.markedDelete: self.toRemove.append(pkg.name) - # no downgrades, re-installs - assert(len(self.toInstall)+len(self.toUpgrade)+len(self.toRemove) == len(changes)) + DistUpgradeView.confirmChanges(self, summary, changes, downloadSize) + logging.debug("toinstall: '%s'", % self.toInstall) + logging.debug("toupgrade: '%s'" % self.toUpgrade) + logging.debug("toremove: '%s'" % self.toRemove) return True def askYesNoQuestion(self, summary, msg): " ask a Yes/No question and return True on 'Yes' " -- cgit v1.2.3 From 2e432bba1f38efc5c61882d72f9c83a9ba26ccd9 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Thu, 2 Feb 2006 19:54:35 +0000 Subject: * small fixes on the non-interactive version --- DistUpgrade/DistUpgradeViewNonInteractive.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'DistUpgrade/DistUpgradeViewNonInteractive.py') diff --git a/DistUpgrade/DistUpgradeViewNonInteractive.py b/DistUpgrade/DistUpgradeViewNonInteractive.py index 78e8d376..bb426a7a 100644 --- a/DistUpgrade/DistUpgradeViewNonInteractive.py +++ b/DistUpgrade/DistUpgradeViewNonInteractive.py @@ -22,7 +22,7 @@ import apt import logging -class NonInteractiveInstallProgress(InstallProgress): +class NonInteractiveInstallProgress(apt.progress.InstallProgress): def error(self, pkg, errormsg): logging.error("got a error from dpkg for pkg: '%s': '%s'" % (pkg, errormsg)) def conffile(self, current, new): @@ -57,7 +57,7 @@ class NonInteractiveDistUpgradeView(object): pass def confirmChanges(self, summary, changes, downloadSize): DistUpgradeView.confirmChanges(self, summary, changes, downloadSize) - logging.debug("toinstall: '%s'", % self.toInstall) + logging.debug("toinstall: '%s'" % self.toInstall) logging.debug("toupgrade: '%s'" % self.toUpgrade) logging.debug("toremove: '%s'" % self.toRemove) return True -- cgit v1.2.3 From 4422d2689f60ec0ac2d10db07919f746724cd9b3 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Fri, 3 Feb 2006 15:37:57 +0000 Subject: * added MaxRetries to the configuration, retry on update errors as well --- DistUpgrade/DistUpgrade.cfg | 6 ++--- DistUpgrade/DistUpgradeControler.py | 33 ++++++++++++++++++---------- DistUpgrade/DistUpgradeViewNonInteractive.py | 3 ++- 3 files changed, 26 insertions(+), 16 deletions(-) (limited to 'DistUpgrade/DistUpgradeViewNonInteractive.py') diff --git a/DistUpgrade/DistUpgrade.cfg b/DistUpgrade/DistUpgrade.cfg index fdc70150..f4491202 100644 --- a/DistUpgrade/DistUpgrade.cfg +++ b/DistUpgrade/DistUpgrade.cfg @@ -1,6 +1,3 @@ -[General] -Frontend=GtkDistUpgradeView - # Distro contains global information about the upgrade [Distro] # the meta-pkgs we support @@ -32,3 +29,6 @@ From=breezy To=dapper ValidOrigin=Ubuntu ValidMirrors = http://archive.ubuntu.com/ubuntu, http://security.ubuntu.com/ubuntu, http://archive.distrosprint/ubuntu/ + +[Network] +MaxRetries=3 \ No newline at end of file diff --git a/DistUpgrade/DistUpgradeControler.py b/DistUpgrade/DistUpgradeControler.py index 3a43d517..1bcf81d3 100644 --- a/DistUpgrade/DistUpgradeControler.py +++ b/DistUpgrade/DistUpgradeControler.py @@ -158,17 +158,25 @@ class DistUpgradeControler(object): progress = self._view.getFetchProgress() # FIXME: retry here too? just like the DoDistUpgrade? # also remove all files from the lists partial dir! - try: - res = self.cache.update(progress) - except IOError, e: - self._view.error(_("Error during update"), - _("A problem occured during the update. " - "This is usually some sort of network " - "problem, please check your network " - "connection and retry."), - "%s" % e) - return False - return True + currentRetry = 0 + maxRetries = self.config.get("Network","MaxRetries") + while currentRetry < maxRetries: + try: + res = self.cache.update(progress) + except IOError, e: + logging.error("IOError in cache.update(): '%s'. Retrying (currentTry: %s)" % (e,currentTry)) + currentRetry += 1 + continue + # no exception, so all was fine, we are done + return True + + self._view.error(_("Error during update"), + _("A problem occured during the update. " + "This is usually some sort of network " + "problem, please check your network " + "connection and retry."), "%s" % e) + return False + def askDistUpgrade(self): if not self.cache.distUpgrade(self._view): @@ -196,7 +204,8 @@ class DistUpgradeControler(object): fprogress = self._view.getFetchProgress() iprogress = self._view.getInstallProgress() # retry the fetching in case of errors - while currentRetry < 3: + maxRetries = self.config.get("Network","MaxRetries") + while currentRetry < maxRetries: try: res = self.cache.commit(fprogress,iprogress) except SystemError, e: diff --git a/DistUpgrade/DistUpgradeViewNonInteractive.py b/DistUpgrade/DistUpgradeViewNonInteractive.py index bb426a7a..6bd110e4 100644 --- a/DistUpgrade/DistUpgradeViewNonInteractive.py +++ b/DistUpgrade/DistUpgradeViewNonInteractive.py @@ -21,6 +21,7 @@ import apt import logging +from DistUpgradeView import DistUpgradeView class NonInteractiveInstallProgress(apt.progress.InstallProgress): def error(self, pkg, errormsg): @@ -28,7 +29,7 @@ class NonInteractiveInstallProgress(apt.progress.InstallProgress): def conffile(self, current, new): logging.debug("got a conffile-prompt from dpkg for file: '%s'" % current) -class NonInteractiveDistUpgradeView(object): +class NonInteractiveDistUpgradeView(DistUpgradeView): " non-interactive version of the upgrade view " def __init__(self): pass -- cgit v1.2.3 From 0900e0b357b949f3d87c7a885b4c27e92c2f1d3d Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Fri, 3 Feb 2006 18:03:50 +0000 Subject: * added short sleeps at stratic points --- DistUpgrade/DistUpgradeViewGtk.py | 2 ++ DistUpgrade/DistUpgradeViewNonInteractive.py | 3 +++ 2 files changed, 5 insertions(+) (limited to 'DistUpgrade/DistUpgradeViewNonInteractive.py') diff --git a/DistUpgrade/DistUpgradeViewGtk.py b/DistUpgrade/DistUpgradeViewGtk.py index f32533db..c8fd5ba4 100644 --- a/DistUpgrade/DistUpgradeViewGtk.py +++ b/DistUpgrade/DistUpgradeViewGtk.py @@ -29,6 +29,7 @@ import gobject import pango import sys import logging +import time import apt import apt_pkg @@ -169,6 +170,7 @@ class GtkInstallProgressAdapter(InstallProgress): self.label_status.set_text(self.status) while gtk.events_pending(): gtk.main_iteration() + time.sleep(0.01) class GtkDistUpgradeView(DistUpgradeView,SimpleGladeApp): diff --git a/DistUpgrade/DistUpgradeViewNonInteractive.py b/DistUpgrade/DistUpgradeViewNonInteractive.py index 6bd110e4..beb843d2 100644 --- a/DistUpgrade/DistUpgradeViewNonInteractive.py +++ b/DistUpgrade/DistUpgradeViewNonInteractive.py @@ -21,6 +21,7 @@ import apt import logging +import time from DistUpgradeView import DistUpgradeView class NonInteractiveInstallProgress(apt.progress.InstallProgress): @@ -28,6 +29,8 @@ class NonInteractiveInstallProgress(apt.progress.InstallProgress): logging.error("got a error from dpkg for pkg: '%s': '%s'" % (pkg, errormsg)) def conffile(self, current, new): logging.debug("got a conffile-prompt from dpkg for file: '%s'" % current) + def updateInterface(self): + time.sleep(0.1) class NonInteractiveDistUpgradeView(DistUpgradeView): " non-interactive version of the upgrade view " -- cgit v1.2.3 From 694ea8be861e66124617709eba63408da07e10c5 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Sat, 4 Feb 2006 12:04:00 +0000 Subject: * make the sleep in non-interactive view way shorter --- DistUpgrade/DistUpgradeViewNonInteractive.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'DistUpgrade/DistUpgradeViewNonInteractive.py') diff --git a/DistUpgrade/DistUpgradeViewNonInteractive.py b/DistUpgrade/DistUpgradeViewNonInteractive.py index beb843d2..f6845a49 100644 --- a/DistUpgrade/DistUpgradeViewNonInteractive.py +++ b/DistUpgrade/DistUpgradeViewNonInteractive.py @@ -30,7 +30,7 @@ class NonInteractiveInstallProgress(apt.progress.InstallProgress): def conffile(self, current, new): logging.debug("got a conffile-prompt from dpkg for file: '%s'" % current) def updateInterface(self): - time.sleep(0.1) + time.sleep(0.001) class NonInteractiveDistUpgradeView(DistUpgradeView): " non-interactive version of the upgrade view " -- cgit v1.2.3 From 52d4a8c09000ea446458ff401f2c0a9d620212cb Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Sat, 4 Feb 2006 15:37:41 +0000 Subject: * view can be configured via the config file now --- DistUpgrade/DistUpgrade.cfg | 4 ++++ DistUpgrade/DistUpgradeViewGtk.py | 2 +- DistUpgrade/DistUpgradeViewNonInteractive.py | 3 ++- DistUpgrade/dist-upgrade.py | 13 +++++++++++-- SoftwareProperties/__init__.py | 1 - UpdateManager/UpdateManager.py | 2 +- gnome-software-properties | 2 +- 7 files changed, 20 insertions(+), 7 deletions(-) (limited to 'DistUpgrade/DistUpgradeViewNonInteractive.py') diff --git a/DistUpgrade/DistUpgrade.cfg b/DistUpgrade/DistUpgrade.cfg index f4491202..e081313a 100644 --- a/DistUpgrade/DistUpgrade.cfg +++ b/DistUpgrade/DistUpgrade.cfg @@ -1,3 +1,7 @@ +[View] +View=DistUpgradeViewGtk +#View=DistUpgradeViewNonInteractive + # Distro contains global information about the upgrade [Distro] # the meta-pkgs we support diff --git a/DistUpgrade/DistUpgradeViewGtk.py b/DistUpgrade/DistUpgradeViewGtk.py index c8fd5ba4..b4ad4a0a 100644 --- a/DistUpgrade/DistUpgradeViewGtk.py +++ b/DistUpgrade/DistUpgradeViewGtk.py @@ -173,7 +173,7 @@ class GtkInstallProgressAdapter(InstallProgress): time.sleep(0.01) -class GtkDistUpgradeView(DistUpgradeView,SimpleGladeApp): +class DistUpgradeViewGtk(DistUpgradeView,SimpleGladeApp): " gtk frontend of the distUpgrade tool " diff --git a/DistUpgrade/DistUpgradeViewNonInteractive.py b/DistUpgrade/DistUpgradeViewNonInteractive.py index f6845a49..7a8fa7eb 100644 --- a/DistUpgrade/DistUpgradeViewNonInteractive.py +++ b/DistUpgrade/DistUpgradeViewNonInteractive.py @@ -30,9 +30,10 @@ class NonInteractiveInstallProgress(apt.progress.InstallProgress): def conffile(self, current, new): logging.debug("got a conffile-prompt from dpkg for file: '%s'" % current) def updateInterface(self): + apt.progress.InstallProgress.updateInterface(self) time.sleep(0.001) -class NonInteractiveDistUpgradeView(DistUpgradeView): +class DistUpgradeViewNonInteractive(DistUpgradeView): " non-interactive version of the upgrade view " def __init__(self): pass diff --git a/DistUpgrade/dist-upgrade.py b/DistUpgrade/dist-upgrade.py index 14f9f4a1..437be42d 100755 --- a/DistUpgrade/dist-upgrade.py +++ b/DistUpgrade/dist-upgrade.py @@ -1,10 +1,10 @@ #!/usr/bin/python2.4 -from DistUpgradeViewGtk import GtkDistUpgradeView from DistUpgradeControler import DistUpgradeControler from DistUpgradeConfigParser import DistUpgradeConfig import logging import os +import sys if __name__ == "__main__": @@ -13,7 +13,16 @@ if __name__ == "__main__": format='%(asctime)s %(levelname)s %(message)s', filemode='w') - view = GtkDistUpgradeView() + config = DistUpgradeConfig() + requested_view= config.get("View","View") + try: + view_modul = __import__(requested_view) + view_class = getattr(view_modul, requested_view) + view = view_class() + except (ImportError, AttributeError): + logging.error("can't import view '%s'" % requested_view) + print "can't find %s" % requested_view + sys.exit(1) app = DistUpgradeControler(view) app.run() diff --git a/SoftwareProperties/__init__.py b/SoftwareProperties/__init__.py index 1e6834bd..e69de29b 100644 --- a/SoftwareProperties/__init__.py +++ b/SoftwareProperties/__init__.py @@ -1 +0,0 @@ -from SoftwareProperties import SoftwareProperties diff --git a/UpdateManager/UpdateManager.py b/UpdateManager/UpdateManager.py index de77f041..3724de94 100644 --- a/UpdateManager/UpdateManager.py +++ b/UpdateManager/UpdateManager.py @@ -637,7 +637,7 @@ class UpdateManager(SimpleGladeApp): # self.window_main.set_sensitive(True) self.window_main.set_sensitive(False) from SoftwareProperties import SoftwareProperties - prop = SoftwareProperties(self.datadir, None) + prop = SoftwareProperties.SoftwareProperties(self.datadir, None) prop.window_main.set_transient_for(self.window_main) prop.run() prop.window_main.hide() diff --git a/gnome-software-properties b/gnome-software-properties index d5cbd0ce..a8074f7e 100644 --- a/gnome-software-properties +++ b/gnome-software-properties @@ -37,7 +37,7 @@ from optparse import OptionParser #sys.path.append("@prefix@/share/update-manager/python") -import SoftwareProperties +from SoftwareProperties import SoftwareProperties if __name__ == "__main__": _ = gettext.gettext -- cgit v1.2.3