Merge lp:~ubuntu-core-dev/ubuntu-release-upgrader/split into lp:ubuntu-release-upgrader

Proposed by Michael Terry
Status: Merged
Merged at revision: 2509
Proposed branch: lp:~ubuntu-core-dev/ubuntu-release-upgrader/split
Merge into: lp:ubuntu-release-upgrader
Diff against target: 257419 lines (+61554/-117564)
254 files modified
BUGS (+0/-5)
ChangeLog (+0/-62)
DistUpgrade/DistUpgradeApport.py (+4/-4)
DistUpgrade/DistUpgradeCache.py (+3/-3)
DistUpgrade/DistUpgradeConfigParser.py (+1/-1)
DistUpgrade/DistUpgradeController.py (+19/-19)
DistUpgrade/DistUpgradeFetcherCore.py (+3/-3)
DistUpgrade/DistUpgradeQuirks.py (+1/-1)
DistUpgrade/DistUpgradeView.py (+1/-1)
DistUpgrade/DistUpgradeViewGtk.py (+3/-3)
DistUpgrade/DistUpgradeViewGtk3.py (+3/-3)
DistUpgrade/DistUpgradeViewKDE.py (+7/-7)
DistUpgrade/DistUpgradeViewText.py (+4/-4)
DistUpgrade/SimpleGtk3builderApp.py (+61/-0)
DistUpgrade/SimpleGtkbuilderApp.py (+61/-0)
DistUpgrade/TODO (+2/-2)
DistUpgrade/build-tarball.sh (+2/-2)
DistUpgrade/crashdialog.ui (+1/-1)
DistUpgrade/removal_blacklist.cfg (+2/-1)
DistUpgrade/xorg_fix_proprietary.py (+4/-4)
LGPL (+0/-510)
README (+0/-18)
TODO (+0/-22)
UpdateManager/ChangelogViewer.py (+0/-283)
UpdateManager/Core/AlertWatcher.py (+0/-96)
UpdateManager/Core/DistUpgradeFetcherCore.py (+0/-313)
UpdateManager/Core/MetaRelease.py (+0/-350)
UpdateManager/Core/MyCache.py (+0/-366)
UpdateManager/Core/UpdateList.py (+0/-102)
UpdateManager/Core/roam.py (+0/-205)
UpdateManager/Core/utils.py (+0/-510)
UpdateManager/Dialogs.py (+0/-235)
UpdateManager/DistUpgradeFetcher.py (+0/-143)
UpdateManager/DistUpgradeFetcherKDE.py (+0/-188)
UpdateManager/GtkProgress.py (+0/-89)
UpdateManager/HelpViewer.py (+0/-33)
UpdateManager/InstallProgress.py (+0/-93)
UpdateManager/MetaReleaseGObject.py (+0/-57)
UpdateManager/ReleaseNotesViewer.py (+0/-186)
UpdateManager/ReleaseNotesViewerWebkit.py (+0/-54)
UpdateManager/SimpleGtk3builderApp.py (+0/-61)
UpdateManager/SimpleGtkbuilderApp.py (+0/-61)
UpdateManager/UnitySupport.py (+0/-94)
UpdateManager/UpdateManager.py (+0/-335)
UpdateManager/UpdateProgress.py (+0/-80)
UpdateManager/UpdatesAvailable.py (+0/-713)
UpdateManager/__init__.py (+0/-1)
UpdateManager/backend/InstallBackendAptdaemon.py (+0/-230)
UpdateManager/backend/InstallBackendSynaptic.py (+0/-73)
UpdateManager/backend/__init__.py (+0/-63)
UpdateManager/check-meta-release.py (+0/-32)
UpdateManager/dialog_release_notes.ui (+0/-70)
UpdateManager/fetch-progress.ui (+0/-106)
UpdateManagerText/UpdateManagerText.py (+0/-191)
check-new-release-gtk (+6/-6)
data/Makefile (+1/-1)
data/com.ubuntu.update-manager.gschema.xml.in (+0/-54)
data/gtkbuilder/UpdateManager.ui (+0/-504)
data/icons/scalable/apps/system-software-update.svg (+0/-1519)
data/update-manager.8 (+0/-78)
data/update-manager.convert (+0/-9)
data/update-manager.desktop.in (+0/-10)
debian/91-release-upgrade (+2/-2)
debian/changelog (+6/-0)
debian/compat (+1/-1)
debian/control (+42/-78)
debian/copyright (+25/-22)
debian/python-update-manager.install (+0/-6)
debian/python3-dist-upgrade.install (+1/-0)
debian/python3-update-manager.install (+0/-6)
debian/release-upgrade-motd (+3/-3)
debian/rules (+1/-2)
debian/source/format (+1/-0)
debian/source_ubuntu-release-upgrader.py (+20/-33)
debian/ubuntu-release-upgrader-core.dirs (+1/-1)
debian/ubuntu-release-upgrader-core.install (+3/-4)
debian/ubuntu-release-upgrader-core.links (+1/-1)
debian/ubuntu-release-upgrader-core.postinst (+1/-1)
debian/ubuntu-release-upgrader-core.preinst (+1/-1)
debian/ubuntu-release-upgrader-gtk.install (+2/-0)
debian/ubuntu-release-upgrader-qt.install (+1/-0)
debian/update-manager-kde.install (+0/-4)
debian/update-manager-text.install (+0/-2)
debian/update-manager.install (+0/-19)
debian/update-manager.manpages (+0/-1)
do-release-upgrade (+3/-3)
help/C/Makefile.am (+0/-7)
help/C/fdl-appendix.xml (+0/-655)
help/C/legal.xml (+0/-76)
help/C/update-manager-C.omf (+0/-18)
help/C/update-manager.xml (+0/-1023)
janitor/__init__.py (+0/-24)
janitor/plugincore/NEWS.rst (+0/-7)
janitor/plugincore/__init__.py (+0/-17)
janitor/plugincore/core/file_cruft.py (+0/-53)
janitor/plugincore/core/missing_package_cruft.py (+0/-52)
janitor/plugincore/core/package_cruft.py (+0/-61)
janitor/plugincore/cruft.py (+0/-159)
janitor/plugincore/docs/README.rst (+0/-201)
janitor/plugincore/exceptions.py (+0/-42)
janitor/plugincore/i18n.py (+0/-34)
janitor/plugincore/manager.py (+0/-185)
janitor/plugincore/plugin.py (+0/-81)
janitor/plugincore/plugins/deb_plugin.py (+0/-42)
janitor/plugincore/plugins/dpkg_status_plugin.py (+0/-80)
janitor/plugincore/plugins/kdelibs4to5_plugin.py (+0/-51)
janitor/plugincore/plugins/langpack_manual_plugin.py (+0/-76)
janitor/plugincore/plugins/remove_lilo_plugin.py (+0/-54)
janitor/plugincore/testing/helpers.py (+0/-68)
janitor/plugincore/tests/data/alpha_plugin.py (+0/-48)
janitor/plugincore/tests/data/bravo_plugin.py (+0/-48)
janitor/plugincore/tests/data/charlie_plugin.py (+0/-48)
janitor/plugincore/tests/test_deb_plugin.py (+0/-44)
janitor/plugincore/tests/test_documentation.py (+0/-93)
janitor/plugincore/tests/test_dpkg_status_plugin.py (+0/-45)
janitor/plugincore/tests/test_file_cruft.py (+0/-81)
janitor/plugincore/tests/test_manager.py (+0/-171)
janitor/plugincore/tests/test_missing_package_cruft.py (+0/-62)
janitor/plugincore/tests/test_package_cruft.py (+0/-62)
po/Makefile (+1/-1)
po/POTFILES.in (+0/-53)
po/af.po (+362/-876)
po/am.po (+436/-878)
po/an.po (+217/-865)
po/ar.po (+774/-942)
po/ast.po (+786/-952)
po/az.po (+312/-868)
po/be.po (+722/-947)
po/bg.po (+712/-947)
po/bn.po (+802/-970)
po/bo.po (+618/-923)
po/br.po (+590/-935)
po/bs.po (+794/-951)
po/ca.po (+796/-958)
po/ca@valencia.po (+721/-956)
po/ceb.po (+215/-866)
po/ckb.po (+215/-866)
po/crh.po (+686/-988)
po/cs.po (+794/-961)
po/csb.po (+505/-893)
po/cv.po (+252/-866)
po/cy.po (+618/-933)
po/da.po (+794/-955)
po/de.po (+819/-982)
po/dv.po (+242/-865)
po/el.po (+806/-966)
po/en_AU.po (+823/-988)
po/en_CA.po (+651/-980)
po/en_GB.po (+818/-982)
po/eo.po (+785/-949)
po/es.po (+797/-961)
po/et.po (+695/-935)
po/eu.po (+712/-944)
po/fa.po (+215/-865)
po/fi.po (+780/-947)
po/fil.po (+437/-882)
po/fo.po (+215/-866)
po/fr.po (+811/-972)
po/fur.po (+291/-870)
po/fy.po (+226/-868)
po/ga.po (+215/-867)
po/gd.po (+811/-969)
po/gl.po (+795/-959)
po/gu.po (+215/-866)
po/gv.po (+215/-867)
po/he.po (+774/-940)
po/hi.po (+685/-927)
po/hr.po (+796/-955)
po/hu.po (+780/-946)
po/hy.po (+215/-865)
po/id.po (+707/-947)
po/is.po (+583/-912)
po/it.po (+798/-962)
po/ja.po (+788/-953)
po/jv.po (+215/-866)
po/ka.po (+405/-883)
po/kk.po (+708/-944)
po/km.po (+764/-931)
po/kn.po (+215/-866)
po/ko.po (+775/-940)
po/ku.po (+366/-876)
po/ky.po (+215/-865)
po/lb.po (+215/-866)
po/lo.po (+215/-865)
po/lt.po (+798/-961)
po/lv.po (+795/-958)
po/mk.po (+378/-881)
po/ml.po (+233/-865)
po/mn.po (+215/-865)
po/mr.po (+328/-878)
po/ms.po (+788/-955)
po/mus.po (+215/-866)
po/my.po (+225/-864)
po/nb.po (+758/-951)
po/nds.po (+253/-871)
po/ne.po (+232/-865)
po/nl.po (+805/-966)
po/nn.po (+709/-948)
po/oc.po (+808/-970)
po/pa.po (+410/-872)
po/pl.po (+758/-961)
po/ps.po (+215/-866)
po/pt.po (+721/-957)
po/pt_BR.po (+796/-958)
po/qu.po (+215/-866)
po/ro.po (+808/-971)
po/ru.po (+786/-949)
po/rw.po (+229/-865)
po/sc.po (+215/-866)
po/sco.po (+215/-866)
po/sd.po (+215/-866)
po/shn.po (+215/-866)
po/si.po (+215/-866)
po/sk.po (+800/-962)
po/sl.po (+794/-959)
po/sq.po (+802/-967)
po/sr.po (+786/-955)
po/sv.po (+785/-948)
po/ta.po (+218/-866)
po/ta_LK.po (+218/-866)
po/te.po (+435/-874)
po/th.po (+633/-910)
po/tl.po (+488/-889)
po/tr.po (+788/-953)
po/ubuntu-release-upgrader.pot (+216/-867)
po/ug.po (+785/-947)
po/uk.po (+798/-960)
po/ur.po (+215/-866)
po/uz.po (+215/-865)
po/vi.po (+776/-941)
po/xh.po (+215/-866)
po/zh_CN.po (+750/-918)
po/zh_HK.po (+680/-919)
po/zh_TW.po (+747/-916)
po/zu.po (+220/-865)
setup.cfg (+1/-6)
setup.py (+6/-30)
tests/aptroot-update-origin/etc/apt/sources.list (+0/-5)
tests/interactive_fetch_release_upgrader.py (+0/-89)
tests/patchdir/pycompile_orig (+1/-1)
tests/test_cache.py (+0/-37)
tests/test_changelog.py (+0/-66)
tests/test_country_mirror.py (+1/-1)
tests/test_dist_upgrade_fetcher_core.py (+1/-1)
tests/test_end_of_life.py (+6/-1)
tests/test_meta_release_core.py (+0/-144)
tests/test_proxy.py (+0/-30)
tests/test_quirks.py (+1/-1)
tests/test_update_origin.py (+0/-124)
tests/test_utils.py (+0/-65)
tests/test_xorg_fix_intrepid.py (+1/-1)
ubuntu-support-status (+0/-185)
update-manager (+0/-131)
update-manager-text (+0/-71)
To merge this branch: bzr merge lp:~ubuntu-core-dev/ubuntu-release-upgrader/split
Reviewer Review Type Date Requested Status
Ken VanDine Approve
Barry Warsaw (community) Needs Fixing
Michael Vogt Pending
Review via email: mp+109209@code.launchpad.net

Description of the change

As discussed at UDS, we wanted to split out the release upgrade code from update-manager to its own source package.

This is my attempt at doing so. I'm not *super* familiar with the code, so I may have made a mistake but for the most part it was straightforward.

Some notes:
 * This still uses some UpdateManager imports, so we hard-dep on update-manager.
 * This still uses a couple keys from update-manager's gsettings schema. It didn't seem worth the pain of transitioning.
 * This still uses the same /etc/update-manager location that update-manager did (although all files under that directory are really owned by this package now). I used appropriate Breaks/Replaces lines, but didn't bother renaming the directory. It didn't seem worth the effort, especially since we'd also have to migrate user files in /etc/update-manager/release-upgrades.d/
 * I re-enabled some tests that had been dormant (chmod +x)
 * A couple apport-oriented Python bits pretend to be /usr/bin/update-manager. I changed those to pretend to be /usr/bin/do-release-upgrade.
 * I split packages into core/gtk/qt, matching what they were in update-manager, although the frontend packages are real tiny.

To post a comment you must log in.
2457. By Michael Terry

merge from lp:update-manager

2458. By Michael Terry

split package into python-* modules too

2459. By Michael Terry

drop python2 module and have the core depend on the python3 module

2460. By Michael Terry

bump version of update-manager to Break because they just released a new one

Revision history for this message
Barry Warsaw (barry) wrote :

Diff against target: 224858 lines (+111053/-13464) 238 files modified (has conflicts)

Ouch! I'm guessing the branch is out of date with the latest trunk of update-manager. Could you take a look at updating your branch, hopefully reducing the diff lines and resolving the conflicts? Thanks!

review: Needs Fixing
2461. By Michael Terry

merge from trunk again

2462. By Michael Terry

merge from trunk

Revision history for this message
Michael Terry (mterry) wrote :

Updated to match latest update-manager trunk again.

Revision history for this message
Ken VanDine (ken-vandine) wrote :

The symlinks to files included in python-update-manager should probably be removed. That is a temporary package, better to fix the imports.

review: Needs Fixing
2463. By Michael Terry

drop some added files from UpdateManager merge

2464. By Michael Terry

drop any symlink dependencies on UpdateManager and make them real imports; copy a couple tiny classes from the UI part of UpdateManager here

Revision history for this message
Ken VanDine (ken-vandine) wrote :

Tests are still failing, it looks like some of the update manager specific tests are still there and probably just need to be removed.

./test_meta_release_core.py
Traceback (most recent call last):
  File "./test_meta_release_core.py", line 45, in <module>
    from DistUpgrade.MetaRelease import MetaReleaseCore, Dist
ImportError: No module named MetaRelease

review: Needs Fixing
2465. By Michael Terry

more import fixes

Revision history for this message
Ken VanDine (ken-vandine) wrote :

All tests that are expected to pass are passing. Looks good now that the symlinks are fixed up.

review: Approve
2466. By Michael Terry

fix versions of update-manager that we Break, the other branch got merged earlier than I expected

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== removed file 'BUGS'
--- BUGS 2006-09-11 08:13:06 +0000
+++ BUGS 1970-01-01 00:00:00 +0000
@@ -1,5 +0,0 @@
1* aptsources.py:
2- when turning off a new sources.list entry for the runing distro
3 (e.g. multiverse in a full edgy) and it is turned on again, the
4 source code checkbox becomes only half-checked
5- when turning off/on a entry the comments become disordered
60
=== removed file 'ChangeLog'
--- ChangeLog 2005-11-15 13:18:07 +0000
+++ ChangeLog 1970-01-01 00:00:00 +0000
@@ -1,62 +0,0 @@
12005-04-04 Michael Vogt <mvo@debian.org>
2
3 * configure.in: Added "xh" to ALL_LINGUAS.
4
52005-04-01 Steve Murphy <murf@e-tools.com>
6
7 * configure.in: Added "rw" to ALL_LINGUAS.
8
92005-03-29 Raphael Higino <raphaelh@cvs.gnome.org>
10
11 * configure.in: Added pt_BR to ALL_LINGUAS.
12
132005-03-29 Zygmunt Krynicki <zyga@www.suxx.pl>
14
15 * src/dialog_apt_key.py.in: Enabled translation of known keys
16
172005-03-24 Michiel Sikkes <michiel@eyesopened.nl>
18
19 * data/update-manager.glade: Added help button. Put package count next
20 to reload button above updatelist.
21 * src/update-manager.in: Implemented help button.
22 * configure.in: Added ja to ALL_LINGUAS.
23
242005-03-21 Adam Weinberger <adamw@gnome.org>
25
26 * configure.in: Added en_CA to ALL_LINGUAS.
27
282005-03-21 Christian Rose <menthos@menthos.com>
29
30 * configure.in: Added "sv" to ALL_LINGUAS.
31 Also sorted the language entries in the ALL_LINGUAS line,
32 so that it will be possible to spot duplicates or omissions.
33
342005-03-11 Michiel Sikkes <michiel@eyesopened.nl>
35
36 * configure.in: Added el (Greek) to ALL_LINGUAS.
37
382005-03-03 Dan Damian <dand@gnome.ro>
39
40 * configure.in: Added ro (Romanian) to ALL_LINGUAS.
41
422005-03-10 Zygmunt Krynicki <zyga@www.suxx.pl>
43
44 * Improved translation support
45
462005-02-18 Michiel Sikkes <michiel@eyesopened.nl>
47
48 * Added window title to the synaptic gtk socket window.
49
502005-02-18 Michiel Sikkes <michiel@eyesopened.nl>
51
52 * Updated strings to have more consistent messages and it's not a pain
53 in the ass to translate ;).
54 * Merge from branches/release-37-2.
55
562005-01-27 Martin Willemoes Hansen <mwh@sysrq.dk>
57
58 * da.po: Added Danish translation.
59
602004-10-25 Michiel Sikkes <michiel@eyesopened.nl>
61
62 * Initial release.
630
=== modified file 'DistUpgrade/DistUpgradeApport.py'
--- DistUpgrade/DistUpgradeApport.py 2012-06-18 18:41:13 +0000
+++ DistUpgrade/DistUpgradeApport.py 2012-06-27 19:25:24 +0000
@@ -15,11 +15,11 @@
15 except ImportError as e:15 except ImportError as e:
16 logging.error("failed to import apport python module, can't report bug: %s" % e)16 logging.error("failed to import apport python module, can't report bug: %s" % e)
17 return False17 return False
18 # we pretend we are update-manager18 # we pretend we are do-release-upgrade
19 sys.argv[0] = "/usr/bin/update-manager"19 sys.argv[0] = "/usr/bin/do-release-upgrade"
20 apport_excepthook(type, value, tb)20 apport_excepthook(type, value, tb)
21 # now add the files in /var/log/dist-upgrade/*21 # now add the files in /var/log/dist-upgrade/*
22 if os.path.exists('/var/crash/_usr_bin_update-manager.0.crash'):22 if os.path.exists('/var/crash/_usr_bin_do-release-upgrade.0.crash'):
23 report = Report()23 report = Report()
24 report.setdefault('Tags', 'dist-upgrade')24 report.setdefault('Tags', 'dist-upgrade')
25 report['Tags'] += ' dist-upgrade'25 report['Tags'] += ' dist-upgrade'
@@ -28,7 +28,7 @@
28 if not os.path.isfile(f) or os.path.getsize(f) == 0:28 if not os.path.isfile(f) or os.path.getsize(f) == 0:
29 continue29 continue
30 report[f.replace(".", "").replace("-", "")] = (open(f), )30 report[f.replace(".", "").replace("-", "")] = (open(f), )
31 report.add_to_existing('/var/crash/_usr_bin_update-manager.0.crash')31 report.add_to_existing('/var/crash/_usr_bin_do-release-upgrade.0.crash')
32 return True32 return True
3333
3434
3535
=== modified file 'DistUpgrade/DistUpgradeCache.py'
--- DistUpgrade/DistUpgradeCache.py 2012-06-13 12:45:49 +0000
+++ DistUpgrade/DistUpgradeCache.py 2012-06-27 19:25:24 +0000
@@ -40,7 +40,7 @@
40from .DistUpgradeGettext import gettext as _40from .DistUpgradeGettext import gettext as _
41from .DistUpgradeGettext import ngettext41from .DistUpgradeGettext import ngettext
4242
43from .utils import inside_chroot, estimate_kernel_size_in_boot43from UpdateManager.Core.utils import inside_chroot, estimate_kernel_size_in_boot
4444
45class CacheException(Exception):45class CacheException(Exception):
46 pass46 pass
@@ -704,7 +704,7 @@
704 "please try again later.")704 "please try again later.")
705 else:705 else:
706 details += _("If none of this applies, then please report this bug using "706 details += _("If none of this applies, then please report this bug using "
707 "the command 'ubuntu-bug update-manager' in a terminal.")707 "the command 'ubuntu-bug ubuntu-release-upgrader-core' in a terminal.")
708 # make the error text available again on stdout for the708 # make the error text available again on stdout for the
709 # text frontend709 # text frontend
710 self._stopAptResolverLog()710 self._stopAptResolverLog()
@@ -915,7 +915,7 @@
915 _("It was impossible to install a "915 _("It was impossible to install a "
916 "required package. Please report "916 "required package. Please report "
917 "this as a bug using "917 "this as a bug using "
918 "'ubuntu-bug update-manager' in "918 "'ubuntu-bug ubuntu-release-upgrader-core' in "
919 "a terminal."))919 "a terminal."))
920 return False920 return False
921 logging.debug("marked_install: '%s' -> '%s'" % (key, self[key].marked_install))921 logging.debug("marked_install: '%s' -> '%s'" % (key, self[key].marked_install))
922922
=== modified file 'DistUpgrade/DistUpgradeConfigParser.py'
--- DistUpgrade/DistUpgradeConfigParser.py 2012-06-11 10:46:56 +0000
+++ DistUpgrade/DistUpgradeConfigParser.py 2012-06-27 19:25:24 +0000
@@ -16,7 +16,7 @@
16import logging16import logging
17import glob17import glob
1818
19CONFIG_OVERRIDE_DIR = "/etc/update-manager/release-upgrades.d"19CONFIG_OVERRIDE_DIR = "/etc/ubuntu-release-upgrader/release-upgrades.d"
2020
21class DistUpgradeConfig(SafeConfigParser):21class DistUpgradeConfig(SafeConfigParser):
22 def __init__(self, datadir, name="DistUpgrade.cfg", 22 def __init__(self, datadir, name="DistUpgrade.cfg",
2323
=== modified file 'DistUpgrade/DistUpgradeController.py'
--- DistUpgrade/DistUpgradeController.py 2012-06-11 12:09:52 +0000
+++ DistUpgrade/DistUpgradeController.py 2012-06-27 19:25:24 +0000
@@ -45,14 +45,14 @@
45except ImportError:45except ImportError:
46 # < 3.046 # < 3.0
47 from ConfigParser import SafeConfigParser, NoOptionError47 from ConfigParser import SafeConfigParser, NoOptionError
48from .utils import (country_mirror,48from UpdateManager.Core.utils import (country_mirror,
49 url_downloadable,49 url_downloadable,
50 check_and_fix_xbit,50 check_and_fix_xbit,
51 get_arch,51 get_arch,
52 iptables_active,52 iptables_active,
53 inside_chroot,53 inside_chroot,
54 get_string_with_no_auth_from_source_entry,54 get_string_with_no_auth_from_source_entry,
55 is_child_of_process_name)55 is_child_of_process_name)
56from string import Template56from string import Template
57try:57try:
58 from urllib.parse import urlsplit58 from urllib.parse import urlsplit
@@ -105,8 +105,8 @@
105 self.options = options105 self.options = options
106106
107 # init gettext107 # init gettext
108 gettext.bindtextdomain("update-manager",localedir)108 gettext.bindtextdomain("ubuntu-release-upgrader",localedir)
109 gettext.textdomain("update-manager")109 gettext.textdomain("ubuntu-release-upgrader")
110110
111 # setup the view111 # setup the view
112 logging.debug("Using '%s' view" % distUpgradeView.__class__.__name__)112 logging.debug("Using '%s' view" % distUpgradeView.__class__.__name__)
@@ -305,7 +305,7 @@
305 and we have network - we will then try to fetch a update305 and we have network - we will then try to fetch a update
306 of ourself306 of ourself
307 """ 307 """
308 from .MetaRelease import MetaReleaseCore308 from UpdateManager.Core.MetaRelease import MetaReleaseCore
309 from .DistUpgradeFetcherSelf import DistUpgradeFetcherSelf309 from .DistUpgradeFetcherSelf import DistUpgradeFetcherSelf
310 # check if we run from a LTS 310 # check if we run from a LTS
311 forceLTS=False311 forceLTS=False
@@ -534,7 +534,7 @@
534 # we replace the sources.list with a single534 # we replace the sources.list with a single
535 # line to ubuntu-main535 # line to ubuntu-main
536 logging.warning('get_distro().enable_component("man") failed, overwriting sources.list instead as last resort')536 logging.warning('get_distro().enable_component("man") failed, overwriting sources.list instead as last resort')
537 s = "# auto generated by update-manager"537 s = "# auto generated by ubuntu-release-upgrader"
538 s += "deb http://archive.ubuntu.com/ubuntu %s main restricted" % self.toDist538 s += "deb http://archive.ubuntu.com/ubuntu %s main restricted" % self.toDist
539 s += "deb http://archive.ubuntu.com/ubuntu %s-updates main restricted" % self.toDist539 s += "deb http://archive.ubuntu.com/ubuntu %s-updates main restricted" % self.toDist
540 s += "deb http://security.ubuntu.com/ubuntu %s-security main restricted" % self.toDist540 s += "deb http://security.ubuntu.com/ubuntu %s-security main restricted" % self.toDist
@@ -771,7 +771,7 @@
771 _("Upgrading the repository information "771 _("Upgrading the repository information "
772 "resulted in a invalid file so a bug "772 "resulted in a invalid file so a bug "
773 "reporting process is being started."))773 "reporting process is being started."))
774 subprocess.Popen(["apport-bug", "update-manager"])774 subprocess.Popen(["apport-bug", "ubuntu-release-upgrader"])
775 return False775 return False
776776
777 if self.sources_disabled:777 if self.sources_disabled:
@@ -1083,8 +1083,8 @@
1083 # if its a ordering bug we can cleanly revert to1083 # if its a ordering bug we can cleanly revert to
1084 # the previous release, no packages have been installed1084 # the previous release, no packages have been installed
1085 # yet (LP: #328655, #356781)1085 # yet (LP: #328655, #356781)
1086 if os.path.exists("/var/run/update-manager-apt-exception"):1086 if os.path.exists("/var/run/ubuntu-release-upgrader-apt-exception"):
1087 e = open("/var/run/update-manager-apt-exception").read()1087 e = open("/var/run/ubuntu-release-upgrader-apt-exception").read()
1088 logging.error("found exception: '%s'" % e)1088 logging.error("found exception: '%s'" % e)
1089 # if its a ordering bug we can cleanly revert but we need to write1089 # if its a ordering bug we can cleanly revert but we need to write
1090 # a marker for the parent process to know its this kind of error1090 # a marker for the parent process to know its this kind of error
@@ -1111,7 +1111,7 @@
1111 if not self._partialUpgrade:1111 if not self._partialUpgrade:
1112 if not run_apport():1112 if not run_apport():
1113 msg += _("\n\nPlease report this bug in a browser at "1113 msg += _("\n\nPlease report this bug in a browser at "
1114 "http://bugs.launchpad.net/ubuntu/+source/update-manager/+filebug "1114 "http://bugs.launchpad.net/ubuntu/+source/ubuntu-release-upgrader/+filebug "
1115 "and attach the files in /var/log/dist-upgrade/ "1115 "and attach the files in /var/log/dist-upgrade/ "
1116 "to the bug report.\n"1116 "to the bug report.\n"
1117 "%s" % e)1117 "%s" % e)
@@ -1594,7 +1594,7 @@
1594 _("Preparing the system for the upgrade "1594 _("Preparing the system for the upgrade "
1595 "failed so a bug reporting process is "1595 "failed so a bug reporting process is "
1596 "being started."))1596 "being started."))
1597 subprocess.Popen(["apport-bug", "update-manager"])1597 subprocess.Popen(["apport-bug", "ubuntu-release-upgrader"])
1598 sys.exit(1)1598 sys.exit(1)
15991599
1600 # mvo: commented out for now, see #54234, this needs to be1600 # mvo: commented out for now, see #54234, this needs to be
@@ -1613,7 +1613,7 @@
1613 "\n"1613 "\n"
1614 "Additionally, a bug reporting process is "1614 "Additionally, a bug reporting process is "
1615 "being started."))1615 "being started."))
1616 subprocess.Popen(["apport-bug", "update-manager"])1616 subprocess.Popen(["apport-bug", "ubuntu-release-upgrader"])
1617 self.abort()1617 self.abort()
16181618
1619 # run a "apt-get update" now, its ok to ignore errors, 1619 # run a "apt-get update" now, its ok to ignore errors,
@@ -1684,7 +1684,7 @@
1684 "In the case of an overloaded mirror, you "1684 "In the case of an overloaded mirror, you "
1685 "may want to try the upgrade again later.")1685 "may want to try the upgrade again later.")
1686 % pkg)1686 % pkg)
1687 subprocess.Popen(["apport-bug", "update-manager"])1687 subprocess.Popen(["apport-bug", "ubuntu-release-upgrader"])
1688 self.abort()1688 self.abort()
16891689
1690 # calc the dist-upgrade and see if the removals are ok/expected1690 # calc the dist-upgrade and see if the removals are ok/expected
16911691
=== modified file 'DistUpgrade/DistUpgradeFetcherCore.py'
--- DistUpgrade/DistUpgradeFetcherCore.py 2012-05-28 10:20:51 +0000
+++ DistUpgrade/DistUpgradeFetcherCore.py 2012-06-27 19:25:24 +0000
@@ -33,7 +33,7 @@
33from gettext import gettext as _33from gettext import gettext as _
34from aptsources.sourceslist import SourcesList34from aptsources.sourceslist import SourcesList
3535
36from .utils import get_dist, url_downloadable, country_mirror36from UpdateManager.Core.utils import get_dist, url_downloadable, country_mirror
3737
38class DistUpgradeFetcherCore(object):38class DistUpgradeFetcherCore(object):
39 " base class (without GUI) for the upgrade fetcher "39 " base class (without GUI) for the upgrade fetcher "
@@ -150,7 +150,7 @@
150 if not os.path.exists(script):150 if not os.path.exists(script):
151 return self.error(_("Could not run the upgrade tool"),151 return self.error(_("Could not run the upgrade tool"),
152 _("Could not run the upgrade tool") + ". " + _("This is most likely a bug in the upgrade tool. "152 _("Could not run the upgrade tool") + ". " + _("This is most likely a bug in the upgrade tool. "
153 "Please report it as a bug using the command 'ubuntu-bug update-manager'."))153 "Please report it as a bug using the command 'ubuntu-bug ubuntu-release-upgrader-core'."))
154 return True154 return True
155155
156 def mirror_from_sources_list(self, uri, default_uri):156 def mirror_from_sources_list(self, uri, default_uri):
@@ -211,7 +211,7 @@
211211
212 def fetchDistUpgrader(self):212 def fetchDistUpgrader(self):
213 " download the tarball with the upgrade script "213 " download the tarball with the upgrade script "
214 self.tmpdir = tmpdir = tempfile.mkdtemp(prefix="update-manager-")214 self.tmpdir = tmpdir = tempfile.mkdtemp(prefix="ubuntu-release-upgrader-")
215 os.chdir(tmpdir)215 os.chdir(tmpdir)
216 logging.debug("using tmpdir: '%s'" % tmpdir)216 logging.debug("using tmpdir: '%s'" % tmpdir)
217 # turn debugging on here (if required)217 # turn debugging on here (if required)
218218
=== modified file 'DistUpgrade/DistUpgradeQuirks.py'
--- DistUpgrade/DistUpgradeQuirks.py 2012-06-12 01:00:52 +0000
+++ DistUpgrade/DistUpgradeQuirks.py 2012-06-27 19:25:24 +0000
@@ -34,7 +34,7 @@
34from subprocess import PIPE, Popen34from subprocess import PIPE, Popen
35from hashlib import md535from hashlib import md5
3636
37from .utils import lsmod, get_arch37from UpdateManager.Core.utils import lsmod, get_arch
3838
39from .DistUpgradeGettext import gettext as _39from .DistUpgradeGettext import gettext as _
40from janitor.plugincore.manager import PluginManager40from janitor.plugincore.manager import PluginManager
4141
=== modified file 'DistUpgrade/DistUpgradeView.py'
--- DistUpgrade/DistUpgradeView.py 2012-06-13 11:57:10 +0000
+++ DistUpgrade/DistUpgradeView.py 2012-06-27 19:25:24 +0000
@@ -206,7 +206,7 @@
206 except Exception as e:206 except Exception as e:
207 print("Exception during pm.DoInstall(): ", e)207 print("Exception during pm.DoInstall(): ", e)
208 logging.exception("Exception during pm.DoInstall()")208 logging.exception("Exception during pm.DoInstall()")
209 open("/var/run/update-manager-apt-exception","w").write(str(e))209 open("/var/run/ubuntu-release-upgrader-apt-exception","w").write(str(e))
210 os._exit(pm.ResultFailed)210 os._exit(pm.ResultFailed)
211 os._exit(res)211 os._exit(res)
212 self.child_pid = pid212 self.child_pid = pid
213213
=== modified file 'DistUpgrade/DistUpgradeViewGtk.py'
--- DistUpgrade/DistUpgradeViewGtk.py 2012-06-13 11:40:17 +0000
+++ DistUpgrade/DistUpgradeViewGtk.py 2012-06-27 19:25:24 +0000
@@ -387,8 +387,8 @@
387 gtk.init_check()387 gtk.init_check()
388388
389 try:389 try:
390 locale.bindtextdomain("update-manager",localedir)390 locale.bindtextdomain("ubuntu-release-upgrader",localedir)
391 gettext.textdomain("update-manager")391 gettext.textdomain("ubuntu-release-upgrader")
392 except Exception as e:392 except Exception as e:
393 logging.warning("Error setting locales (%s)" % e)393 logging.warning("Error setting locales (%s)" % e)
394 394
@@ -400,7 +400,7 @@
400 pass400 pass
401 SimpleGtkbuilderApp.__init__(self, 401 SimpleGtkbuilderApp.__init__(self,
402 gladedir+"/DistUpgrade.ui", 402 gladedir+"/DistUpgrade.ui",
403 "update-manager")403 "ubuntu-release-upgrader")
404 # terminal stuff404 # terminal stuff
405 self.create_terminal()405 self.create_terminal()
406406
407407
=== modified file 'DistUpgrade/DistUpgradeViewGtk3.py'
--- DistUpgrade/DistUpgradeViewGtk3.py 2012-06-13 11:40:17 +0000
+++ DistUpgrade/DistUpgradeViewGtk3.py 2012-06-27 19:25:24 +0000
@@ -407,14 +407,14 @@
407 Gtk.init_check(sys.argv)407 Gtk.init_check(sys.argv)
408408
409 try:409 try:
410 locale.bindtextdomain("update-manager",localedir)410 locale.bindtextdomain("ubuntu-release-upgrader",localedir)
411 gettext.textdomain("update-manager")411 gettext.textdomain("ubuntu-release-upgrader")
412 except Exception as e:412 except Exception as e:
413 logging.warning("Error setting locales (%s)" % e)413 logging.warning("Error setting locales (%s)" % e)
414414
415 SimpleGtkbuilderApp.__init__(self,415 SimpleGtkbuilderApp.__init__(self,
416 gladedir+"/DistUpgrade.ui",416 gladedir+"/DistUpgrade.ui",
417 "update-manager")417 "ubuntu-release-upgrader")
418418
419 icons = Gtk.IconTheme.get_default()419 icons = Gtk.IconTheme.get_default()
420 try:420 try:
421421
=== modified file 'DistUpgrade/DistUpgradeViewKDE.py'
--- DistUpgrade/DistUpgradeViewKDE.py 2012-06-13 11:41:10 +0000
+++ DistUpgrade/DistUpgradeViewKDE.py 2012-06-27 19:25:24 +0000
@@ -455,12 +455,12 @@
455 if not datadir:455 if not datadir:
456 localedir=os.path.join(os.getcwd(),"mo")456 localedir=os.path.join(os.getcwd(),"mo")
457 else:457 else:
458 localedir="/usr/share/locale/update-manager"458 localedir="/usr/share/locale/ubuntu-release-upgrader"
459459
460 # FIXME: i18n must be somewhere relative do this dir460 # FIXME: i18n must be somewhere relative do this dir
461 try:461 try:
462 gettext.bindtextdomain("update-manager", localedir)462 gettext.bindtextdomain("ubuntu-release-upgrader", localedir)
463 gettext.textdomain("update-manager")463 gettext.textdomain("ubuntu-release-upgrader")
464 except Exception as e:464 except Exception as e:
465 logging.warning("Error setting locales (%s)" % e)465 logging.warning("Error setting locales (%s)" % e)
466466
@@ -474,7 +474,7 @@
474 # exception when run without DISPLAY but dies instead474 # exception when run without DISPLAY but dies instead
475 if not "DISPLAY" in os.environ:475 if not "DISPLAY" in os.environ:
476 raise Exception("No DISPLAY in os.environ found")476 raise Exception("No DISPLAY in os.environ found")
477 self.app = QApplication(["update-manager"])477 self.app = QApplication(["ubuntu-release-upgrader"])
478478
479 if os.path.exists("/usr/share/icons/oxygen/48x48/apps/system-software-update.png"):479 if os.path.exists("/usr/share/icons/oxygen/48x48/apps/system-software-update.png"):
480 messageIcon = QPixmap("/usr/share/icons/oxygen/48x48/apps/system-software-update.png")480 messageIcon = QPixmap("/usr/share/icons/oxygen/48x48/apps/system-software-update.png")
@@ -524,8 +524,8 @@
524 subprocess.call(["killall", "adept_updater"])524 subprocess.call(["killall", "adept_updater"])
525525
526 # init gettext526 # init gettext
527 gettext.bindtextdomain("update-manager",localedir)527 gettext.bindtextdomain("ubuntu-release-upgrader",localedir)
528 gettext.textdomain("update-manager")528 gettext.textdomain("ubuntu-release-upgrader")
529 self.translate_widget_children()529 self.translate_widget_children()
530 self.window_main.label_title.setText(self.window_main.label_title.text().replace("Ubuntu", "Kubuntu"))530 self.window_main.label_title.setText(self.window_main.label_title.text().replace("Ubuntu", "Kubuntu"))
531531
@@ -610,7 +610,7 @@
610 """start konqueror"""610 """start konqueror"""
611 #need to run this else kdesu can't run Konqueror611 #need to run this else kdesu can't run Konqueror
612 #subprocess.call(['su', 'ubuntu', 'xhost', '+localhost'])612 #subprocess.call(['su', 'ubuntu', 'xhost', '+localhost'])
613 QDesktopServices.openUrl(QUrl("https://launchpad.net/ubuntu/+source/update-manager/+filebug"))613 QDesktopServices.openUrl(QUrl("https://launchpad.net/ubuntu/+source/ubuntu-release-upgrader/+filebug"))
614614
615 def showTerminal(self):615 def showTerminal(self):
616 if self.window_main.konsole_frame.isVisible():616 if self.window_main.konsole_frame.isVisible():
617617
=== modified file 'DistUpgrade/DistUpgradeViewText.py'
--- DistUpgrade/DistUpgradeViewText.py 2012-06-13 11:19:42 +0000
+++ DistUpgrade/DistUpgradeViewText.py 2012-06-27 19:25:24 +0000
@@ -33,7 +33,7 @@
3333
34import gettext34import gettext
35from .DistUpgradeGettext import gettext as _35from .DistUpgradeGettext import gettext as _
36from .utils import twrap36from UpdateManager.Core.utils import twrap
3737
38class TextAcquireProgress(AcquireProgress, apt.progress.text.AcquireProgress):38class TextAcquireProgress(AcquireProgress, apt.progress.text.AcquireProgress):
39 def __init__(self):39 def __init__(self):
@@ -68,11 +68,11 @@
68 if not datadir:68 if not datadir:
69 localedir=os.path.join(os.getcwd(),"mo")69 localedir=os.path.join(os.getcwd(),"mo")
70 else:70 else:
71 localedir="/usr/share/locale/update-manager"71 localedir="/usr/share/locale/ubuntu-release-upgrader"
7272
73 try:73 try:
74 gettext.bindtextdomain("update-manager", localedir)74 gettext.bindtextdomain("ubuntu-release-upgrader", localedir)
75 gettext.textdomain("update-manager")75 gettext.textdomain("ubuntu-release-upgrader")
76 except Exception as e:76 except Exception as e:
77 logging.warning("Error setting locales (%s)" % e)77 logging.warning("Error setting locales (%s)" % e)
78 78
7979
=== removed symlink 'DistUpgrade/MetaRelease.py'
=== target was u'../UpdateManager/Core/MetaRelease.py'
=== added file 'DistUpgrade/SimpleGtk3builderApp.py'
--- DistUpgrade/SimpleGtk3builderApp.py 1970-01-01 00:00:00 +0000
+++ DistUpgrade/SimpleGtk3builderApp.py 2012-06-27 19:25:24 +0000
@@ -0,0 +1,61 @@
1"""
2 SimpleGladeApp.py
3 Module that provides an object oriented abstraction to pygtk and libglade.
4 Copyright (C) 2004 Sandino Flores Moreno
5"""
6
7# This library is free software; you can redistribute it and/or
8# modify it under the terms of the GNU Lesser General Public
9# License as published by the Free Software Foundation; either
10# version 2.1 of the License, or (at your option) any later version.
11#
12# This library is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15# Lesser General Public License for more details.
16#
17# You should have received a copy of the GNU Lesser General Public
18# License along with this library; if not, write to the Free Software
19# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20# USA
21
22import logging
23
24from gi.repository import Gtk
25
26# based on SimpleGladeApp
27class SimpleGtkbuilderApp:
28
29 def __init__(self, path, domain):
30 self.builder = Gtk.Builder()
31 self.builder.set_translation_domain(domain)
32 self.builder.add_from_file(path)
33 self.builder.connect_signals(self)
34 for o in self.builder.get_objects():
35 if issubclass(type(o), Gtk.Buildable):
36 name = Gtk.Buildable.get_name(o)
37 setattr(self, name, o)
38 else:
39 logging.debug("WARNING: can not get name for '%s'" % o)
40
41 def run(self):
42 """
43 Starts the main loop of processing events checking for Control-C.
44
45 The default implementation checks wheter a Control-C is pressed,
46 then calls on_keyboard_interrupt().
47
48 Use this method for starting programs.
49 """
50 try:
51 Gtk.main()
52 except KeyboardInterrupt:
53 self.on_keyboard_interrupt()
54
55 def on_keyboard_interrupt(self):
56 """
57 This method is called by the default implementation of run()
58 after a program is finished by pressing Control-C.
59 """
60 pass
61
062
=== removed symlink 'DistUpgrade/SimpleGtk3builderApp.py'
=== target was u'../UpdateManager/SimpleGtk3builderApp.py'
=== added file 'DistUpgrade/SimpleGtkbuilderApp.py'
--- DistUpgrade/SimpleGtkbuilderApp.py 1970-01-01 00:00:00 +0000
+++ DistUpgrade/SimpleGtkbuilderApp.py 2012-06-27 19:25:24 +0000
@@ -0,0 +1,61 @@
1"""
2 SimpleGladeApp.py
3 Module that provides an object oriented abstraction to pygtk and libglade.
4 Copyright (C) 2004 Sandino Flores Moreno
5"""
6
7# This library is free software; you can redistribute it and/or
8# modify it under the terms of the GNU Lesser General Public
9# License as published by the Free Software Foundation; either
10# version 2.1 of the License, or (at your option) any later version.
11#
12# This library is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15# Lesser General Public License for more details.
16#
17# You should have received a copy of the GNU Lesser General Public
18# License along with this library; if not, write to the Free Software
19# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20# USA
21
22import logging
23
24import gtk
25
26# based on SimpleGladeApp
27class SimpleGtkbuilderApp:
28
29 def __init__(self, path, domain):
30 self.builder = gtk.Builder()
31 self.builder.set_translation_domain(domain)
32 self.builder.add_from_file(path)
33 self.builder.connect_signals(self)
34 for o in self.builder.get_objects():
35 if issubclass(type(o), gtk.Buildable):
36 name = gtk.Buildable.get_name(o)
37 setattr(self, name, o)
38 else:
39 logging.debug("WARNING: can not get name for '%s'" % o)
40
41 def run(self):
42 """
43 Starts the main loop of processing events checking for Control-C.
44
45 The default implementation checks wheter a Control-C is pressed,
46 then calls on_keyboard_interrupt().
47
48 Use this method for starting programs.
49 """
50 try:
51 gtk.main()
52 except KeyboardInterrupt:
53 self.on_keyboard_interrupt()
54
55 def on_keyboard_interrupt(self):
56 """
57 This method is called by the default implementation of run()
58 after a program is finished by pressing Control-C.
59 """
60 pass
61
062
=== removed symlink 'DistUpgrade/SimpleGtkbuilderApp.py'
=== target was u'../UpdateManager/SimpleGtkbuilderApp.py'
=== modified file 'DistUpgrade/TODO'
--- DistUpgrade/TODO 2006-10-05 14:36:09 +0000
+++ DistUpgrade/TODO 2012-06-27 19:25:24 +0000
@@ -8,8 +8,8 @@
8 * if run from CDROM and we have network -> do a self update8 * if run from CDROM and we have network -> do a self update
9 * support dapper-commercial in sources.list rewriting9 * support dapper-commercial in sources.list rewriting
10 * after "no-network" dist-upgrade it is most likely that the system10 * after "no-network" dist-upgrade it is most likely that the system
11 is only half-upgraded and update-manager will not be able to do11 is only half-upgraded and ubuntu-release-upgrader will not be able to do
12 the full upgrade. update-manager needs to be changed to support12 the full upgrade. ubuntu-release-upgrader needs to be changed to support
13 full dist-upgrades (possible by just calling the dist-upgrader13 full dist-upgrades (possible by just calling the dist-upgrader
14 in a special mode)14 in a special mode)
1515
1616
=== modified file 'DistUpgrade/build-tarball.sh'
--- DistUpgrade/build-tarball.sh 2012-06-11 15:08:35 +0000
+++ DistUpgrade/build-tarball.sh 2012-06-27 19:25:24 +0000
@@ -7,7 +7,7 @@
7# cleanup7# cleanup
8echo "Cleaning up"8echo "Cleaning up"
99
10for d in ./ janitor/; do10for d in ./; do
11 rm -f $d/*~ $d/*.bak $d/*.pyc $d/*.moved $d/'#'* $d/*.rej $d/*.orig11 rm -f $d/*~ $d/*.bak $d/*.pyc $d/*.moved $d/'#'* $d/*.rej $d/*.orig
12 rm -rf $d/__pycache__12 rm -rf $d/__pycache__
13 rm -f *.tar.gz *.tar13 rm -f *.tar.gz *.tar
@@ -38,4 +38,4 @@
38tar --append -v -f $DIST.tar ./DistUpgrade38tar --append -v -f $DIST.tar ./DistUpgrade
3939
40# and compress it40# and compress it
41gzip -9 $DIST.tar
42\ No newline at end of file41\ No newline at end of file
42gzip -9 $DIST.tar
4343
=== modified file 'DistUpgrade/crashdialog.ui'
--- DistUpgrade/crashdialog.ui 2008-07-28 17:48:53 +0000
+++ DistUpgrade/crashdialog.ui 2012-06-27 19:25:24 +0000
@@ -59,7 +59,7 @@
59 <item>59 <item>
60 <widget class="QLabel" name="crash_info_text" >60 <widget class="QLabel" name="crash_info_text" >
61 <property name="text" >61 <property name="text" >
62 <string>&lt;qt>We're sorry; the upgrade tool crashed. Please file a new bug report at &lt;a href="http://launchpad.net/ubuntu/+source/update-manager">http://launchpad.net/ubuntu/+source/update-manager&lt;/a> (do not attach your details to any existing bug) and a developer will attend to the problem as soon as possible. To help the developers understand what went wrong, include the following detail in your bug report, and attach the files /var/log/dist-upgrade/apt.log and /var/log/dist-upgrade/main.log:</string>62 <string>&lt;qt>We're sorry; the upgrade tool crashed. Please file a new bug report at &lt;a href="http://launchpad.net/ubuntu/+source/ubuntu-release-upgrader">http://launchpad.net/ubuntu/+source/ubuntu-release-upgrader&lt;/a> (do not attach your details to any existing bug) and a developer will attend to the problem as soon as possible. To help the developers understand what went wrong, include the following detail in your bug report, and attach the files /var/log/dist-upgrade/apt.log and /var/log/dist-upgrade/main.log:</string>
63 </property>63 </property>
64 <property name="alignment" >64 <property name="alignment" >
65 <set>Qt::AlignVCenter</set>65 <set>Qt::AlignVCenter</set>
6666
=== removed symlink 'DistUpgrade/janitor'
=== target was u'../janitor'
=== modified file 'DistUpgrade/removal_blacklist.cfg'
--- DistUpgrade/removal_blacklist.cfg 2012-04-17 19:26:33 +0000
+++ DistUpgrade/removal_blacklist.cfg 2012-06-27 19:25:24 +0000
@@ -5,9 +5,10 @@
5kubuntu-desktop5kubuntu-desktop
6xubuntu-desktop6xubuntu-desktop
7lubuntu-desktop7lubuntu-desktop
8# update-manager itself should not remove itself8# ubuntu-release-upgrader should not remove itself or update-manager
9update-manager9update-manager
10update-manager-core10update-manager-core
11ubuntu-release-upgrader
11# posgresql (LP: #871893)12# posgresql (LP: #871893)
12^postgresql-.*[0-9]\.[0-9].*13^postgresql-.*[0-9]\.[0-9].*
13# the upgrade runs in it14# the upgrade runs in it
1415
=== removed symlink 'DistUpgrade/utils.py'
=== target was u'../UpdateManager/Core/utils.py'
=== modified file 'DistUpgrade/xorg_fix_proprietary.py'
--- DistUpgrade/xorg_fix_proprietary.py 2012-05-28 10:20:51 +0000
+++ DistUpgrade/xorg_fix_proprietary.py 2012-06-27 19:25:24 +0000
@@ -31,7 +31,7 @@
31 if (line.lower().startswith("section") and 31 if (line.lower().startswith("section") and
32 line.lower().split("#")[0].strip().endswith('"inputdevice"')):32 line.lower().split("#")[0].strip().endswith('"inputdevice"')):
33 logging.debug("found 'InputDevice' section")33 logging.debug("found 'InputDevice' section")
34 content.append("# commented out by update-manager, HAL is now used and auto-detects devices\n")34 content.append("# commented out by ubuntu-release-upgrader, HAL is now used and auto-detects devices\n")
35 content.append("# Keyboard settings are now read from /etc/default/console-setup\n")35 content.append("# Keyboard settings are now read from /etc/default/console-setup\n")
36 content.append("#"+raw)36 content.append("#"+raw)
37 in_input_devices=True37 in_input_devices=True
@@ -40,7 +40,7 @@
40 in_input_devices=False40 in_input_devices=False
41 elif line.lower().startswith("inputdevice"):41 elif line.lower().startswith("inputdevice"):
42 logging.debug("commenting out '%s' " % line)42 logging.debug("commenting out '%s' " % line)
43 content.append("# commented out by update-manager, HAL is now used and auto-detects devices\n")43 content.append("# commented out by ubuntu-release-upgrader, HAL is now used and auto-detects devices\n")
44 content.append("# Keyboard settings are now read from /etc/default/console-setup\n")44 content.append("# Keyboard settings are now read from /etc/default/console-setup\n")
45 content.append("#"+raw)45 content.append("#"+raw)
46 elif in_input_devices:46 elif in_input_devices:
@@ -123,8 +123,8 @@
123 print("Need to run as root")123 print("Need to run as root")
124 sys.exit(1)124 sys.exit(1)
125125
126 # we pretend to be update-manger so that apport picks up when we crash126 # we pretend to be do-release-upgrade so that apport picks up when we crash
127 sys.argv[0] = "/usr/bin/update-manager"127 sys.argv[0] = "/usr/bin/do-release-upgrade"
128128
129 # setup logging129 # setup logging
130 logging.basicConfig(level=logging.DEBUG,130 logging.basicConfig(level=logging.DEBUG,
131131
=== removed file 'LGPL'
--- LGPL 2007-02-07 15:47:06 +0000
+++ LGPL 1970-01-01 00:00:00 +0000
@@ -1,510 +0,0 @@
1
2 GNU LESSER GENERAL PUBLIC LICENSE
3 Version 2.1, February 1999
4
5 Copyright (C) 1991, 1999 Free Software Foundation, Inc.
6 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
7 Everyone is permitted to copy and distribute verbatim copies
8 of this license document, but changing it is not allowed.
9
10[This is the first released version of the Lesser GPL. It also counts
11 as the successor of the GNU Library Public License, version 2, hence
12 the version number 2.1.]
13
14 Preamble
15
16 The licenses for most software are designed to take away your
17freedom to share and change it. By contrast, the GNU General Public
18Licenses are intended to guarantee your freedom to share and change
19free software--to make sure the software is free for all its users.
20
21 This license, the Lesser General Public License, applies to some
22specially designated software packages--typically libraries--of the
23Free Software Foundation and other authors who decide to use it. You
24can use it too, but we suggest you first think carefully about whether
25this license or the ordinary General Public License is the better
26strategy to use in any particular case, based on the explanations
27below.
28
29 When we speak of free software, we are referring to freedom of use,
30not price. Our General Public Licenses are designed to make sure that
31you have the freedom to distribute copies of free software (and charge
32for this service if you wish); that you receive source code or can get
33it if you want it; that you can change the software and use pieces of
34it in new free programs; and that you are informed that you can do
35these things.
36
37 To protect your rights, we need to make restrictions that forbid
38distributors to deny you these rights or to ask you to surrender these
39rights. These restrictions translate to certain responsibilities for
40you if you distribute copies of the library or if you modify it.
41
42 For example, if you distribute copies of the library, whether gratis
43or for a fee, you must give the recipients all the rights that we gave
44you. You must make sure that they, too, receive or can get the source
45code. If you link other code with the library, you must provide
46complete object files to the recipients, so that they can relink them
47with the library after making changes to the library and recompiling
48it. And you must show them these terms so they know their rights.
49
50 We protect your rights with a two-step method: (1) we copyright the
51library, and (2) we offer you this license, which gives you legal
52permission to copy, distribute and/or modify the library.
53
54 To protect each distributor, we want to make it very clear that
55there is no warranty for the free library. Also, if the library is
56modified by someone else and passed on, the recipients should know
57that what they have is not the original version, so that the original
58author's reputation will not be affected by problems that might be
59introduced by others.
60
610
62 Finally, software patents pose a constant threat to the existence of
63any free program. We wish to make sure that a company cannot
64effectively restrict the users of a free program by obtaining a
65restrictive license from a patent holder. Therefore, we insist that
66any patent license obtained for a version of the library must be
67consistent with the full freedom of use specified in this license.
68
69 Most GNU software, including some libraries, is covered by the
70ordinary GNU General Public License. This license, the GNU Lesser
71General Public License, applies to certain designated libraries, and
72is quite different from the ordinary General Public License. We use
73this license for certain libraries in order to permit linking those
74libraries into non-free programs.
75
76 When a program is linked with a library, whether statically or using
77a shared library, the combination of the two is legally speaking a
78combined work, a derivative of the original library. The ordinary
79General Public License therefore permits such linking only if the
80entire combination fits its criteria of freedom. The Lesser General
81Public License permits more lax criteria for linking other code with
82the library.
83
84 We call this license the "Lesser" General Public License because it
85does Less to protect the user's freedom than the ordinary General
86Public License. It also provides other free software developers Less
87of an advantage over competing non-free programs. These disadvantages
88are the reason we use the ordinary General Public License for many
89libraries. However, the Lesser license provides advantages in certain
90special circumstances.
91
92 For example, on rare occasions, there may be a special need to
93encourage the widest possible use of a certain library, so that it
94becomes a de-facto standard. To achieve this, non-free programs must
95be allowed to use the library. A more frequent case is that a free
96library does the same job as widely used non-free libraries. In this
97case, there is little to gain by limiting the free library to free
98software only, so we use the Lesser General Public License.
99
100 In other cases, permission to use a particular library in non-free
101programs enables a greater number of people to use a large body of
102free software. For example, permission to use the GNU C Library in
103non-free programs enables many more people to use the whole GNU
104operating system, as well as its variant, the GNU/Linux operating
105system.
106
107 Although the Lesser General Public License is Less protective of the
108users' freedom, it does ensure that the user of a program that is
109linked with the Library has the freedom and the wherewithal to run
110that program using a modified version of the Library.
111
112 The precise terms and conditions for copying, distribution and
113modification follow. Pay close attention to the difference between a
114"work based on the library" and a "work that uses the library". The
115former contains code derived from the library, whereas the latter must
116be combined with the library in order to run.
117
1181
119 GNU LESSER GENERAL PUBLIC LICENSE
120 TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
121
122 0. This License Agreement applies to any software library or other
123program which contains a notice placed by the copyright holder or
124other authorized party saying it may be distributed under the terms of
125this Lesser General Public License (also called "this License").
126Each licensee is addressed as "you".
127
128 A "library" means a collection of software functions and/or data
129prepared so as to be conveniently linked with application programs
130(which use some of those functions and data) to form executables.
131
132 The "Library", below, refers to any such software library or work
133which has been distributed under these terms. A "work based on the
134Library" means either the Library or any derivative work under
135copyright law: that is to say, a work containing the Library or a
136portion of it, either verbatim or with modifications and/or translated
137straightforwardly into another language. (Hereinafter, translation is
138included without limitation in the term "modification".)
139
140 "Source code" for a work means the preferred form of the work for
141making modifications to it. For a library, complete source code means
142all the source code for all modules it contains, plus any associated
143interface definition files, plus the scripts used to control
144compilation and installation of the library.
145
146 Activities other than copying, distribution and modification are not
147covered by this License; they are outside its scope. The act of
148running a program using the Library is not restricted, and output from
149such a program is covered only if its contents constitute a work based
150on the Library (independent of the use of the Library in a tool for
151writing it). Whether that is true depends on what the Library does
152and what the program that uses the Library does.
153
154 1. You may copy and distribute verbatim copies of the Library's
155complete source code as you receive it, in any medium, provided that
156you conspicuously and appropriately publish on each copy an
157appropriate copyright notice and disclaimer of warranty; keep intact
158all the notices that refer to this License and to the absence of any
159warranty; and distribute a copy of this License along with the
160Library.
161
162 You may charge a fee for the physical act of transferring a copy,
163and you may at your option offer warranty protection in exchange for a
164fee.
165
1662
167 2. You may modify your copy or copies of the Library or any portion
168of it, thus forming a work based on the Library, and copy and
169distribute such modifications or work under the terms of Section 1
170above, provided that you also meet all of these conditions:
171
172 a) The modified work must itself be a software library.
173
174 b) You must cause the files modified to carry prominent notices
175 stating that you changed the files and the date of any change.
176
177 c) You must cause the whole of the work to be licensed at no
178 charge to all third parties under the terms of this License.
179
180 d) If a facility in the modified Library refers to a function or a
181 table of data to be supplied by an application program that uses
182 the facility, other than as an argument passed when the facility
183 is invoked, then you must make a good faith effort to ensure that,
184 in the event an application does not supply such function or
185 table, the facility still operates, and performs whatever part of
186 its purpose remains meaningful.
187
188 (For example, a function in a library to compute square roots has
189 a purpose that is entirely well-defined independent of the
190 application. Therefore, Subsection 2d requires that any
191 application-supplied function or table used by this function must
192 be optional: if the application does not supply it, the square
193 root function must still compute square roots.)
194
195These requirements apply to the modified work as a whole. If
196identifiable sections of that work are not derived from the Library,
197and can be reasonably considered independent and separate works in
198themselves, then this License, and its terms, do not apply to those
199sections when you distribute them as separate works. But when you
200distribute the same sections as part of a whole which is a work based
201on the Library, the distribution of the whole must be on the terms of
202this License, whose permissions for other licensees extend to the
203entire whole, and thus to each and every part regardless of who wrote
204it.
205
206Thus, it is not the intent of this section to claim rights or contest
207your rights to work written entirely by you; rather, the intent is to
208exercise the right to control the distribution of derivative or
209collective works based on the Library.
210
211In addition, mere aggregation of another work not based on the Library
212with the Library (or with a work based on the Library) on a volume of
213a storage or distribution medium does not bring the other work under
214the scope of this License.
215
216 3. You may opt to apply the terms of the ordinary GNU General Public
217License instead of this License to a given copy of the Library. To do
218this, you must alter all the notices that refer to this License, so
219that they refer to the ordinary GNU General Public License, version 2,
220instead of to this License. (If a newer version than version 2 of the
221ordinary GNU General Public License has appeared, then you can specify
222that version instead if you wish.) Do not make any other change in
223these notices.
224
2253
226 Once this change is made in a given copy, it is irreversible for
227that copy, so the ordinary GNU General Public License applies to all
228subsequent copies and derivative works made from that copy.
229
230 This option is useful when you wish to copy part of the code of
231the Library into a program that is not a library.
232
233 4. You may copy and distribute the Library (or a portion or
234derivative of it, under Section 2) in object code or executable form
235under the terms of Sections 1 and 2 above provided that you accompany
236it with the complete corresponding machine-readable source code, which
237must be distributed under the terms of Sections 1 and 2 above on a
238medium customarily used for software interchange.
239
240 If distribution of object code is made by offering access to copy
241from a designated place, then offering equivalent access to copy the
242source code from the same place satisfies the requirement to
243distribute the source code, even though third parties are not
244compelled to copy the source along with the object code.
245
246 5. A program that contains no derivative of any portion of the
247Library, but is designed to work with the Library by being compiled or
248linked with it, is called a "work that uses the Library". Such a
249work, in isolation, is not a derivative work of the Library, and
250therefore falls outside the scope of this License.
251
252 However, linking a "work that uses the Library" with the Library
253creates an executable that is a derivative of the Library (because it
254contains portions of the Library), rather than a "work that uses the
255library". The executable is therefore covered by this License.
256Section 6 states terms for distribution of such executables.
257
258 When a "work that uses the Library" uses material from a header file
259that is part of the Library, the object code for the work may be a
260derivative work of the Library even though the source code is not.
261Whether this is true is especially significant if the work can be
262linked without the Library, or if the work is itself a library. The
263threshold for this to be true is not precisely defined by law.
264
265 If such an object file uses only numerical parameters, data
266structure layouts and accessors, and small macros and small inline
267functions (ten lines or less in length), then the use of the object
268file is unrestricted, regardless of whether it is legally a derivative
269work. (Executables containing this object code plus portions of the
270Library will still fall under Section 6.)
271
272 Otherwise, if the work is a derivative of the Library, you may
273distribute the object code for the work under the terms of Section 6.
274Any executables containing that work also fall under Section 6,
275whether or not they are linked directly with the Library itself.
276
2774
278 6. As an exception to the Sections above, you may also combine or
279link a "work that uses the Library" with the Library to produce a
280work containing portions of the Library, and distribute that work
281under terms of your choice, provided that the terms permit
282modification of the work for the customer's own use and reverse
283engineering for debugging such modifications.
284
285 You must give prominent notice with each copy of the work that the
286Library is used in it and that the Library and its use are covered by
287this License. You must supply a copy of this License. If the work
288during execution displays copyright notices, you must include the
289copyright notice for the Library among them, as well as a reference
290directing the user to the copy of this License. Also, you must do one
291of these things:
292
293 a) Accompany the work with the complete corresponding
294 machine-readable source code for the Library including whatever
295 changes were used in the work (which must be distributed under
296 Sections 1 and 2 above); and, if the work is an executable linked
297 with the Library, with the complete machine-readable "work that
298 uses the Library", as object code and/or source code, so that the
299 user can modify the Library and then relink to produce a modified
300 executable containing the modified Library. (It is understood
301 that the user who changes the contents of definitions files in the
302 Library will not necessarily be able to recompile the application
303 to use the modified definitions.)
304
305 b) Use a suitable shared library mechanism for linking with the
306 Library. A suitable mechanism is one that (1) uses at run time a
307 copy of the library already present on the user's computer system,
308 rather than copying library functions into the executable, and (2)
309 will operate properly with a modified version of the library, if
310 the user installs one, as long as the modified version is
311 interface-compatible with the version that the work was made with.
312
313 c) Accompany the work with a written offer, valid for at least
314 three years, to give the same user the materials specified in
315 Subsection 6a, above, for a charge no more than the cost of
316 performing this distribution.
317
318 d) If distribution of the work is made by offering access to copy
319 from a designated place, offer equivalent access to copy the above
320 specified materials from the same place.
321
322 e) Verify that the user has already received a copy of these
323 materials or that you have already sent this user a copy.
324
325 For an executable, the required form of the "work that uses the
326Library" must include any data and utility programs needed for
327reproducing the executable from it. However, as a special exception,
328the materials to be distributed need not include anything that is
329normally distributed (in either source or binary form) with the major
330components (compiler, kernel, and so on) of the operating system on
331which the executable runs, unless that component itself accompanies
332the executable.
333
334 It may happen that this requirement contradicts the license
335restrictions of other proprietary libraries that do not normally
336accompany the operating system. Such a contradiction means you cannot
337use both them and the Library together in an executable that you
338distribute.
339
3405
341 7. You may place library facilities that are a work based on the
342Library side-by-side in a single library together with other library
343facilities not covered by this License, and distribute such a combined
344library, provided that the separate distribution of the work based on
345the Library and of the other library facilities is otherwise
346permitted, and provided that you do these two things:
347
348 a) Accompany the combined library with a copy of the same work
349 based on the Library, uncombined with any other library
350 facilities. This must be distributed under the terms of the
351 Sections above.
352
353 b) Give prominent notice with the combined library of the fact
354 that part of it is a work based on the Library, and explaining
355 where to find the accompanying uncombined form of the same work.
356
357 8. You may not copy, modify, sublicense, link with, or distribute
358the Library except as expressly provided under this License. Any
359attempt otherwise to copy, modify, sublicense, link with, or
360distribute the Library is void, and will automatically terminate your
361rights under this License. However, parties who have received copies,
362or rights, from you under this License will not have their licenses
363terminated so long as such parties remain in full compliance.
364
365 9. You are not required to accept this License, since you have not
366signed it. However, nothing else grants you permission to modify or
367distribute the Library or its derivative works. These actions are
368prohibited by law if you do not accept this License. Therefore, by
369modifying or distributing the Library (or any work based on the
370Library), you indicate your acceptance of this License to do so, and
371all its terms and conditions for copying, distributing or modifying
372the Library or works based on it.
373
374 10. Each time you redistribute the Library (or any work based on the
375Library), the recipient automatically receives a license from the
376original licensor to copy, distribute, link with or modify the Library
377subject to these terms and conditions. You may not impose any further
378restrictions on the recipients' exercise of the rights granted herein.
379You are not responsible for enforcing compliance by third parties with
380this License.
381
3826
383 11. If, as a consequence of a court judgment or allegation of patent
384infringement or for any other reason (not limited to patent issues),
385conditions are imposed on you (whether by court order, agreement or
386otherwise) that contradict the conditions of this License, they do not
387excuse you from the conditions of this License. If you cannot
388distribute so as to satisfy simultaneously your obligations under this
389License and any other pertinent obligations, then as a consequence you
390may not distribute the Library at all. For example, if a patent
391license would not permit royalty-free redistribution of the Library by
392all those who receive copies directly or indirectly through you, then
393the only way you could satisfy both it and this License would be to
394refrain entirely from distribution of the Library.
395
396If any portion of this section is held invalid or unenforceable under
397any particular circumstance, the balance of the section is intended to
398apply, and the section as a whole is intended to apply in other
399circumstances.
400
401It is not the purpose of this section to induce you to infringe any
402patents or other property right claims or to contest validity of any
403such claims; this section has the sole purpose of protecting the
404integrity of the free software distribution system which is
405implemented by public license practices. Many people have made
406generous contributions to the wide range of software distributed
407through that system in reliance on consistent application of that
408system; it is up to the author/donor to decide if he or she is willing
409to distribute software through any other system and a licensee cannot
410impose that choice.
411
412This section is intended to make thoroughly clear what is believed to
413be a consequence of the rest of this License.
414
415 12. If the distribution and/or use of the Library is restricted in
416certain countries either by patents or by copyrighted interfaces, the
417original copyright holder who places the Library under this License
418may add an explicit geographical distribution limitation excluding those
419countries, so that distribution is permitted only in or among
420countries not thus excluded. In such case, this License incorporates
421the limitation as if written in the body of this License.
422
423 13. The Free Software Foundation may publish revised and/or new
424versions of the Lesser General Public License from time to time.
425Such new versions will be similar in spirit to the present version,
426but may differ in detail to address new problems or concerns.
427
428Each version is given a distinguishing version number. If the Library
429specifies a version number of this License which applies to it and
430"any later version", you have the option of following the terms and
431conditions either of that version or of any later version published by
432the Free Software Foundation. If the Library does not specify a
433license version number, you may choose any version ever published by
434the Free Software Foundation.
435
4367
437 14. If you wish to incorporate parts of the Library into other free
438programs whose distribution conditions are incompatible with these,
439write to the author to ask for permission. For software which is
440copyrighted by the Free Software Foundation, write to the Free
441Software Foundation; we sometimes make exceptions for this. Our
442decision will be guided by the two goals of preserving the free status
443of all derivatives of our free software and of promoting the sharing
444and reuse of software generally.
445
446 NO WARRANTY
447
448 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
449WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
450EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
451OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
452KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
453IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
454PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
455LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
456THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
457
458 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
459WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
460AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
461FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
462CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
463LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
464RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
465FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
466SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
467DAMAGES.
468
469 END OF TERMS AND CONDITIONS
470
4718
472 How to Apply These Terms to Your New Libraries
473
474 If you develop a new library, and you want it to be of the greatest
475possible use to the public, we recommend making it free software that
476everyone can redistribute and change. You can do so by permitting
477redistribution under these terms (or, alternatively, under the terms
478of the ordinary General Public License).
479
480 To apply these terms, attach the following notices to the library.
481It is safest to attach them to the start of each source file to most
482effectively convey the exclusion of warranty; and each file should
483have at least the "copyright" line and a pointer to where the full
484notice is found.
485
486
487 <one line to give the library's name and a brief idea of what it does.>
488 Copyright (C) <year> <name of author>
489
490 This library is free software; you can redistribute it and/or
491 modify it under the terms of the GNU Lesser General Public
492 License as published by the Free Software Foundation; either
493 version 2.1 of the License, or (at your option) any later version.
494
495 This library is distributed in the hope that it will be useful,
496 but WITHOUT ANY WARRANTY; without even the implied warranty of
497 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
498 Lesser General Public License for more details.
499
500 You should have received a copy of the GNU Lesser General Public
501 License along with this library; if not, write to the Free Software
502 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
503
504Also add information on how to contact you by electronic and paper mail.
505
506You should also get your employer (if you work as a programmer) or
507your school, if any, to sign a "copyright disclaimer" for the library,
508if necessary. Here is a sample; alter the names:
509
510 Yoyodyne, Inc., hereby disclaims all copyright interest in the
511 library `Frob' (a library for tweaking knobs) written by James
512 Random Hacker.
513
514 <signature of Ty Coon>, 1 April 1990
515 Ty Coon, President of Vice
516
517That's all there is to it!
518
519
5209
=== removed file 'README'
--- README 2012-05-15 19:43:43 +0000
+++ README 1970-01-01 00:00:00 +0000
@@ -1,18 +0,0 @@
1Software Updater for apt
2------------------------
3
4This is an application which lets you manage available updates for your
5computer via apt and python-apt.
6
7It also supports easy release upgrades. The following environment variables
8are honored:
9
10DEBUG_UPDATE_MANAGER:
11- If set, debug information is printed to sys.stderr. This is useful for
12 testing e.g. release upgrade checking/fetching.
13
14
15If the release upgrade is running in text mode and gnu screen is
16available it will automatically use gnu screen. This means that if
17e.g. the network connection is dropping just running the upgrader
18again will just reconnect to the running upgrade.
190
=== renamed file 'README.dist-upgrade' => 'README'
=== removed file 'TODO'
--- TODO 2007-07-31 10:55:22 +0000
+++ TODO 1970-01-01 00:00:00 +0000
@@ -1,22 +0,0 @@
1* offer removal of no-longer-supported apps
2* improve countrymirror detection
3
4
5UpdateManager.Common.aptsources.py:
6- make the distro detection in sources.list more clever by using the
7 origin informaton to avoid adding full uris to (unofficial/internal)
8 mirrors
9- make it possible to inherit the mirrros from a ParentSuite (for
10 the childs)
11
12Misc:
13- have a common error dialog readymade and rib out all those
14 GtkMessageDialogs
15- add download size to treeview
16- add /etc/apt/software-properties.d dir where the user can
17 install matchers and templates
18- handle cases like "deb http://bla/ dist sec1 sec2 # comment"
19- rework the add channel/cdrom dialogs
20- d'n'd for key files
21- use one row per section and not one per channel in the treeview
22- sort the sources by dist
230
=== removed directory 'UpdateManager'
=== removed file 'UpdateManager/ChangelogViewer.py'
--- UpdateManager/ChangelogViewer.py 2012-06-11 16:17:31 +0000
+++ UpdateManager/ChangelogViewer.py 1970-01-01 00:00:00 +0000
@@ -1,283 +0,0 @@
1# ReleaseNotesViewer.py
2#
3# Copyright (c) 2006 Sebastian Heinlein
4# 2007 Canonical
5#
6# Author: Sebastian Heinlein <sebastian.heinlein@web.de>
7# Michael Vogt <michael.vogt@ubuntu.com>
8#
9# This modul provides an inheritance of the Gtk.TextView that is
10# aware of http URLs and allows to open them in a browser.
11# It is based on the pygtk-demo "hypertext".
12#
13# This program is free software; you can redistribute it and/or
14# modify it under the terms of the GNU General Public License as
15# published by the Free Software Foundation; either version 2 of the
16# License, or (at your option) any later version.
17#
18# This program is distributed in the hope that it will be useful,
19# but WITHOUT ANY WARRANTY; without even the implied warranty of
20# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21# GNU General Public License for more details.
22#
23# You should have received a copy of the GNU General Public License
24# along with this program; if not, write to the Free Software
25# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
26# USA
27
28
29from __future__ import absolute_import
30
31from gi.repository import Gtk
32from gi.repository import Gdk
33from gi.repository import GObject
34from gi.repository import Pango
35from gettext import gettext as _
36
37from .ReleaseNotesViewer import open_url
38
39class ChangelogViewer(Gtk.TextView):
40 def __init__(self, changelog=None):
41 """Init the ChangelogViewer as an Inheritance of the Gtk.TextView"""
42 # init the parent
43 GObject.GObject.__init__(self)
44 # global hovering over link state
45 self.hovering = False
46 self.first = True
47 # setup the buffer and signals
48 self.set_property("editable", False)
49 self.set_cursor_visible(False)
50 # set some margin
51 self.set_right_margin(4)
52 self.set_left_margin(4)
53 self.set_pixels_above_lines(4)
54 self.buffer = Gtk.TextBuffer()
55 self.set_buffer(self.buffer)
56 self.connect("button-press-event", self.button_press_event)
57 self.connect("motion-notify-event", self.motion_notify_event)
58 self.connect("visibility-notify-event", self.visibility_notify_event)
59 #self.buffer.connect("changed", self.search_links)
60 self.buffer.connect_after("insert-text", self.on_insert_text)
61 # search for links in the changelog and make them clickable
62 if changelog != None:
63 self.buffer.set_text(changelog)
64
65 def create_context_menu(self, url):
66 """Create the context menu to be displayed when links are right clicked"""
67 self.menu = Gtk.Menu()
68
69 # create menu items
70 item_grey_link = Gtk.MenuItem()
71 item_grey_link.set_label(url)
72 item_grey_link.connect("activate", self.handle_context_menu, "open", url)
73 item_seperator = Gtk.MenuItem()
74 item_open_link = Gtk.MenuItem()
75 item_open_link.set_label(_("Open Link in Browser"))
76 item_open_link.connect("activate", self.handle_context_menu, "open", url)
77 item_copy_link = Gtk.MenuItem()
78 item_copy_link.set_label(_("Copy Link to Clipboard"))
79 item_copy_link.connect("activate", self.handle_context_menu, "copy", url)
80
81 # add menu items
82 self.menu.add(item_grey_link)
83 self.menu.add(item_seperator)
84 self.menu.add(item_open_link)
85 self.menu.add(item_copy_link)
86 self.menu.show_all()
87
88 def handle_context_menu(self, menuitem, action, url):
89 """Handle activate event for the links' context menu"""
90 if action == "open":
91 open_url(url)
92 if action == "copy":
93 # the following two lines used to be enough - then gtk3/pygi
94 # came along ...
95 #cb = Gtk.Clipboard()
96 #cb.set_text(url)
97 display = Gdk.Display.get_default()
98 selection = Gdk.Atom.intern ("CLIPBOARD", False)
99 cb = Gtk.Clipboard.get_for_display(display, selection)
100 cb.set_text(url, -1)
101 cb.store()
102
103 def tag_link(self, start, end, url):
104 """Apply the tag that marks links to the specified buffer selection"""
105 tags = start.get_tags()
106 for tag in tags:
107 url = getattr(tag, "url", None)
108 if url != "":
109 return
110 tag = self.buffer.create_tag(None, foreground="blue",
111 underline=Pango.Underline.SINGLE)
112 tag.url = url
113 self.buffer.apply_tag(tag , start, end)
114
115 def on_insert_text(self, buffer, iter_end, text, *args):
116 """Search for http URLs in newly inserted text
117 and tag them accordingly"""
118
119 # some convenient urls
120 MALONE = "https://launchpad.net/bugs/"
121 DEBIAN = "http://bugs.debian.org/"
122 CVE = "http://cve.mitre.org/cgi-bin/cvename.cgi?name="
123 # some convinient end-markers
124 ws = [" ","\t","\n"]
125 brak = [")","]",">"]
126 punct = [",","!",":"]
127 dot = ["."]+punct
128 dot_cr = [".\n"]
129
130 # search items are start-str, list-of-end-strs, url-prefix
131 # a lot of this search is "TEH SUCK"(tm) because of limitations
132 # in iter.forward_search()
133 # - i.e. no insensitive searching, no regexp
134 search_items = [ ("http://", ws+brak+punct+dot_cr, "http://"),
135 ("LP#", ws+brak+dot, MALONE),
136 ("LP: #", ws+brak+dot, MALONE),
137 ("lp: #", ws+brak+dot, MALONE),
138 ("LP:#", ws+brak+dot, MALONE),
139 ("Malone: #", ws+brak+dot, MALONE),
140 ("Malone:#", ws+brak+dot, MALONE),
141 ("Ubuntu: #", ws+brak+dot, MALONE),
142 ("Ubuntu:#", ws+brak+dot, MALONE),
143 ("Closes: #",ws+brak+dot, DEBIAN),
144 ("Closes:#",ws+brak+dot, DEBIAN),
145 ("closes:#",ws+brak+dot, DEBIAN),
146 ("closes: #",ws+brak+dot, DEBIAN),
147 ("CVE-", ws+brak+dot, CVE),
148 ]
149 # init
150 iter = buffer.get_iter_at_offset(iter_end.get_offset() - len(text))
151
152 # search for the next match in the buffer
153 for (start_str, end_list, url_prefix) in search_items:
154 while True:
155 ret = iter.forward_search(start_str,
156 Gtk.TextSearchFlags.VISIBLE_ONLY,
157 iter_end)
158 # if we reach the end break the loop
159 if not ret:
160 break
161 # get the position of the protocol prefix
162 (match_start, match_end) = ret
163 match_suffix = match_end.copy()
164 match_tmp = match_end.copy()
165 while True:
166 # extend the selection to the complete search item
167 if match_tmp.forward_char():
168 text = match_end.get_text(match_tmp)
169 if text in end_list:
170 break
171 # move one char futher to get two char
172 # end-markers (and back later) LP: #396393
173 match_tmp.forward_char()
174 text = match_end.get_text(match_tmp)
175 if text in end_list:
176 break
177 match_tmp.backward_char()
178 else:
179 break
180 match_end = match_tmp.copy()
181
182 # call the tagging method for the complete URL
183 url = url_prefix + match_suffix.get_text(match_end)
184
185 self.tag_link(match_start, match_end, url)
186 # set the starting point for the next search
187 iter = match_end
188
189 def button_press_event(self, text_view, event):
190 """callback for mouse click events"""
191 # we only react on left or right mouse clicks
192 if event.button != 1 and event.button != 3:
193 return False
194
195 # try to get a selection
196 try:
197 (start, end) = self.buffer.get_selection_bounds()
198 except ValueError:
199 pass
200 else:
201 if start.get_offset() != end.get_offset():
202 return False
203
204 # get the iter at the mouse position
205 (x, y) = self.window_to_buffer_coords(Gtk.TextWindowType.WIDGET,
206 int(event.x), int(event.y))
207 iter = self.get_iter_at_location(x, y)
208
209 # call open_url or menu.popup if an URL is assigned to the iter
210 tags = iter.get_tags()
211 for tag in tags:
212 if hasattr(tag, "url"):
213 if event.button == 1:
214 open_url(tag.url)
215 break
216 if event.button == 3:
217 self.create_context_menu(tag.url)
218 self.menu.popup(None, None, None, None, event.button, event.time)
219 return True
220
221 def motion_notify_event(self, text_view, event):
222 """callback for the mouse movement event, that calls the
223 check_hovering method with the mouse postition coordiantes"""
224 x, y = text_view.window_to_buffer_coords(Gtk.TextWindowType.WIDGET,
225 int(event.x), int(event.y))
226 self.check_hovering(x, y)
227 self.get_window(Gtk.TextWindowType.TEXT).get_pointer()
228 return False
229
230 def visibility_notify_event(self, text_view, event):
231 """callback if the widgets gets visible (e.g. moves to the foreground)
232 that calls the check_hovering method with the mouse position
233 coordinates"""
234 (screen, wx, wy, mod) = text_view.get_window(Gtk.TextWindowType.TEXT).get_pointer()
235 (bx, by) = text_view.window_to_buffer_coords(Gtk.TextWindowType.WIDGET, wx,
236 wy)
237 self.check_hovering(bx, by)
238 return False
239
240 def check_hovering(self, x, y):
241 """Check if the mouse is above a tagged link and if yes show
242 a hand cursor"""
243 _hovering = False
244 # get the iter at the mouse position
245 iter = self.get_iter_at_location(x, y)
246
247 # set _hovering if the iter has the tag "url"
248 tags = iter.get_tags()
249 for tag in tags:
250 if hasattr(tag, "url"):
251 _hovering = True
252 break
253
254 # change the global hovering state
255 if _hovering != self.hovering or self.first == True:
256 self.first = False
257 self.hovering = _hovering
258 # Set the appropriate cursur icon
259 if self.hovering:
260 self.get_window(Gtk.TextWindowType.TEXT).\
261 set_cursor(Gdk.Cursor.new(Gdk.CursorType.HAND2))
262 else:
263 self.get_window(Gtk.TextWindowType.TEXT).\
264 set_cursor(Gdk.Cursor.new(Gdk.CursorType.LEFT_PTR))
265
266
267if __name__ == "__main__":
268 w = Gtk.Window()
269 cv = ChangelogViewer()
270 changes = cv.get_buffer()
271 changes.create_tag("versiontag", weight=Pango.Weight.BOLD)
272 changes.set_text("""
273
274Version 6-14-0ubuntu1.9.04:
275
276 * New upstream version. LP: #382918.
277 Release notes at http://java.sun.com/javase/6/webnotes/ReleaseNotes.html.
278
279""")
280
281 w.add(cv)
282 w.show_all()
283 Gtk.main()
2840
=== removed directory 'UpdateManager/Core'
=== removed file 'UpdateManager/Core/AlertWatcher.py'
--- UpdateManager/Core/AlertWatcher.py 2012-05-01 14:01:29 +0000
+++ UpdateManager/Core/AlertWatcher.py 1970-01-01 00:00:00 +0000
@@ -1,96 +0,0 @@
1# AlertWatcher.py
2#
3# Copyright (c) 2010 Mohamed Amine IL Idrissi
4#
5# Author: Mohamed Amine IL Idrissi <ilidrissiamine@gmail.com>
6#
7# This program is free software; you can redistribute it and/or
8# modify it under the terms of the GNU General Public License as
9# published by the Free Software Foundation; either version 2 of the
10# License, or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program; if not, write to the Free Software
19# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20# USA
21
22from __future__ import absolute_import
23
24from gi.repository import GObject
25import dbus
26from dbus.mainloop.glib import DBusGMainLoop
27
28class AlertWatcher(GObject.GObject):
29 """ a class that checks for alerts and reports them, like a battery
30 or network warning """
31
32 __gsignals__ = {"network-alert": (GObject.SignalFlags.RUN_FIRST,
33 None,
34 (GObject.TYPE_INT,)),
35 "battery-alert": (GObject.SignalFlags.RUN_FIRST,
36 None,
37 (GObject.TYPE_BOOLEAN,)),
38 "network-3g-alert": (GObject.SignalFlags.RUN_FIRST,
39 None,
40 (GObject.TYPE_BOOLEAN,
41 GObject.TYPE_BOOLEAN,)),
42 }
43
44 def __init__(self):
45 GObject.GObject.__init__(self)
46 DBusGMainLoop(set_as_default=True)
47 self.bus = dbus.Bus(dbus.Bus.TYPE_SYSTEM)
48 self.network_state = 3 # make it always connected if NM isn't available
49
50 def check_alert_state(self):
51 try:
52 obj = self.bus.get_object("org.freedesktop.NetworkManager",
53 "/org/freedesktop/NetworkManager")
54 obj.connect_to_signal("StateChanged",
55 self._on_network_state_changed,
56 dbus_interface="org.freedesktop.NetworkManager")
57 interface = dbus.Interface(obj, "org.freedesktop.DBus.Properties")
58 self.network_state = interface.Get("org.freedesktop.NetworkManager", "State")
59 self._network_alert(self.network_state)
60 # power
61 obj = self.bus.get_object('org.freedesktop.UPower',
62 '/org/freedesktop/UPower')
63 obj.connect_to_signal("Changed", self._power_changed,
64 dbus_interface="org.freedesktop.UPower")
65 self._power_changed()
66 # 3g
67 self._update_3g_state()
68 except dbus.exceptions.DBusException:
69 pass
70
71 def _on_network_state_changed(self, state):
72 self._network_alert(state)
73 self._update_3g_state()
74
75 def _update_3g_state(self):
76 from .roam import NetworkManagerHelper
77 nm = NetworkManagerHelper()
78 on_3g = nm.is_active_connection_gsm_or_cdma()
79 is_roaming = nm.is_active_connection_gsm_or_cdma_roaming()
80 self._network_3g_alert(on_3g, is_roaming)
81
82 def _network_3g_alert(self, on_3g, is_roaming):
83 self.emit("network-3g-alert", on_3g, is_roaming)
84
85 def _network_alert(self, state):
86 self.network_state = state
87 self.emit("network-alert", state)
88
89 def _power_changed(self):
90 obj = self.bus.get_object("org.freedesktop.UPower", \
91 "/org/freedesktop/UPower")
92 interface = dbus.Interface(obj, "org.freedesktop.DBus.Properties")
93 on_battery = interface.Get("org.freedesktop.UPower", "OnBattery")
94 self.emit("battery-alert", on_battery)
95
96
970
=== removed file 'UpdateManager/Core/DistUpgradeFetcherCore.py'
--- UpdateManager/Core/DistUpgradeFetcherCore.py 2012-05-28 10:20:51 +0000
+++ UpdateManager/Core/DistUpgradeFetcherCore.py 1970-01-01 00:00:00 +0000
@@ -1,313 +0,0 @@
1# DistUpgradeFetcherCore.py
2#
3# Copyright (c) 2006 Canonical
4#
5# Author: Michael Vogt <michael.vogt@ubuntu.com>
6#
7# This program is free software; you can redistribute it and/or
8# modify it under the terms of the GNU General Public License as
9# published by the Free Software Foundation; either version 2 of the
10# License, or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program; if not, write to the Free Software
19# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20# USA
21
22from __future__ import absolute_import, print_function
23
24from string import Template
25import os
26import apt_pkg
27import logging
28import tarfile
29import tempfile
30import shutil
31import sys
32import subprocess
33from gettext import gettext as _
34from aptsources.sourceslist import SourcesList
35
36from .utils import get_dist, url_downloadable, country_mirror
37
38class DistUpgradeFetcherCore(object):
39 " base class (without GUI) for the upgrade fetcher "
40
41 DEFAULT_MIRROR="http://archive.ubuntu.com/ubuntu"
42 DEFAULT_COMPONENT="main"
43 DEBUG = "DEBUG_UPDATE_MANAGER" in os.environ
44
45 def __init__(self, new_dist, progress):
46 self.new_dist = new_dist
47 self.current_dist_name = get_dist()
48 self._progress = progress
49 # options to pass to the release upgrader when it is run
50 self.run_options = []
51
52 def _debug(self, msg):
53 " helper to show debug information "
54 if self.DEBUG:
55 sys.stderr.write(msg+"\n")
56
57 def showReleaseNotes(self):
58 return True
59
60 def error(self, summary, message):
61 """ dummy implementation for error display, should be overwriten
62 by subclasses that want to more fancy method
63 """
64 print(summary)
65 print(message)
66 return False
67
68 def authenticate(self):
69 if self.new_dist.upgradeToolSig:
70 f = self.tmpdir+"/"+os.path.basename(self.new_dist.upgradeTool)
71 sig = self.tmpdir+"/"+os.path.basename(self.new_dist.upgradeToolSig)
72 print(_("authenticate '%(file)s' against '%(signature)s' ") % {
73 'file' : os.path.basename(f),
74 'signature' : os.path.basename(sig)})
75 if self.gpgauthenticate(f, sig):
76 return True
77 return False
78
79 def gpgauthenticate(self, file, signature,
80 keyring='/etc/apt/trusted.gpg'):
81 """ authenticated a file against a given signature, if no keyring
82 is given use the apt default keyring
83 """
84 status_pipe = os.pipe()
85 logger_pipe = os.pipe()
86 gpg = [
87 "gpg",
88 "--status-fd", "%d" % status_pipe[1],
89 "--logger-fd", "%d" % logger_pipe[1],
90 "--no-options",
91 "--homedir", self.tmpdir,
92 "--no-default-keyring",
93 "--ignore-time-conflict",
94 "--keyring", keyring,
95 "--verify", signature, file,
96 ]
97 def gpg_preexec():
98 os.close(status_pipe[0])
99 os.close(logger_pipe[0])
100 proc = subprocess.Popen(
101 gpg, stderr=subprocess.PIPE, preexec_fn=gpg_preexec,
102 close_fds=False, universal_newlines=True)
103 os.close(status_pipe[1])
104 os.close(logger_pipe[1])
105 status_handle = os.fdopen(status_pipe[0])
106 logger_handle = os.fdopen(logger_pipe[0])
107 try:
108 gpgres = status_handle.read()
109 ret = proc.wait()
110 if ret != 0:
111 # gnupg returned a problem (non-zero exit)
112 print("gpg exited %d" % ret)
113 print("Debug information: ")
114 print(status_handle.read())
115 print(proc.stderr.read())
116 print(logger_handle.read())
117 return False
118 if "VALIDSIG" in gpgres:
119 return True
120 print("invalid result from gpg:")
121 print(gpgres)
122 return False
123 finally:
124 status_handle.close()
125 proc.stderr.close()
126 logger_handle.close()
127
128 def extractDistUpgrader(self):
129 # extract the tarbal
130 fname = os.path.join(self.tmpdir,os.path.basename(self.uri))
131 print(_("extracting '%s'") % os.path.basename(fname))
132 if not os.path.exists(fname):
133 return False
134 try:
135 tar = tarfile.open(self.tmpdir+"/"+os.path.basename(self.uri),"r")
136 for tarinfo in tar:
137 tar.extract(tarinfo)
138 tar.close()
139 except tarfile.ReadError as e:
140 logging.error("failed to open tarfile (%s)" % e)
141 return False
142 return True
143
144 def verifyDistUprader(self):
145 # FIXME: check a internal dependency file to make sure
146 # that the script will run correctly
147
148 # see if we have a script file that we can run
149 self.script = script = "%s/%s" % (self.tmpdir, self.new_dist.name)
150 if not os.path.exists(script):
151 return self.error(_("Could not run the upgrade tool"),
152 _("Could not run the upgrade tool") + ". " + _("This is most likely a bug in the upgrade tool. "
153 "Please report it as a bug using the command 'ubuntu-bug update-manager'."))
154 return True
155
156 def mirror_from_sources_list(self, uri, default_uri):
157 """
158 try to figure what the mirror is from current sources.list
159
160 do this by looing for matching DEFAULT_COMPONENT, current dist
161 in sources.list and then doing a http HEAD/ftp size request
162 to see if the uri is available on this server
163 """
164 self._debug("mirror_from_sources_list: %s" % self.current_dist_name)
165 sources = SourcesList(withMatcher=False)
166 seen = set()
167 for e in sources.list:
168 if e.disabled or e.invalid or not e.type == "deb":
169 continue
170 # check if we probed this mirror already
171 if e.uri in seen:
172 continue
173 # we are using the main mirror already, so we are fine
174 if (e.uri.startswith(default_uri) and
175 e.dist == self.current_dist_name and
176 self.DEFAULT_COMPONENT in e.comps):
177 return uri
178 elif (e.dist == self.current_dist_name and
179 "main" in e.comps):
180 mirror_uri = e.uri+uri[len(default_uri):]
181 if url_downloadable(mirror_uri, self._debug):
182 return mirror_uri
183 seen.add(e.uri)
184 self._debug("no mirror found")
185 return ""
186
187 def _expandUri(self, uri):
188 """
189 expand the uri so that it uses a mirror if the url starts
190 with a well know string (like archive.ubuntu.com)
191 """
192 # try to guess the mirror from the sources.list
193 if uri.startswith(self.DEFAULT_MIRROR):
194 self._debug("trying to find suitable mirror")
195 new_uri = self.mirror_from_sources_list(uri, self.DEFAULT_MIRROR)
196 if new_uri:
197 return new_uri
198 # if that fails, use old method
199 uri_template = Template(uri)
200 m = country_mirror()
201 new_uri = uri_template.safe_substitute(countrymirror=m)
202 # be paranoid and check if the given uri is really downloadable
203 try:
204 if not url_downloadable(new_uri, self._debug):
205 raise Exception("failed to download %s" % new_uri)
206 except Exception as e:
207 self._debug("url '%s' could not be downloaded" % e)
208 # else fallback to main server
209 new_uri = uri_template.safe_substitute(countrymirror='')
210 return new_uri
211
212 def fetchDistUpgrader(self):
213 " download the tarball with the upgrade script "
214 self.tmpdir = tmpdir = tempfile.mkdtemp(prefix="update-manager-")
215 os.chdir(tmpdir)
216 logging.debug("using tmpdir: '%s'" % tmpdir)
217 # turn debugging on here (if required)
218 if self.DEBUG > 0:
219 apt_pkg.config.set("Debug::Acquire::http","1")
220 apt_pkg.config.set("Debug::Acquire::ftp","1")
221 #os.listdir(tmpdir)
222 fetcher = apt_pkg.Acquire(self._progress)
223 if self.new_dist.upgradeToolSig != None:
224 uri = self._expandUri(self.new_dist.upgradeToolSig)
225 af1 = apt_pkg.AcquireFile(fetcher,
226 uri,
227 descr=_("Upgrade tool signature"))
228 # reference it here to shut pyflakes up
229 af1
230 if self.new_dist.upgradeTool != None:
231 self.uri = self._expandUri(self.new_dist.upgradeTool)
232 af2 = apt_pkg.AcquireFile(fetcher,
233 self.uri,
234 descr=_("Upgrade tool"))
235 # reference it here to shut pyflakes up
236 af2
237 result = fetcher.run()
238 if result != fetcher.RESULT_CONTINUE:
239 logging.warn("fetch result != continue (%s)" % result)
240 return False
241 # check that both files are really there and non-null
242 for f in [os.path.basename(self.new_dist.upgradeToolSig),
243 os.path.basename(self.new_dist.upgradeTool)]:
244 if not (os.path.exists(f) and os.path.getsize(f) > 0):
245 logging.warn("file '%s' missing" % f)
246 return False
247 return True
248 return False
249
250 def runDistUpgrader(self):
251 args = [self.script]+self.run_options
252 if os.getuid() != 0:
253 os.execv("/usr/bin/sudo",["sudo"]+args)
254 else:
255 os.execv(self.script,args)
256
257 def cleanup(self):
258 # cleanup
259 os.chdir("..")
260 # del tmpdir
261 shutil.rmtree(self.tmpdir)
262
263 def run(self):
264 # see if we have release notes
265 if not self.showReleaseNotes():
266 return
267 if not self.fetchDistUpgrader():
268 self.error(_("Failed to fetch"),
269 _("Fetching the upgrade failed. There may be a network "
270 "problem. "))
271 return
272 if not self.authenticate():
273 self.error(_("Authentication failed"),
274 _("Authenticating the upgrade failed. There may be a problem "
275 "with the network or with the server. "))
276 self.cleanup()
277 return
278 if not self.extractDistUpgrader():
279 self.error(_("Failed to extract"),
280 _("Extracting the upgrade failed. There may be a problem "
281 "with the network or with the server. "))
282
283 return
284 if not self.verifyDistUprader():
285 self.error(_("Verification failed"),
286 _("Verifying the upgrade failed. There may be a problem "
287 "with the network or with the server. "))
288 self.cleanup()
289 return
290 try:
291 # check if we can execute, if we run it via sudo we will
292 # not know otherwise, sudo/gksu will not raise a exception
293 if not os.access(self.script, os.X_OK):
294 ex = OSError("Can not execute '%s'" % self.script)
295 ex.errno = 13
296 raise ex
297 self.runDistUpgrader()
298 except OSError as e:
299 if e.errno == 13:
300 self.error(_("Can not run the upgrade"),
301 _("This usually is caused by a system where /tmp "
302 "is mounted noexec. Please remount without "
303 "noexec and run the upgrade again."))
304 return False
305 else:
306 self.error(_("Can not run the upgrade"),
307 _("The error message is '%s'.") % e.strerror)
308 return True
309
310if __name__ == "__main__":
311 d = DistUpgradeFetcherCore(None,None)
312# print(d.authenticate('/tmp/Release','/tmp/Release.gpg'))
313 print("got mirror: '%s'" % d.mirror_from_sources_list("http://archive.ubuntu.com/ubuntu/dists/intrepid-proposed/main/dist-upgrader-all/0.93.34/intrepid.tar.gz", "http://archive.ubuntu.com/ubuntu"))
3140
=== removed file 'UpdateManager/Core/MetaRelease.py'
--- UpdateManager/Core/MetaRelease.py 2012-06-15 20:13:15 +0000
+++ UpdateManager/Core/MetaRelease.py 1970-01-01 00:00:00 +0000
@@ -1,350 +0,0 @@
1# MetaRelease.py
2#
3# Copyright (c) 2004,2005 Canonical
4#
5# Author: Michael Vogt <michael.vogt@ubuntu.com>
6#
7# This program is free software; you can redistribute it and/or
8# modify it under the terms of the GNU General Public License as
9# published by the Free Software Foundation; either version 2 of the
10# License, or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program; if not, write to the Free Software
19# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20# USA
21
22from __future__ import absolute_import, print_function
23
24import apt_pkg
25try:
26 import configparser
27except ImportError:
28 import ConfigParser as configparser
29try:
30 from http.client import BadStatusLine
31except ImportError:
32 from httplib import BadStatusLine
33import logging
34import email.utils
35import os
36import sys
37import time
38import threading
39try:
40 from urllib.request import Request, urlopen
41 from urllib.error import HTTPError, URLError
42except ImportError:
43 from urllib2 import HTTPError, Request, URLError, urlopen
44
45from .utils import get_lang, get_dist, get_dist_version, get_ubuntu_flavor, get_ubuntu_flavor_name
46
47class Dist(object):
48 def __init__(self, name, version, date, supported):
49 self.name = name
50 self.version = version
51 self.date = date
52 self.supported = supported
53 self.releaseNotesURI = None
54 self.releaseNotesHtmlUri = None
55 self.upgradeTool = None
56 self.upgradeToolSig = None
57 # the server may report that the upgrade is broken currently
58 self.upgrade_broken = None
59
60class MetaReleaseCore(object):
61 """
62 A MetaReleaseCore object astracts the list of released
63 distributions.
64 """
65
66 DEBUG = "DEBUG_UPDATE_MANAGER" in os.environ
67
68 # some constants
69 CONF = "/etc/update-manager/release-upgrades"
70 CONF_METARELEASE = "/etc/update-manager/meta-release"
71
72 def __init__(self,
73 useDevelopmentRelease=False,
74 useProposed=False,
75 forceLTS=False,
76 forceDownload=False):
77 self._debug("MetaRelease.__init__() useDevel=%s useProposed=%s" % (useDevelopmentRelease, useProposed))
78 # force download instead of sending if-modified-since
79 self.forceDownload = forceDownload
80 # information about the available dists
81 self.downloading = True
82 self.upgradable_to = None
83 self.new_dist = None
84 self.flavor_name = get_ubuntu_flavor_name()
85 self.current_dist_name = get_dist()
86 self.current_dist_version = get_dist_version()
87 self.no_longer_supported = None
88
89 # default (if the conf file is missing)
90 self.METARELEASE_URI = "http://changelogs.ubuntu.com/meta-release"
91 self.METARELEASE_URI_LTS = "http://changelogs.ubuntu.com/meta-release-lts"
92 self.METARELEASE_URI_UNSTABLE_POSTFIX = "-development"
93 self.METARELEASE_URI_PROPOSED_POSTFIX = "-development"
94
95 # check the meta-release config first
96 parser = configparser.ConfigParser()
97 if os.path.exists(self.CONF_METARELEASE):
98 try:
99 parser.read(self.CONF_METARELEASE)
100 except configparser.Error as e:
101 sys.stderr.write("ERROR: failed to read '%s':\n%s" % (
102 self.CONF_METARELEASE, e))
103 return
104 # make changing the metarelease file and the location
105 # for the files easy
106 if parser.has_section("METARELEASE"):
107 sec = "METARELEASE"
108 for k in ["URI",
109 "URI_LTS",
110 "URI_UNSTABLE_POSTFIX",
111 "URI_PROPOSED_POSTFIX"]:
112 if parser.has_option(sec, k):
113 self._debug("%s: %s " % (self.CONF_METARELEASE,
114 parser.get(sec,k)))
115 setattr(self, "%s_%s" % (sec, k), parser.get(sec, k))
116
117 # check the config file first to figure if we want lts upgrades only
118 parser = configparser.ConfigParser()
119 if os.path.exists(self.CONF):
120 try:
121 parser.read(self.CONF)
122 except configparser.Error as e:
123 sys.stderr.write("ERROR: failed to read '%s':\n%s" % (
124 self.CONF, e))
125 return
126 # now check which specific url to use
127 if parser.has_option("DEFAULT","Prompt"):
128 type = parser.get("DEFAULT","Prompt").lower()
129 if (type == "never" or type == "no"):
130 # nothing to do for this object
131 # FIXME: what about no longer supported?
132 self.downloading = False
133 return
134 elif type == "lts":
135 self.METARELEASE_URI = self.METARELEASE_URI_LTS
136 # needed for the _tryUpgradeSelf() code in DistUpgradeController
137 if forceLTS:
138 self.METARELEASE_URI = self.METARELEASE_URI_LTS
139 # devel and proposed "just" change the postfix
140 if useDevelopmentRelease:
141 self.METARELEASE_URI += self.METARELEASE_URI_UNSTABLE_POSTFIX
142 elif useProposed:
143 self.METARELEASE_URI += self.METARELEASE_URI_PROPOSED_POSTFIX
144
145 self._debug("metarelease-uri: %s" % self.METARELEASE_URI)
146 self.metarelease_information = None
147 if not self._buildMetaReleaseFile():
148 self._debug("_buildMetaReleaseFile failed")
149 return
150 # we start the download thread here and we have a timeout
151 threading.Thread(target=self.download).start()
152 #threading.Thread(target=self.check).start()
153
154 def _buildMetaReleaseFile(self):
155 # build the metarelease_file name
156 self.METARELEASE_FILE = os.path.join("/var/lib/update-manager/",
157 os.path.basename(self.METARELEASE_URI))
158 # check if we can write to the global location, if not,
159 # write to homedir
160 try:
161 open(self.METARELEASE_FILE,"a")
162 except IOError as e:
163 cache_dir = os.getenv(
164 "XDG_CACHE_HOME", os.path.expanduser("~/.cache"))
165 path = os.path.join(cache_dir, 'update-manager-core')
166 if not os.path.exists(path):
167 try:
168 os.mkdir(path)
169 except OSError as e:
170 sys.stderr.write("mkdir() failed: '%s'" % e)
171 return False
172 self.METARELEASE_FILE = os.path.join(path,os.path.basename(self.METARELEASE_URI))
173 # if it is empty, remove it to avoid I-M-S hits on empty file
174 try:
175 if os.path.getsize(self.METARELEASE_FILE) == 0:
176 os.unlink(self.METARELEASE_FILE)
177 except Exception as e:
178 pass
179 return True
180
181 def dist_no_longer_supported(self, dist):
182 """ virtual function that is called when the distro is no longer
183 supported
184 """
185 self.no_longer_supported = dist
186 def new_dist_available(self, dist):
187 """ virtual function that is called when a new distro release
188 is available
189 """
190 self.new_dist = dist
191
192 def parse(self):
193 self._debug("MetaRelease.parse()")
194 current_dist_name = self.current_dist_name
195 self._debug("current dist name: '%s'" % current_dist_name)
196 current_dist = None
197 dists = []
198
199 # parse the metarelease_information file
200 index_tag = apt_pkg.TagFile(self.metarelease_information)
201 step_result = index_tag.step()
202 while step_result:
203 if "Dist" in index_tag.section:
204 name = index_tag.section["Dist"]
205 self._debug("found distro name: '%s'" % name)
206 rawdate = index_tag.section["Date"]
207 parseddate = list(email.utils.parsedate(rawdate))
208 parseddate[8] = 0 # assume no DST
209 date = time.mktime(tuple(parseddate))
210 supported = int(index_tag.section["Supported"])
211 version = index_tag.section["Version"]
212 # add the information to a new date object
213 dist = Dist(name, version, date,supported)
214 if "ReleaseNotes" in index_tag.section:
215 dist.releaseNotesURI = index_tag.section["ReleaseNotes"]
216 lang = get_lang()
217 if lang:
218 dist.releaseNotesURI += "?lang=%s" % lang
219 if "ReleaseNotesHtml" in index_tag.section:
220 dist.releaseNotesHtmlUri = index_tag.section["ReleaseNotesHtml"]
221 query = self._get_release_notes_uri_query_string(dist)
222 if query:
223 dist.releaseNotesHtmlUri += query
224 if "UpgradeTool" in index_tag.section:
225 dist.upgradeTool = index_tag.section["UpgradeTool"]
226 if "UpgradeToolSignature" in index_tag.section:
227 dist.upgradeToolSig = index_tag.section["UpgradeToolSignature"]
228 if "UpgradeBroken" in index_tag.section:
229 dist.upgrade_broken = index_tag.section["UpgradeBroken"]
230 dists.append(dist)
231 if name == current_dist_name:
232 current_dist = dist
233 step_result = index_tag.step()
234
235 # first check if the current runing distro is in the meta-release
236 # information. if not, we assume that we run on something not
237 # supported and silently return
238 if current_dist is None:
239 self._debug("current dist not found in meta-release file\n")
240 return False
241
242 # then see what we can upgrade to
243 upgradable_to = ""
244 for dist in dists:
245 if dist.date > current_dist.date:
246 upgradable_to = dist
247 self._debug("new dist: %s" % upgradable_to)
248 break
249
250 # only warn if unsupported and a new dist is available (because
251 # the development version is also unsupported)
252 if upgradable_to != "" and not current_dist.supported:
253 self.upgradable_to = upgradable_to
254 self.dist_no_longer_supported(current_dist)
255 if upgradable_to != "":
256 self.upgradable_to = upgradable_to
257 self.new_dist_available(upgradable_to)
258
259 # parsing done and sucessfully
260 return True
261
262 # the network thread that tries to fetch the meta-index file
263 # can't touch the gui, runs as a thread
264 def download(self):
265 self._debug("MetaRelease.download()")
266 lastmodified = 0
267 req = Request(self.METARELEASE_URI)
268 # make sure that we always get the latest file (#107716)
269 req.add_header("Cache-Control", "No-Cache")
270 req.add_header("Pragma", "no-cache")
271 if os.access(self.METARELEASE_FILE, os.W_OK):
272 try:
273 lastmodified = os.stat(self.METARELEASE_FILE).st_mtime
274 except OSError as e:
275 pass
276 if lastmodified > 0 and not self.forceDownload:
277 req.add_header("If-Modified-Since", time.asctime(time.gmtime(lastmodified)))
278 try:
279 # open
280 uri=urlopen(req, timeout=20)
281 # sometime there is a root owned meta-relase file
282 # there, try to remove it so that we get it
283 # with proper permissions
284 if (os.path.exists(self.METARELEASE_FILE) and
285 not os.access(self.METARELEASE_FILE,os.W_OK)):
286 try:
287 os.unlink(self.METARELEASE_FILE)
288 except OSError as e:
289 print("Can't unlink '%s' (%s)" % (self.METARELEASE_FILE, e))
290 # we may get exception here on e.g. disk full
291 try:
292 f=open(self.METARELEASE_FILE,"w+b")
293 for line in uri.readlines():
294 f.write(line)
295 f.flush()
296 f.seek(0,0)
297 self.metarelease_information=f
298 except IOError as e:
299 pass
300 uri.close()
301 # http error
302 except HTTPError as e:
303 # mvo: only reuse local info on "not-modified"
304 if e.code == 304 and os.path.exists(self.METARELEASE_FILE):
305 self._debug("reading file '%s'" % self.METARELEASE_FILE)
306 self.metarelease_information=open(self.METARELEASE_FILE,"r")
307 else:
308 self._debug("result of meta-release download: '%s'" % e)
309 # generic network error
310 except (URLError, BadStatusLine) as e:
311 self._debug("result of meta-release download: '%s'" % e)
312 # now check the information we have
313 if self.metarelease_information != None:
314 self._debug("have self.metarelease_information")
315 try:
316 self.parse()
317 except:
318 logging.exception("parse failed for '%s'" % self.METARELEASE_FILE)
319 # no use keeping a broken file around
320 os.remove(self.METARELEASE_FILE)
321 # we don't want to keep a meta-release file around when it
322 # has a "Broken" flag, this ensures we are not bitten by
323 # I-M-S/cache issues
324 if self.new_dist and self.new_dist.upgrade_broken:
325 os.remove(self.METARELEASE_FILE)
326 else:
327 self._debug("NO self.metarelease_information")
328 self.downloading = False
329
330 def _get_release_notes_uri_query_string(self, dist):
331 q = "?"
332 # get the lang
333 lang = get_lang()
334 if lang:
335 q += "lang=%s&" % lang
336 # get the os
337 os = get_ubuntu_flavor()
338 q += "os=%s&" % os
339 # get the version to upgrade to
340 q += "ver=%s" % dist.version
341 return q
342
343 def _debug(self, msg):
344 if self.DEBUG:
345 sys.stderr.write(msg+"\n")
346
347
348if __name__ == "__main__":
349 meta = MetaReleaseCore(False, False)
350
3510
=== removed file 'UpdateManager/Core/MyCache.py'
--- UpdateManager/Core/MyCache.py 2012-06-12 01:40:26 +0000
+++ UpdateManager/Core/MyCache.py 1970-01-01 00:00:00 +0000
@@ -1,366 +0,0 @@
1# MyCache.py
2#
3# Copyright (c) 2004-2008 Canonical
4#
5# Author: Michael Vogt <mvo@debian.org>
6#
7# This program is free software; you can redistribute it and/or
8# modify it under the terms of the GNU General Public License as
9# published by the Free Software Foundation; either version 2 of the
10# License, or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program; if not, write to the Free Software
19# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20# USA
21
22from __future__ import absolute_import, print_function
23
24import warnings
25warnings.filterwarnings("ignore", "apt API not stable yet", FutureWarning)
26import apt
27import apt_pkg
28import logging
29import os
30try:
31 from urllib.error import HTTPError
32 from urllib.request import urlopen
33 from urllib.parse import urlsplit
34except ImportError:
35 from urllib2 import HTTPError, urlopen
36 from urlparse import urlsplit
37try:
38 from http.client import BadStatusLine
39except ImportError:
40 from httplib import BadStatusLine
41import socket
42import re
43import DistUpgrade.DistUpgradeCache
44from gettext import gettext as _
45from .UpdateList import UpdateOrigin
46
47SYNAPTIC_PINFILE = "/var/lib/synaptic/preferences"
48CHANGELOGS_URI="http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/%s"
49
50class HttpsChangelogsUnsupportedError(Exception):
51 """ https changelogs with credentials are unsupported because of the
52 lack of certitifcation validation in urllib2 which allows MITM
53 attacks to steal the credentials
54 """
55 pass
56
57class MyCache(DistUpgrade.DistUpgradeCache.MyCache):
58
59 CHANGELOG_ORIGIN = "Ubuntu"
60
61 def __init__(self, progress, rootdir=None):
62 apt.Cache.__init__(self, progress, rootdir)
63 # raise if we have packages in reqreinst state
64 # and let the caller deal with that (runs partial upgrade)
65 assert len(self.req_reinstall_pkgs) == 0
66 # check if the dpkg journal is ok (we need to do that here
67 # too because libapt will only do it when it tries to lock
68 # the packaging system)
69 assert(not self._dpkgJournalDirty())
70 # init the regular cache
71 self._initDepCache()
72 self.all_changes = {}
73 self.all_news = {}
74 # on broken packages, try to fix via saveDistUpgrade()
75 if self._depcache.broken_count > 0:
76 self.saveDistUpgrade()
77 assert (self._depcache.broken_count == 0 and
78 self._depcache.del_count == 0)
79
80 def _dpkgJournalDirty(self):
81 """
82 test if the dpkg journal is dirty
83 (similar to debSystem::CheckUpdates)
84 """
85 d = os.path.dirname(
86 apt_pkg.config.find_file("Dir::State::status"))+"/updates"
87 for f in os.listdir(d):
88 if re.match("[0-9]+", f):
89 return True
90 return False
91
92 def _initDepCache(self):
93 #apt_pkg.config.set("Debug::pkgPolicy","1")
94 #self.depcache = apt_pkg.GetDepCache(self.cache)
95 #self._depcache = apt_pkg.GetDepCache(self._cache)
96 self._depcache.read_pinfile()
97 if os.path.exists(SYNAPTIC_PINFILE):
98 self._depcache.read_pinfile(SYNAPTIC_PINFILE)
99 self._depcache.init()
100 def clear(self):
101 self._initDepCache()
102 @property
103 def required_download(self):
104 """ get the size of the packages that are required to download """
105 pm = apt_pkg.PackageManager(self._depcache)
106 fetcher = apt_pkg.Acquire()
107 pm.get_archives(fetcher, self._list, self._records)
108 return fetcher.fetch_needed
109 @property
110 def install_count(self):
111 return self._depcache.inst_count
112 def keep_count(self):
113 return self._depcache.keep_count
114 def saveDistUpgrade(self):
115 """ this functions mimics a upgrade but will never remove anything """
116 #self._apply_dselect_upgrade()
117 self._depcache.upgrade(True)
118 wouldDelete = self._depcache.del_count
119 if self._depcache.del_count > 0:
120 self.clear()
121 assert self._depcache.broken_count == 0 and self._depcache.del_count == 0
122 #self._apply_dselect_upgrade()
123 self._depcache.upgrade()
124 return wouldDelete
125 def match_package_origin(self, pkg, matcher):
126 """ match 'pkg' origin against 'matcher', take versions between
127 installed.version and candidate.version into account too
128 Useful if installed pkg A v1.0 is available in both
129 -updates (as v1.2) and -security (v1.1). we want to display
130 it as a security update then
131 """
132 inst_ver = pkg._pkg.current_ver
133 cand_ver = self._depcache.get_candidate_ver(pkg._pkg)
134 # init matcher with candidate.version
135 update_origin = matcher[(None,None)]
136 verFileIter = None
137 for (verFileIter,index) in cand_ver.file_list:
138 if (verFileIter.archive, verFileIter.origin) in matcher:
139 indexfile = pkg._pcache._list.find_index(verFileIter)
140 if indexfile: # and indexfile.IsTrusted:
141 match = matcher[verFileIter.archive, verFileIter.origin]
142 update_origin = match
143 break
144 else:
145 # add a node for each origin/archive combination
146 if verFileIter and verFileIter.origin and verFileIter.archive:
147 matcher[verFileIter.archive, verFileIter.origin] = UpdateOrigin(_("Other updates (%s)") % verFileIter.origin, 0)
148 update_origin = matcher[verFileIter.archive, verFileIter.origin]
149 # if the candidate comes from a unknown source (e.g. a PPA) skip
150 # skip the shadow logic below as it would put e.g. a PPA package
151 # in "Recommended updates" when the version in the PPA
152 # is higher than the one in %s-updates
153 if update_origin.importance <= 0:
154 return update_origin
155 # for known packages, check if we have higher versions that
156 # "shadow" this one
157 for ver in pkg._pkg.version_list:
158 # discard is < than installed ver
159 if (inst_ver and
160 apt_pkg.version_compare(ver.ver_str, inst_ver.ver_str) <= 0):
161 #print("skipping '%s' " % ver.ver_str)
162 continue
163 # check if we have a match
164 for(verFileIter,index) in ver.file_list:
165 if (verFileIter.archive, verFileIter.origin) in matcher:
166 indexfile = pkg._pcache._list.find_index(verFileIter)
167 if indexfile: # and indexfile.IsTrusted:
168 match = matcher[verFileIter.archive, verFileIter.origin]
169 if match.importance > update_origin.importance:
170 update_origin = match
171 return update_origin
172
173 def _strip_epoch(self, verstr):
174 " strip of the epoch "
175 l = verstr.split(":")
176 if len(l) > 1:
177 verstr = "".join(l[1:])
178 return verstr
179
180 def _get_changelog_or_news(self, name, fname, strict_versioning=False, changelogs_uri=None):
181 " helper that fetches the file in question "
182 # don't touch the gui in this function, it needs to be thread-safe
183 pkg = self[name]
184
185 # get the src package name
186 srcpkg = pkg.candidate.source_name
187
188 # assume "main" section
189 src_section = "main"
190 # use the section of the candidate as a starting point
191 section = pkg._pcache._depcache.get_candidate_ver(pkg._pkg).section
192
193 # get the source version, start with the binaries version
194 srcver_epoch = pkg.candidate.version
195 srcver = self._strip_epoch(srcver_epoch)
196 #print("bin: %s" % binver)
197
198 l = section.split("/")
199 if len(l) > 1:
200 src_section = l[0]
201
202 # lib is handled special
203 prefix = srcpkg[0]
204 if srcpkg.startswith("lib"):
205 prefix = "lib" + srcpkg[3]
206
207 # the changelogs_uri argument overrides the default changelogs_uri,
208 # this is useful for e.g. PPAs where we construct the changelogs
209 # path differently
210 if changelogs_uri:
211 uri = changelogs_uri
212 else:
213 uri = CHANGELOGS_URI % (src_section,prefix,srcpkg,srcpkg, srcver, fname)
214
215 # https uris are not supported when they contain a username/password
216 # because the urllib2 https implementation will not check certificates
217 # and so its possible to do a man-in-the-middle attack to steal the
218 # credentials
219 res = urlsplit(uri)
220 if res.scheme == "https" and res.username != "":
221 raise HttpsChangelogsUnsupportedError(
222 "https locations with username/password are not"
223 "supported to fetch changelogs")
224
225 # print("Trying: %s " % uri)
226 changelog = urlopen(uri)
227 #print(changelog.read())
228 # do only get the lines that are new
229 alllines = ""
230 regexp = "^%s \((.*)\)(.*)$" % (re.escape(srcpkg))
231
232 while True:
233 line = changelog.readline().decode("UTF-8", "replace")
234 if line == "":
235 break
236 match = re.match(regexp,line)
237 if match:
238 # strip epoch from installed version
239 # and from changelog too
240 installed = getattr(pkg.installed, "version", None)
241 if installed and ":" in installed:
242 installed = installed.split(":",1)[1]
243 changelogver = match.group(1)
244 if changelogver and ":" in changelogver:
245 changelogver = changelogver.split(":",1)[1]
246 # we test for "==" here for changelogs
247 # to ensure that the version
248 # is actually really in the changelog - if not
249 # just display it all, this catches cases like:
250 # gcc-defaults with "binver=4.3.1" and srcver=1.76
251 #
252 # for NEWS.Debian we do require the changelogver > installed
253 if strict_versioning:
254 if (installed and
255 apt_pkg.version_compare(changelogver,installed)<0):
256 break
257 else:
258 if (installed and
259 apt_pkg.version_compare(changelogver,installed)==0):
260 break
261 alllines = alllines + line
262 return alllines
263
264 def _guess_third_party_changelogs_uri_by_source(self, name):
265 pkg = self[name]
266 deb_uri = pkg.candidate.uri
267 if deb_uri is None:
268 return None
269 srcrec = pkg.candidate.record.get("Source")
270 if not srcrec:
271 return None
272 # srcpkg can be "apt" or "gcc-default (1.0)"
273 srcpkg = srcrec.split("(")[0].strip()
274 if "(" in srcrec:
275 srcver = srcrec.split("(")[1].rstrip(")")
276 else:
277 srcver = pkg.candidate.version
278 base_uri = deb_uri.rpartition("/")[0]
279 return base_uri + "/%s_%s.changelog" % (srcpkg, srcver)
280
281 def _guess_third_party_changelogs_uri_by_binary(self, name):
282 """ guess changelogs uri based on ArchiveURI by replacing .deb
283 with .changelog
284 """
285 # there is always a pkg and a pkg.candidate, no need to add
286 # check here
287 pkg = self[name]
288 deb_uri = pkg.candidate.uri
289 if deb_uri:
290 return "%s.changelog" % deb_uri.rsplit(".", 1)[0]
291 return None
292
293
294 def get_news_and_changelog(self, name, lock):
295 self.get_news(name)
296 self.get_changelog(name)
297 try:
298 lock.release()
299 except:
300 pass
301
302 def get_news(self, name):
303 " get the NEWS.Debian file from the changelogs location "
304 try:
305 news = self._get_changelog_or_news(name, "NEWS.Debian", True)
306 except Exception:
307 return
308 if news:
309 self.all_news[name] = news
310
311 def _fetch_changelog_for_third_party_package(self, name):
312 # Try non official changelog location
313 changelogs_uri_binary = self._guess_third_party_changelogs_uri_by_binary(name)
314 changelogs_uri_source = self._guess_third_party_changelogs_uri_by_source(name)
315 error_message = ""
316 for changelogs_uri in [changelogs_uri_binary,changelogs_uri_source]:
317 if changelogs_uri:
318 try:
319 changelog = self._get_changelog_or_news(
320 name, "changelog", False, changelogs_uri)
321 self.all_changes[name] += changelog
322 except (HTTPError, HttpsChangelogsUnsupportedError):
323 # no changelogs_uri or 404
324 error_message = _(
325 "This update does not come from a "
326 "source that supports changelogs.")
327 except (IOError, BadStatusLine, socket.error):
328 # network errors and others
329 logging.exception("error on changelog fetching")
330 error_message = _(
331 "Failed to download the list of changes. \n"
332 "Please check your Internet connection.")
333 self.all_changes[name] += error_message
334
335 def get_changelog(self, name):
336 " get the changelog file from the changelog location "
337 origins = self[name].candidate.origins
338 self.all_changes[name] = _("Changes for the versions:\nInstalled version: %s\nAvailable version: %s\n\n") % (getattr(self[name].installed, "version", None), self[name].candidate.version)
339 if not self.CHANGELOG_ORIGIN in [o.origin for o in origins]:
340 self._fetch_changelog_for_third_party_package(name)
341 return
342 # fixup epoch handling version
343 srcpkg = self[name].candidate.source_name
344 srcver_epoch = self[name].candidate.version.replace(':', '%3A')
345 try:
346 changelog = self._get_changelog_or_news(name, "changelog")
347 if len(changelog) == 0:
348 changelog = _("The changelog does not contain any relevant changes.\n\n"
349 "Please use http://launchpad.net/ubuntu/+source/%s/%s/+changelog\n"
350 "until the changes become available or try again "
351 "later.") % (srcpkg, srcver_epoch)
352 except HTTPError as e:
353 changelog = _("The list of changes is not available yet.\n\n"
354 "Please use http://launchpad.net/ubuntu/+source/%s/%s/+changelog\n"
355 "until the changes become available or try again "
356 "later.") % (srcpkg, srcver_epoch)
357 except (IOError, BadStatusLine, socket.error) as e:
358 print("caught exception: ", e)
359 changelog = _("Failed to download the list "
360 "of changes. \nPlease "
361 "check your Internet "
362 "connection.")
363 self.all_changes[name] += changelog
364
365
366
3670
=== removed file 'UpdateManager/Core/UpdateList.py'
--- UpdateManager/Core/UpdateList.py 2012-06-12 13:17:46 +0000
+++ UpdateManager/Core/UpdateList.py 1970-01-01 00:00:00 +0000
@@ -1,102 +0,0 @@
1# UpdateList.py
2#
3# Copyright (c) 2004-2008 Canonical
4#
5# Author: Michael Vogt <mvo@debian.org>
6#
7# This program is free software; you can redistribute it and/or
8# modify it under the terms of the GNU General Public License as
9# published by the Free Software Foundation; either version 2 of the
10# License, or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program; if not, write to the Free Software
19# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20# USA
21
22from __future__ import print_function
23
24import warnings
25warnings.filterwarnings("ignore", "Accessed deprecated property", DeprecationWarning)
26
27from gettext import gettext as _
28import operator
29import subprocess
30import sys
31
32class UpdateOrigin(object):
33 def __init__(self, desc, importance):
34 self.packages = []
35 self.importance = importance
36 self.description = desc
37
38class UpdateList(object):
39 """
40 class that contains the list of available updates in
41 self.pkgs[origin] where origin is the user readable string
42 """
43
44 def __init__(self, parent):
45 # a map of packages under their origin
46 try:
47 dist = subprocess.check_output(
48 ["lsb_release", "-c", "-s"], universal_newlines=True).strip()
49 except subprocess.CalledProcessError as e:
50 print("Error in lsb_release: %s" % e)
51 parent.error(_("Failed to detect distribution"),
52 _("A error '%s' occurred while checking what system "
53 "you are using.") % e)
54 sys.exit(1)
55 self.distUpgradeWouldDelete = 0
56 self.pkgs = {}
57 self.num_updates = 0
58 self.matcher = self.initMatcher(dist)
59
60 def initMatcher(self, dist):
61 # (origin, archive, description, importance)
62 matcher_templates = [
63 ("%s-security" % dist, "Ubuntu", _("Important security updates"),10),
64 ("%s-updates" % dist, "Ubuntu", _("Recommended updates"), 9),
65 ("%s-proposed" % dist, "Ubuntu", _("Proposed updates"), 8),
66 ("%s-backports" % dist, "Ubuntu", _("Backports"), 7),
67 (dist, "Ubuntu", _("Distribution updates"), 6)
68 ]
69 matcher = {}
70 for (origin, archive, desc, importance) in matcher_templates:
71 matcher[(origin, archive)] = UpdateOrigin(desc, importance)
72 matcher[(None,None)] = UpdateOrigin(_("Other updates"), -1)
73 return matcher
74
75 def update(self, cache):
76 self.held_back = []
77
78 # do the upgrade
79 self.distUpgradeWouldDelete = cache.saveDistUpgrade()
80
81 #dselect_upgrade_origin = UpdateOrigin(_("Previous selected"), 1)
82
83 # sort by origin
84 for pkg in cache:
85 if pkg.is_upgradable or pkg.marked_install:
86 if getattr(pkg.candidate, "origins", None) == None:
87 # can happen for e.g. locked packages
88 # FIXME: do something more sensible here (but what?)
89 print("WARNING: upgradable but no candidate.origins?!?: ", pkg.name)
90 continue
91 # check where the package belongs
92 origin_node = cache.match_package_origin(pkg, self.matcher)
93 if origin_node not in self.pkgs:
94 self.pkgs[origin_node] = []
95 self.pkgs[origin_node].append(pkg)
96 self.num_updates = self.num_updates + 1
97 if pkg.is_upgradable and not (pkg.marked_upgrade or pkg.marked_install):
98 self.held_back.append(pkg.name)
99 for l in self.pkgs.keys():
100 self.pkgs[l].sort(key=operator.attrgetter("name"))
101 self.keepcount = cache._depcache.keep_count
102
1030
=== removed file 'UpdateManager/Core/__init__.py'
=== removed file 'UpdateManager/Core/roam.py'
--- UpdateManager/Core/roam.py 2012-05-01 00:29:04 +0000
+++ UpdateManager/Core/roam.py 1970-01-01 00:00:00 +0000
@@ -1,205 +0,0 @@
1# utils.py
2#
3# Copyright (c) 2011 Canonical
4#
5# Author: Alex Chiang <achiang@canonical.com>
6# Michael Vogt <michael.vogt@ubuntu.com>
7#
8# This program is free software; you can redistribute it and/or
9# modify it under the terms of the GNU General Public License as
10# published by the Free Software Foundation; either version 2 of the
11# License, or (at your option) any later version.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16# GNU General Public License for more details.
17#
18# You should have received a copy of the GNU General Public License
19# along with this program; if not, write to the Free Software
20# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
21# USA
22
23
24from __future__ import print_function
25
26import dbus
27import sys
28
29class ModemManagerHelper(object):
30
31 # data taken from
32 # http://projects.gnome.org/NetworkManager/developers/mm-spec-04.html
33 MM_DBUS_IFACE = "org.freedesktop.ModemManager"
34 MM_DBUS_IFACE_MODEM = MM_DBUS_IFACE + ".Modem"
35
36 # MM_MODEM_TYPE
37 MM_MODEM_TYPE_GSM = 1
38 MM_MODEM_TYPE_CDMA = 2
39
40 # GSM
41 # Not registered, not searching for new operator to register.
42 MM_MODEM_GSM_NETWORK_REG_STATUS_IDLE = 0
43 # Registered on home network.
44 MM_MODEM_GSM_NETWORK_REG_STATUS_HOME = 1
45 # Not registered, searching for new operator to register with.
46 MM_MODEM_GSM_NETWORK_REG_STATUS_SEARCHING = 2
47 # Registration denied.
48 MM_MODEM_GSM_NETWORK_REG_STATUS_DENIED = 3
49 # Unknown registration status.
50 MM_MODEM_GSM_NETWORK_REG_STATUS_UNKNOWN = 4
51 # Registered on a roaming network.
52 MM_MODEM_GSM_NETWORK_REG_STATUS_ROAMING = 5
53
54 # CDMA
55 # Registration status is unknown or the device is not registered.
56 MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN = 0
57 # Registered, but roaming status is unknown or cannot be provided
58 # by the device. The device may or may not be roaming.
59 MM_MODEM_CDMA_REGISTRATION_STATE_REGISTERED = 1
60 # Currently registered on the home network.
61 MM_MODEM_CDMA_REGISTRATION_STATE_HOME = 2
62 # Currently registered on a roaming network.
63 MM_MODEM_CDMA_REGISTRATION_STATE_ROAMING = 3
64
65 def __init__(self):
66 self.bus = dbus.SystemBus()
67 self.proxy = self.bus.get_object("org.freedesktop.ModemManager",
68 "/org/freedesktop/ModemManager")
69 modem_manager = dbus.Interface(self.proxy, self.MM_DBUS_IFACE)
70 self.modems = modem_manager.EnumerateDevices()
71
72 @staticmethod
73 def get_dbus_property(proxy, interface, property):
74 props = dbus.Interface(proxy, "org.freedesktop.DBus.Properties")
75 property = props.Get(interface, property)
76 return property
77
78 def is_gsm_roaming(self):
79 for m in self.modems:
80 dev = self.bus.get_object(self.MM_DBUS_IFACE, m)
81 type = self.get_dbus_property(dev, self.MM_DBUS_IFACE_MODEM, "Type")
82 if type != self.MM_MODEM_TYPE_GSM:
83 continue
84 net = dbus.Interface(dev, self.MM_DBUS_IFACE_MODEM + ".Gsm.Network")
85 reg = net.GetRegistrationInfo()
86 # Be conservative about roaming. If registration unknown,
87 # assume yes.
88 # MM_MODEM_GSM_NETWORK_REG_STATUS
89 if reg[0] in (self.MM_MODEM_GSM_NETWORK_REG_STATUS_UNKNOWN,
90 self.MM_MODEM_GSM_NETWORK_REG_STATUS_ROAMING):
91 return True
92 return False
93
94 def is_cdma_roaming(self):
95 for m in self.modems:
96 dev = self.bus.get_object(self.MM_DBUS_IFACE, m)
97 type = self.get_dbus_property(dev, self.MM_DBUS_IFACE_MODEM, "Type")
98 if type != self.MM_MODEM_TYPE_CDMA:
99 continue
100 cdma = dbus.Interface(dev, self.MM_DBUS_IFACE_MODEM + ".Cdma")
101 (cmda_1x, evdo) = cdma.GetRegistrationState()
102 # Be conservative about roaming. If registration unknown,
103 # assume yes.
104 # MM_MODEM_CDMA_REGISTRATION_STATE
105 roaming_states = (self.MM_MODEM_CDMA_REGISTRATION_STATE_REGISTERED,
106 self.MM_MODEM_CDMA_REGISTRATION_STATE_ROAMING)
107 # evdo trumps cmda_1x (thanks to Mathieu Trudel-Lapierre)
108 if evdo in roaming_states:
109 return True
110 elif cmda_1x in roaming_states:
111 return True
112 return False
113
114class NetworkManagerHelper(object):
115 NM_DBUS_IFACE = "org.freedesktop.NetworkManager"
116
117 # connection states
118 # Old enum values are for NM 0.7
119
120 # The NetworkManager daemon is in an unknown state.
121 NM_STATE_UNKNOWN = 0
122 # The NetworkManager daemon is connecting a device.
123 NM_STATE_CONNECTING_OLD = 2
124 NM_STATE_CONNECTING = 40
125 NM_STATE_CONNECTING_LIST = [NM_STATE_CONNECTING_OLD,
126 NM_STATE_CONNECTING]
127 # The NetworkManager daemon is connected.
128 NM_STATE_CONNECTED_OLD = 3
129 NM_STATE_CONNECTED_LOCAL = 50
130 NM_STATE_CONNECTED_SITE = 60
131 NM_STATE_CONNECTED_GLOBAL = 70
132 NM_STATE_CONNECTED_LIST = [NM_STATE_CONNECTED_OLD,
133 NM_STATE_CONNECTED_LOCAL,
134 NM_STATE_CONNECTED_SITE,
135 NM_STATE_CONNECTED_GLOBAL]
136
137 # The device type is unknown.
138 NM_DEVICE_TYPE_UNKNOWN = 0
139 # The device is wired Ethernet device.
140 NM_DEVICE_TYPE_ETHERNET = 1
141 # The device is an 802.11 WiFi device.
142 NM_DEVICE_TYPE_WIFI = 2
143 # The device is a GSM-based cellular WAN device.
144 NM_DEVICE_TYPE_GSM = 3
145 # The device is a CDMA/IS-95-based cellular WAN device.
146 NM_DEVICE_TYPE_CDMA = 4
147
148 def __init__(self):
149 self.bus = dbus.SystemBus()
150 self.proxy = self.bus.get_object("org.freedesktop.NetworkManager",
151 "/org/freedesktop/NetworkManager")
152
153 @staticmethod
154 def get_dbus_property(proxy, interface, property):
155 props = dbus.Interface(proxy, "org.freedesktop.DBus.Properties")
156 property = props.Get(interface, property)
157 return property
158
159 def is_active_connection_gsm_or_cdma(self):
160 res = False
161 actives = self.get_dbus_property(
162 self.proxy, self.NM_DBUS_IFACE, 'ActiveConnections')
163 for a in actives:
164 active = self.bus.get_object(self.NM_DBUS_IFACE, a)
165 default_route = self.get_dbus_property(
166 active, self.NM_DBUS_IFACE + ".Connection.Active", 'Default')
167 if not default_route:
168 continue
169 devs = self.get_dbus_property(
170 active, self.NM_DBUS_IFACE + ".Connection.Active", 'Devices')
171 for d in devs:
172 dev = self.bus.get_object(self.NM_DBUS_IFACE, d)
173 type = self.get_dbus_property(
174 dev, self.NM_DBUS_IFACE + ".Device", 'DeviceType')
175 if type == self.NM_DEVICE_TYPE_GSM:
176 return True
177 elif type == self.NM_DEVICE_TYPE_CDMA:
178 return True
179 else:
180 continue
181 return res
182
183 def is_active_connection_gsm_or_cdma_roaming(self):
184 res = False
185 if self.is_active_connection_gsm_or_cdma():
186 mmhelper = ModemManagerHelper()
187 res |= mmhelper.is_gsm_roaming()
188 res |= mmhelper.is_cdma_roaming()
189 return res
190
191if __name__ == "__main__":
192
193 # test code
194 if sys.argv[1:] and sys.argv[1] == "--test":
195 mmhelper = ModemManagerHelper()
196 print("is_gsm_roaming", mmhelper.is_gsm_roaming())
197 print("is_cdma_romaing", mmhelper.is_cdma_roaming())
198
199 # roaming?
200 nmhelper = NetworkManagerHelper()
201 is_roaming = nmhelper.is_active_connection_gsm_or_cdma_roaming()
202 print("roam: ", is_roaming)
203 if is_roaming:
204 sys.exit(1)
205 sys.exit(0)
2060
=== removed file 'UpdateManager/Core/utils.py'
--- UpdateManager/Core/utils.py 2012-06-15 20:13:15 +0000
+++ UpdateManager/Core/utils.py 1970-01-01 00:00:00 +0000
@@ -1,510 +0,0 @@
1# utils.py
2#
3# Copyright (c) 2004-2008 Canonical
4#
5# Author: Michael Vogt <mvo@debian.org>
6#
7# This program is free software; you can redistribute it and/or
8# modify it under the terms of the GNU General Public License as
9# published by the Free Software Foundation; either version 2 of the
10# License, or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program; if not, write to the Free Software
19# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20# USA
21
22from __future__ import print_function
23
24from gettext import gettext as _
25from gettext import ngettext
26from stat import (S_IMODE, ST_MODE, S_IXUSR)
27from math import ceil
28
29import apt_pkg
30apt_pkg.init_config()
31
32import locale
33import logging
34import re
35import os
36import glob
37import subprocess
38import sys
39import time
40try:
41 from urllib.request import (
42 ProxyHandler,
43 Request,
44 build_opener,
45 install_opener,
46 urlopen,
47 )
48 from urllib.parse import urlsplit
49except ImportError:
50 from urllib2 import (
51 ProxyHandler,
52 Request,
53 build_opener,
54 install_opener,
55 urlopen,
56 )
57 from urlparse import urlsplit
58
59from copy import copy
60
61
62class ExecutionTime(object):
63 """
64 Helper that can be used in with statements to have a simple
65 measure of the timing of a particular block of code, e.g.
66 with ExecutionTime("db flush"):
67 db.flush()
68 """
69 def __init__(self, info=""):
70 self.info = info
71 def __enter__(self):
72 self.now = time.time()
73 def __exit__(self, type, value, stack):
74 print("%s: %s" % (self.info, time.time() - self.now))
75
76def get_string_with_no_auth_from_source_entry(entry):
77 tmp = copy(entry)
78 url_parts = urlsplit(tmp.uri)
79 if url_parts.username:
80 tmp.uri = tmp.uri.replace(url_parts.username, "hidden-u")
81 if url_parts.password:
82 tmp.uri = tmp.uri.replace(url_parts.password, "hidden-p")
83 return str(tmp)
84
85def estimate_kernel_size_in_boot():
86 """ estimate the amount of space that the current kernel takes in /boot """
87 size = 0
88 kver = os.uname()[2]
89 for f in glob.glob("/boot/*%s*" % kver):
90 size += os.path.getsize(f)
91 return size
92
93def is_unity_running():
94 """ return True if Unity is currently running """
95 unity_running = False
96 try:
97 import dbus
98 bus = dbus.SessionBus()
99 unity_running = bus.name_has_owner("com.canonical.Unity")
100 except:
101 logging.exception("could not check for Unity dbus service")
102 return unity_running
103
104def is_child_of_process_name(processname, pid=None):
105 if not pid:
106 pid = os.getpid()
107 while pid > 0:
108 stat_file = "/proc/%s/stat" % pid
109 with open(stat_file) as stat_f:
110 stat = stat_f.read()
111 # extract command (inside ())
112 command = stat.partition("(")[2].partition(")")[0]
113 if command == processname:
114 return True
115 # get parent (second to the right of command) and check that next
116 pid = int(stat.partition(")")[2].split()[1])
117 return False
118
119def inside_chroot():
120 """ returns True if we are inside a chroot
121 """
122 # if there is no proc or no pid 1 we are very likely inside a chroot
123 if not os.path.exists("/proc") or not os.path.exists("/proc/1"):
124 return True
125 # if the inode is differnt for pid 1 "/" and our "/"
126 return os.stat("/") != os.stat("/proc/1/root")
127
128def wrap(t, width=70, subsequent_indent=""):
129 """ helpers inspired after textwrap - unfortunately
130 we can not use textwrap directly because it break
131 packagenames with "-" in them into new lines
132 """
133 out = ""
134 for s in t.split():
135 if (len(out)-out.rfind("\n")) + len(s) > width:
136 out += "\n" + subsequent_indent
137 out += s + " "
138 return out
139
140def twrap(s, **kwargs):
141 msg = ""
142 paras = s.split("\n")
143 for par in paras:
144 s = wrap(par, **kwargs)
145 msg += s+"\n"
146 return msg
147
148def lsmod():
149 " return list of loaded modules (or [] if lsmod is not found) "
150 modules=[]
151 # FIXME raise?
152 if not os.path.exists("/sbin/lsmod"):
153 return []
154 p=subprocess.Popen(["/sbin/lsmod"], stdout=subprocess.PIPE,
155 universal_newlines=True)
156 lines=p.communicate()[0].split("\n")
157 # remove heading line: "Modules Size Used by"
158 del lines[0]
159 # add lines to list, skip empty lines
160 for line in lines:
161 if line:
162 modules.append(line.split()[0])
163 return modules
164
165def check_and_fix_xbit(path):
166 " check if a given binary has the executable bit and if not, add it"
167 if not os.path.exists(path):
168 return
169 mode = S_IMODE(os.stat(path)[ST_MODE])
170 if not ((mode & S_IXUSR) == S_IXUSR):
171 os.chmod(path, mode | S_IXUSR)
172
173def country_mirror():
174 " helper to get the country mirror from the current locale "
175 # special cases go here
176 lang_mirror = { 'c' : '',
177 }
178 # no lang, no mirror
179 if not 'LANG' in os.environ:
180 return ''
181 lang = os.environ['LANG'].lower()
182 # check if it is a special case
183 if lang[:5] in lang_mirror:
184 return lang_mirror[lang[:5]]
185 # now check for the most comon form (en_US.UTF-8)
186 if "_" in lang:
187 country = lang.split(".")[0].split("_")[1]
188 if "@" in country:
189 country = country.split("@")[0]
190 return country+"."
191 else:
192 return lang[:2]+"."
193 return ''
194
195def get_dist():
196 " return the codename of the current runing distro "
197 # support debug overwrite
198 dist = os.environ.get("META_RELEASE_FAKE_CODENAME")
199 if dist:
200 logging.warn("using fake release name '%s' (because of META_RELEASE_FAKE_CODENAME environment) " % dist)
201 return dist
202 # then check the real one
203 from subprocess import Popen, PIPE
204 p = Popen(["lsb_release","-c","-s"], stdout=PIPE, universal_newlines=True)
205 res = p.wait()
206 if res != 0:
207 sys.stderr.write("lsb_release returned exitcode: %i\n" % res)
208 return "unknown distribution"
209 dist = p.stdout.readline().strip()
210 p.stdout.close()
211 return dist
212
213def get_dist_version():
214 " return the version of the current running distro "
215 # support debug overwrite
216 desc = os.environ.get("META_RELEASE_FAKE_VERSION")
217 if desc:
218 logging.warn("using fake release version '%s' (because of META_RELEASE_FAKE_VERSION environment) " % desc)
219 return desc
220 # then check the real one
221 from subprocess import Popen, PIPE
222 p = Popen(["lsb_release","-r","-s"], stdout=PIPE, universal_newlines=True)
223 res = p.wait()
224 if res != 0:
225 sys.stderr.write("lsb_release returned exitcode: %i\n" % res)
226 return "unknown distribution"
227 desc = p.stdout.readline().strip()
228 p.stdout.close()
229 return desc
230
231class HeadRequest(Request):
232 def get_method(self):
233 return "HEAD"
234
235def url_downloadable(uri, debug_func=None):
236 """
237 helper that checks if the given uri exists and is downloadable
238 (supports optional debug_func function handler to support
239 e.g. logging)
240
241 Supports http (via HEAD) and ftp (via size request)
242 """
243 if not debug_func:
244 lambda x: True
245 debug_func("url_downloadable: %s" % uri)
246 (scheme, netloc, path, querry, fragment) = urlsplit(uri)
247 debug_func("s='%s' n='%s' p='%s' q='%s' f='%s'" % (scheme, netloc, path, querry, fragment))
248 if scheme == "http":
249 try:
250 http_file = urlopen(HeadRequest(uri))
251 http_file.close()
252 if http_file.code == 200:
253 return True
254 return False
255 except Exception as e:
256 debug_func("error from httplib: '%s'" % e)
257 return False
258 elif scheme == "ftp":
259 import ftplib
260 try:
261 f = ftplib.FTP(netloc)
262 f.login()
263 f.cwd(os.path.dirname(path))
264 size = f.size(os.path.basename(path))
265 f.quit()
266 if debug_func:
267 debug_func("ftplib.size() returned: %s" % size)
268 if size != 0:
269 return True
270 except Exception as e:
271 if debug_func:
272 debug_func("error from ftplib: '%s'" % e)
273 return False
274 return False
275
276def init_proxy(gsettings=None):
277 """ init proxy settings
278
279 * first check for http_proxy environment (always wins),
280 * then check the apt.conf http proxy,
281 * then look into synaptics conffile
282 * then into gconf (if gconfclient was supplied)
283 """
284 SYNAPTIC_CONF_FILE = "/root/.synaptic/synaptic.conf"
285 proxy = None
286 # generic apt config wins
287 if apt_pkg.config.find("Acquire::http::Proxy") != '':
288 proxy = apt_pkg.config.find("Acquire::http::Proxy")
289 # then synaptic
290 elif os.path.exists(SYNAPTIC_CONF_FILE):
291 cnf = apt_pkg.Configuration()
292 apt_pkg.read_config_file(cnf, SYNAPTIC_CONF_FILE)
293 use_proxy = cnf.find_b("Synaptic::useProxy", False)
294 if use_proxy:
295 proxy_host = cnf.find("Synaptic::httpProxy")
296 proxy_port = str(cnf.find_i("Synaptic::httpProxyPort"))
297 if proxy_host and proxy_port:
298 proxy = "http://%s:%s/" % (proxy_host, proxy_port)
299 # gconf is no more
300 # elif gconfclient:
301 # try: # see LP: #281248
302 # if gconfclient.get_bool("/system/http_proxy/use_http_proxy"):
303 # host = gconfclient.get_string("/system/http_proxy/host")
304 # port = gconfclient.get_int("/system/http_proxy/port")
305 # use_auth = gconfclient.get_bool("/system/http_proxy/use_authentication")
306 # if host and port:
307 # if use_auth:
308 # auth_user = gconfclient.get_string("/system/http_proxy/authentication_user")
309 # auth_pw = gconfclient.get_string("/system/http_proxy/authentication_password")
310 # proxy = "http://%s:%s@%s:%s/" % (auth_user,auth_pw,host, port)
311 # else:
312 # proxy = "http://%s:%s/" % (host, port)
313 # except Exception as e:
314 # print("error from gconf: %s" % e)
315 # if we have a proxy, set it
316 if proxy:
317 # basic verification
318 if not re.match("http://\w+", proxy):
319 print("proxy '%s' looks invalid" % proxy, file=sys.stderr)
320 return
321 proxy_support = ProxyHandler({"http":proxy})
322 opener = build_opener(proxy_support)
323 install_opener(opener)
324 os.putenv("http_proxy",proxy)
325 return proxy
326
327def on_battery():
328 """
329 Check via dbus if the system is running on battery.
330 This function is using UPower per default, if UPower is not
331 available it falls-back to DeviceKit.Power.
332 """
333 try:
334 import dbus
335 bus = dbus.Bus(dbus.Bus.TYPE_SYSTEM)
336 try:
337 devobj = bus.get_object('org.freedesktop.UPower',
338 '/org/freedesktop/UPower')
339 dev = dbus.Interface(devobj, 'org.freedesktop.DBus.Properties')
340 return dev.Get('org.freedesktop.UPower', 'OnBattery')
341 except dbus.exceptions.DBusException as e:
342 if e._dbus_error_name != 'org.freedesktop.DBus.Error.ServiceUnknown':
343 raise
344 devobj = bus.get_object('org.freedesktop.DeviceKit.Power',
345 '/org/freedesktop/DeviceKit/Power')
346 dev = dbus.Interface(devobj, "org.freedesktop.DBus.Properties")
347 return dev.Get("org.freedesktop.DeviceKit.Power", "on_battery")
348 except Exception as e:
349 #import sys
350 #print("on_battery returned error: ", e, file=sys.stderr)
351 return False
352
353def inhibit_sleep():
354 """
355 Send a dbus signal to power-manager to not suspend
356 the system, using the freedesktop common interface
357 """
358 try:
359 import dbus
360 bus = dbus.Bus(dbus.Bus.TYPE_SESSION)
361 devobj = bus.get_object('org.freedesktop.PowerManagement',
362 '/org/freedesktop/PowerManagement/Inhibit')
363 dev = dbus.Interface(devobj, "org.freedesktop.PowerManagement.Inhibit")
364 cookie = dev.Inhibit('UpdateManager', 'Updating system')
365 return (dev, cookie)
366 except Exception:
367 #print("could not send the dbus Inhibit signal: %s" % e)
368 return (False, False)
369
370def allow_sleep(dev, cookie):
371 """Send a dbus signal to gnome-power-manager to allow a suspending
372 the system"""
373 try:
374 dev.UnInhibit(cookie)
375 except Exception as e:
376 print("could not send the dbus UnInhibit signal: %s" % e)
377
378
379def str_to_bool(str):
380 if str == "0" or str.upper() == "FALSE":
381 return False
382 return True
383
384def get_lang():
385 import logging
386 try:
387 (locale_s, encoding) = locale.getdefaultlocale()
388 return locale_s
389 except Exception:
390 logging.exception("gedefaultlocale() failed")
391 return None
392
393def get_ubuntu_flavor():
394 """ try to guess the flavor based on the running desktop """
395 # this will (of course) not work in a server environment,
396 # but the main use case for this is to show the right
397 # release notes
398 # TODO: actually examine which meta packages are installed, like
399 # DistUpgrade/DistUpgradeCache.py does and use that to choose a flavor.
400 denv = os.environ.get("DESKTOP_SESSION", "")
401 if "gnome" in denv:
402 return "ubuntu"
403 elif "kde" in denv:
404 return "kubuntu"
405 elif "xfce" in denv or "xubuntu" in denv:
406 return "xubuntu"
407 elif "LXDE" in denv or "Lubuntu" in denv:
408 return "lubuntu"
409 # default to ubuntu if nothing more specific is found
410 return "ubuntu"
411
412def get_ubuntu_flavor_name():
413 flavor = get_ubuntu_flavor()
414 if flavor == "kubuntu":
415 return "Kubuntu"
416 elif flavor == "xubuntu":
417 return "Xubuntu"
418 elif flavor == "lubuntu":
419 return "Lubuntu"
420 else:
421 return "Ubuntu"
422
423def error(parent, summary, message):
424 from gi.repository import Gtk, Gdk
425 d = Gtk.MessageDialog(parent=parent,
426 flags=Gtk.DialogFlags.MODAL,
427 type=Gtk.MessageType.ERROR,
428 buttons=Gtk.ButtonsType.CLOSE)
429 d.set_markup("<big><b>%s</b></big>\n\n%s" % (summary, message))
430 d.realize()
431 d.window.set_functions(Gdk.FUNC_MOVE)
432 d.set_title("")
433 d.run()
434 d.destroy()
435 return False
436
437def humanize_size(bytes):
438 """
439 Convert a given size in bytes to a nicer better readable unit
440 """
441
442 if bytes < 1000 * 1000:
443 # to have 0 for 0 bytes, 1 for 0-1000 bytes and for 1 and above round up
444 size_in_kb = int(ceil(bytes/float(1000)));
445 # TRANSLATORS: download size of small updates, e.g. "250 kB"
446 return ngettext("%(size).0f kB", "%(size).0f kB", size_in_kb) % { "size" : size_in_kb }
447 else:
448 # TRANSLATORS: download size of updates, e.g. "2.3 MB"
449 return locale.format_string(_("%.1f MB"), bytes / 1000.0 / 1000.0)
450
451def get_arch():
452 return apt_pkg.config.find("APT::Architecture")
453
454
455def is_port_already_listening(port):
456 """ check if the current system is listening on the given tcp port """
457 # index in the line
458 INDEX_LOCAL_ADDR = 1
459 #INDEX_REMOTE_ADDR = 2
460 INDEX_STATE = 3
461 # state (st) that we care about
462 STATE_LISTENING = '0A'
463 # read the data
464 with open("/proc/net/tcp") as net_tcp:
465 for line in net_tcp:
466 line = line.strip()
467 if not line:
468 continue
469 # split, values are:
470 # sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode
471 values = line.split()
472 state = values[INDEX_STATE]
473 if state != STATE_LISTENING:
474 continue
475 local_port_str = values[INDEX_LOCAL_ADDR].split(":")[1]
476 local_port = int(local_port_str, 16)
477 if local_port == port:
478 return True
479 return False
480
481
482def iptables_active():
483 """ Return True if iptables is active """
484 # FIXME: is there a better way?
485 iptables_empty="""Chain INPUT (policy ACCEPT)
486target prot opt source destination
487
488Chain FORWARD (policy ACCEPT)
489target prot opt source destination
490
491Chain OUTPUT (policy ACCEPT)
492target prot opt source destination
493"""
494 if os.getuid() != 0:
495 raise OSError("Need root to check the iptables state")
496 if not os.path.exists("/sbin/iptables"):
497 return False
498 out = subprocess.Popen(["iptables", "-L"],
499 stdout=subprocess.PIPE,
500 universal_newlines=True).communicate()[0]
501 if out == iptables_empty:
502 return False
503 return True
504
505
506if __name__ == "__main__":
507 #print(mirror_from_sources_list())
508 #print(on_battery())
509 #print(inside_chroot())
510 print(iptables_active())
5110
=== removed file 'UpdateManager/Dialogs.py'
--- UpdateManager/Dialogs.py 2012-06-27 13:39:33 +0000
+++ UpdateManager/Dialogs.py 1970-01-01 00:00:00 +0000
@@ -1,235 +0,0 @@
1# Dialogs.py
2# -*- coding: utf-8 -*-
3#
4# Copyright (c) 2012 Canonical
5#
6# Author: Michael Terry <michael.terry@canonical.com>
7#
8# This program is free software; you can redistribute it and/or
9# modify it under the terms of the GNU General Public License as
10# published by the Free Software Foundation; either version 2 of the
11# License, or (at your option) any later version.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16# GNU General Public License for more details.
17#
18# You should have received a copy of the GNU General Public License
19# along with this program; if not, write to the Free Software
20# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
21# USA
22
23from __future__ import absolute_import, print_function
24
25from gi.repository import Gtk
26from gi.repository import GObject
27GObject.threads_init()
28
29import warnings
30warnings.filterwarnings("ignore", "Accessed deprecated property", DeprecationWarning)
31
32import dbus
33import os
34import subprocess
35import sys
36import time
37from .SimpleGtk3builderApp import SimpleGtkbuilderApp
38from .DistUpgradeFetcher import DistUpgradeFetcherGtk
39from .GtkProgress import GtkAcquireProgress
40
41from gettext import gettext as _
42
43class Dialog(SimpleGtkbuilderApp):
44 def __init__(self, window_main):
45 self.window_main = window_main
46 self.focus_button = None
47 SimpleGtkbuilderApp.__init__(self, self.window_main.datadir+"/gtkbuilder/Dialog.ui",
48 "update-manager")
49
50 def main(self):
51 self.window_main.push(self.pane_dialog, self)
52 if self.focus_button:
53 self.focus_button.grab_focus()
54
55 def run(self, parent=None):
56 if self.focus_button:
57 self.focus_button.grab_focus()
58 if parent:
59 self.window_dialog.set_transient_for(parent)
60 self.window_dialog.set_modal(True)
61 self.window_dialog.run()
62
63 def close(self):
64 sys.exit(0) # By default, exit the app
65
66 def add_button(self, label, callback, secondary=False):
67 # from_stock tries stock first and falls back to mnemonic
68 button = Gtk.Button.new_from_stock(label)
69 button.connect("clicked", lambda x: callback())
70 button.show()
71 self.buttonbox.add(button)
72 self.buttonbox.set_child_secondary(button, secondary)
73 return button
74
75 def add_settings_button(self):
76 if os.path.exists("/usr/bin/software-properties-gtk"):
77 return self.add_button(_("Settings…"), self.on_settings_button_clicked, secondary=True)
78 else:
79 return None
80
81 def on_settings_button_clicked(self):
82 cmd = ["/usr/bin/software-properties-gtk",
83 "--open-tab","2",
84 # FIXME: once get_xid() is available via introspections, add
85 # this back
86 #"--toplevel", "%s" % self.window_main.get_window().get_xid()
87 ]
88 self.window_main.set_sensitive(False)
89 p = subprocess.Popen(cmd)
90 while p.poll() is None:
91 while Gtk.events_pending():
92 Gtk.main_iteration()
93 time.sleep(0.05)
94 self.window_main.set_sensitive(True)
95
96 def set_header(self, label):
97 self.label_header.set_label(label)
98
99 def set_desc(self, label):
100 self.label_desc.set_label(label)
101 self.label_desc.set_visible(bool(label))
102
103
104class NoUpdatesDialog(Dialog):
105 def __init__(self, window_main):
106 Dialog.__init__(self, window_main)
107 self.set_header(_("The software on this computer is up to date."))
108 self.add_settings_button()
109 self.focus_button = self.add_button(Gtk.STOCK_OK, self.close)
110
111
112class DistUpgradeDialog(Dialog):
113 def __init__(self, window_main, meta_release):
114 Dialog.__init__(self, window_main)
115 self.meta_release = meta_release
116 self.set_header(_("The software on this computer is up to date."))
117 # Translators: these are Ubuntu version names like "Ubuntu 12.04"
118 self.set_desc(_("However, %s %s is now available (you have %s).") % (
119 meta_release.flavor_name,
120 meta_release.upgradable_to.version,
121 meta_release.current_dist_version))
122 self.add_settings_button()
123 self.add_button(_("Upgrade…"), self.upgrade)
124 self.focus_button = self.add_button(Gtk.STOCK_OK, self.close)
125
126 def upgrade(self):
127 progress = GtkAcquireProgress(self.window_main, self.window_main.datadir,
128 _("Downloading the release upgrade tool"))
129 fetcher = DistUpgradeFetcherGtk(new_dist=self.meta_release.upgradable_to,
130 parent=self.window_main,
131 progress=progress,
132 datadir=self.window_main.datadir)
133 if self.window_main.options.sandbox:
134 fetcher.run_options.append("--sandbox")
135 fetcher.run()
136
137
138class UnsupportedDialog(DistUpgradeDialog):
139 def __init__(self, window_main, meta_release):
140 DistUpgradeDialog.__init__(self, window_main, meta_release)
141 # Translators: this is an Ubuntu version name like "Ubuntu 12.04"
142 self.set_header(_("Software updates are no longer provided for %s %s.") % (
143 meta_release.flavor_name,
144 meta_release.current_dist_version))
145 # Translators: this is an Ubuntu version name like "Ubuntu 12.04"
146 self.set_desc(_("To stay secure, you should upgrade to %s %s.") % (
147 meta_release.flavor_name,
148 meta_release.upgradable_to.version))
149
150 def run(self, parent):
151 # This field is used in tests/test_end_of_life.py
152 self.window_main.no_longer_supported_nag = self.window_dialog
153 DistUpgradeDialog.run(self, parent)
154
155
156class PartialUpgradeDialog(Dialog):
157 def __init__(self, window_main):
158 Dialog.__init__(self, window_main)
159 self.set_header(_("Not all updates can be installed"))
160 self.set_desc(_("""Run a partial upgrade, to install as many updates as possible.
161
162This can be caused by:
163 * A previous upgrade which didn't complete
164 * Problems with some of the installed software
165 * Unofficial software packages not provided by Ubuntu
166 * Normal changes of a pre-release version of Ubuntu"""))
167 self.add_settings_button()
168 self.add_button(_("_Partial Upgrade"), self.upgrade)
169 self.focus_button = self.add_button(_("_Continue"), Gtk.main_quit)
170
171 def upgrade(self):
172 os.execl("/usr/bin/gksu",
173 "/usr/bin/gksu", "--desktop",
174 "/usr/share/applications/update-manager.desktop",
175 "--", "/usr/bin/update-manager", "--dist-upgrade")
176
177 def main(self):
178 Dialog.main(self)
179 # Block progress until user has answered this question
180 Gtk.main()
181
182
183class ErrorDialog(Dialog):
184 def __init__(self, window_main, header, desc=None):
185 Dialog.__init__(self, window_main)
186 self.set_header(header)
187 if desc:
188 self.set_desc(desc)
189 self.label_desc.set_selectable(True)
190 self.add_settings_button()
191 self.focus_button = self.add_button(Gtk.STOCK_OK, self.close)
192
193 def main(self):
194 Dialog.main(self)
195 # The label likes to start selecting everything (b/c it got focus before
196 # we switched to our default button).
197 self.label_desc.select_region(0, 0)
198 # Since errors usually are outside the normal flow, we'll guarantee that
199 # we don't continue with normal code flow by running our own loop here.
200 # We won't screw anything up because the only thing this dialog will do
201 # is exit.
202 Gtk.main()
203
204
205class NeedRestartDialog(Dialog):
206 def __init__(self, window_main):
207 Dialog.__init__(self, window_main)
208 self.set_header(_("The computer needs to restart to finish installing updates."))
209 self.focus_button = self.add_button(_("_Restart"), self.restart)
210
211 def restart(self, *args, **kwargs):
212 self._request_reboot_via_session_manager()
213
214 def _request_reboot_via_session_manager(self):
215 try:
216 bus = dbus.SessionBus()
217 proxy_obj = bus.get_object("org.gnome.SessionManager",
218 "/org/gnome/SessionManager")
219 iface = dbus.Interface(proxy_obj, "org.gnome.SessionManager")
220 iface.RequestReboot()
221 except dbus.DBusException:
222 self._request_reboot_via_consolekit()
223 except:
224 pass
225
226 def _request_reboot_via_consolekit(self):
227 try:
228 bus = dbus.SystemBus()
229 proxy_obj = bus.get_object("org.freedesktop.ConsoleKit",
230 "/org/freedesktop/ConsoleKit/Manager")
231 iface = dbus.Interface(proxy_obj, "org.freedesktop.ConsoleKit.Manager")
232 iface.Restart()
233 except dbus.DBusException:
234 pass
235
2360
=== removed file 'UpdateManager/DistUpgradeFetcher.py'
--- UpdateManager/DistUpgradeFetcher.py 2012-06-15 20:02:33 +0000
+++ UpdateManager/DistUpgradeFetcher.py 1970-01-01 00:00:00 +0000
@@ -1,143 +0,0 @@
1# DistUpgradeFetcher.py
2#
3# Copyright (c) 2006 Canonical
4#
5# Author: Michael Vogt <michael.vogt@ubuntu.com>
6#
7# This program is free software; you can redistribute it and/or
8# modify it under the terms of the GNU General Public License as
9# published by the Free Software Foundation; either version 2 of the
10# License, or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program; if not, write to the Free Software
19# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20# USA
21
22from __future__ import absolute_import, print_function
23
24from gi.repository import Gtk, Gdk
25
26from .ReleaseNotesViewer import ReleaseNotesViewer
27from .Core.utils import error, inhibit_sleep, allow_sleep
28from .Core.DistUpgradeFetcherCore import DistUpgradeFetcherCore
29from .SimpleGtk3builderApp import SimpleGtkbuilderApp
30from gettext import gettext as _
31try:
32 from urllib.request import urlopen
33 from urllib.error import HTTPError
34except ImportError:
35 from urllib2 import urlopen, HTTPError
36import os
37import socket
38
39
40class DistUpgradeFetcherGtk(DistUpgradeFetcherCore):
41
42 def __init__(self, new_dist, progress, parent, datadir):
43 DistUpgradeFetcherCore.__init__(self,new_dist,progress)
44 uifile = datadir + "gtkbuilder/ReleaseNotes.ui"
45 self.widgets = SimpleGtkbuilderApp(uifile, "update-manager")
46 self.window_main = parent
47
48 def error(self, summary, message):
49 return error(self.window_main, summary, message)
50
51 def runDistUpgrader(self):
52 inhibit_sleep()
53 # now run it with sudo
54 if os.getuid() != 0:
55 os.execv("/usr/bin/gksu",["gksu",
56 "--desktop","/usr/share/applications/update-manager.desktop",
57 "--",
58 self.script]+self.run_options)
59 else:
60 os.execv(self.script,[self.script]+self.run_options)
61 # we shouldn't come to this point, but if we do, undo our
62 # inhibit sleep
63 allow_sleep()
64
65 def showReleaseNotes(self):
66 # first try showing the webkit version, this may fail (return None
67 # because e.g. there is no webkit installed)
68 res = self._try_show_release_notes_webkit()
69 if res is not None:
70 return res
71 else:
72 # fallback to text
73 return self._try_show_release_notes_textview()
74
75 def _try_show_release_notes_webkit(self):
76 if self.new_dist.releaseNotesHtmlUri is not None:
77 try:
78 from .ReleaseNotesViewerWebkit import ReleaseNotesViewerWebkit
79 webkit_release_notes = ReleaseNotesViewerWebkit(self.new_dist.releaseNotesHtmlUri)
80 webkit_release_notes.show()
81 self.widgets.scrolled_notes.add(webkit_release_notes)
82 res = self.widgets.dialog_release_notes.run()
83 self.widgets.dialog_release_notes.hide()
84 if res == Gtk.ResponseType.OK:
85 return True
86 return False
87 except ImportError:
88 pass
89 return None
90
91 def _try_show_release_notes_textview(self):
92 # FIXME: care about i18n! (append -$lang or something)
93 if self.new_dist.releaseNotesURI != None:
94 uri = self._expandUri(self.new_dist.releaseNotesURI)
95 self.window_main.set_sensitive(False)
96 self.window_main.get_window().set_cursor(Gdk.Cursor.new(Gdk.CursorType.WATCH))
97 while Gtk.events_pending():
98 Gtk.main_iteration()
99
100 # download/display the release notes
101 # FIXME: add some progress reporting here
102 res = Gtk.ResponseType.CANCEL
103 timeout = socket.getdefaulttimeout()
104 try:
105 socket.setdefaulttimeout(5)
106 release_notes = urlopen(uri)
107 notes = release_notes.read().decode("UTF-8", "replace")
108 textview_release_notes = ReleaseNotesViewer(notes)
109 textview_release_notes.show()
110 self.widgets.scrolled_notes.add(textview_release_notes)
111 self.widgets.dialog_release_notes.set_transient_for(self.window_main)
112 res = self.widgets.dialog_release_notes.run()
113 self.widgets.dialog_release_notes.hide()
114 except HTTPError:
115 primary = "<span weight=\"bold\" size=\"larger\">%s</span>" % \
116 _("Could not find the release notes")
117 secondary = _("The server may be overloaded. ")
118 dialog = Gtk.MessageDialog(self.window_main,Gtk.DialogFlags.MODAL,
119 Gtk.MessageType.ERROR,Gtk.ButtonsType.CLOSE,"")
120 dialog.set_title("")
121 dialog.set_markup(primary);
122 dialog.format_secondary_text(secondary);
123 dialog.run()
124 dialog.destroy()
125 except IOError:
126 primary = "<span weight=\"bold\" size=\"larger\">%s</span>" % \
127 _("Could not download the release notes")
128 secondary = _("Please check your internet connection.")
129 dialog = Gtk.MessageDialog(self.window_main,Gtk.DialogFlags.MODAL,
130 Gtk.MessageType.ERROR,Gtk.ButtonsType.CLOSE,"")
131 dialog.set_title("")
132 dialog.set_markup(primary);
133 dialog.format_secondary_text(secondary);
134 dialog.run()
135 dialog.destroy()
136 socket.setdefaulttimeout(timeout)
137 self.window_main.set_sensitive(True)
138 self.window_main.get_window().set_cursor(None)
139 # user clicked cancel
140 if res == Gtk.ResponseType.OK:
141 return True
142 return False
143
1440
=== removed file 'UpdateManager/DistUpgradeFetcherKDE.py'
--- UpdateManager/DistUpgradeFetcherKDE.py 2012-06-12 01:40:26 +0000
+++ UpdateManager/DistUpgradeFetcherKDE.py 1970-01-01 00:00:00 +0000
@@ -1,188 +0,0 @@
1# DistUpgradeFetcherKDE.py
2#
3# Copyright (c) 2008 Canonical Ltd
4#
5# Author: Jonathan Riddell <jriddell@ubuntu.com>
6#
7# This program is free software; you can redistribute it and/or
8# modify it under the terms of the GNU General Public License as
9# published by the Free Software Foundation; either version 2 of the
10# License, or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19
20from __future__ import absolute_import
21
22from PyKDE4.kdecore import ki18n, KAboutData, KCmdLineOptions, KCmdLineArgs
23from PyKDE4.kdeui import KIcon, KMessageBox, KApplication, KStandardGuiItem
24from PyQt4.QtCore import QDir, QTimer
25from PyQt4.QtGui import QDialog, QDialogButtonBox
26from PyQt4 import uic
27
28import apt_pkg
29import sys
30
31from .Core.utils import inhibit_sleep, allow_sleep
32from .Core.DistUpgradeFetcherCore import DistUpgradeFetcherCore
33from gettext import gettext as _
34try:
35 from urllib.request import urlopen
36 from urllib.error import HTTPError
37except ImportError:
38 from urllib2 import urlopen, HTTPError
39import os
40
41from .Core.MetaRelease import MetaReleaseCore
42import time
43import apt
44
45class DistUpgradeFetcherKDE(DistUpgradeFetcherCore):
46 """A small application run by Adept to download, verify
47 and run the dist-upgrade tool"""
48
49 def __init__(self, useDevelopmentRelease=False, useProposed=False):
50 self.useDevelopmentRelease = useDevelopmentRelease
51 self.useProposed = useProposed
52 metaRelease = MetaReleaseCore(useDevelopmentRelease, useProposed)
53 while metaRelease.downloading:
54 time.sleep(0.2)
55 if metaRelease.new_dist is None and __name__ == "__main__":
56 sys.exit()
57 elif metaRelease.new_dist is None:
58 return
59
60 self.progressDialogue = QDialog()
61 if os.path.exists("fetch-progress.ui"):
62 self.APPDIR = QDir.currentPath()
63 else:
64 self.APPDIR = "/usr/share/update-manager"
65
66 uic.loadUi(self.APPDIR + "/fetch-progress.ui", self.progressDialogue)
67 self.progressDialogue.setWindowIcon(KIcon("system-software-update"))
68 self.progressDialogue.setWindowTitle(_("Upgrade"))
69 self.progress = KDEAcquireProgressAdapter(self.progressDialogue.installationProgress, self.progressDialogue.installingLabel, None)
70 DistUpgradeFetcherCore.__init__(self,metaRelease.new_dist,self.progress)
71
72 def error(self, summary, message):
73 KMessageBox.sorry(None, message, summary)
74
75 def runDistUpgrader(self):
76 inhibit_sleep()
77 # now run it with sudo
78 if os.getuid() != 0:
79 os.execv("/usr/bin/kdesudo",["kdesudo", self.script + " --frontend=DistUpgradeViewKDE"])
80 else:
81 os.execv(self.script,[self.script]+ ["--frontend=DistUpgradeViewKDE"] + self.run_options)
82 # we shouldn't come to this point, but if we do, undo our
83 # inhibit sleep
84 allow_sleep()
85
86 def showReleaseNotes(self):
87 # FIXME: care about i18n! (append -$lang or something)
88 self.dialogue = QDialog()
89 uic.loadUi(self.APPDIR + "/dialog_release_notes.ui", self.dialogue)
90 upgradeButton = self.dialogue.buttonBox.button(QDialogButtonBox.Ok)
91 upgradeButton.setText(_("Upgrade"))
92 upgradeButton.setIcon(KIcon("dialog-ok"))
93 cancelButton = self.dialogue.buttonBox.button(QDialogButtonBox.Cancel)
94 cancelButton.setIcon(KIcon("dialog-cancel"))
95 self.dialogue.setWindowTitle(_("Release Notes"))
96 self.dialogue.show()
97 if self.new_dist.releaseNotesURI != None:
98 uri = self._expandUri(self.new_dist.releaseNotesURI)
99 # download/display the release notes
100 # FIXME: add some progress reporting here
101 result = None
102 try:
103 release_notes = urlopen(uri)
104 notes = release_notes.read().decode("UTF-8", "replace")
105 self.dialogue.scrolled_notes.setText(notes)
106 result = self.dialogue.exec_()
107 except HTTPError:
108 primary = "<span weight=\"bold\" size=\"larger\">%s</span>" % \
109 _("Could not find the release notes")
110 secondary = _("The server may be overloaded. ")
111 KMessageBox.sorry(None, primary + "<br />" + secondary, "")
112 except IOError:
113 primary = "<span weight=\"bold\" size=\"larger\">%s</span>" % \
114 _("Could not download the release notes")
115 secondary = _("Please check your internet connection.")
116 KMessageBox.sorry(None, primary + "<br />" + secondary, "")
117 # user clicked cancel
118 if result == QDialog.Accepted:
119 self.progressDialogue.show()
120 return True
121 if __name__ == "__main__":
122 KApplication.kApplication().exit(1)
123 if self.useDevelopmentRelease or self.useProposed:
124 sys.exit() #FIXME why does KApplication.kApplication().exit() crash but this doesn't?
125 return False
126
127class KDEAcquireProgressAdapter(apt.progress.base.AcquireProgress):
128 def __init__(self,progress,label,parent):
129 self.progress = progress
130 self.label = label
131 self.parent = parent
132
133 def start(self):
134 self.label.setText(_("Downloading additional package files..."))
135 self.progress.setValue(0)
136
137 def stop(self):
138 pass
139
140 def pulse(self, owner):
141 apt.progress.base.AcquireProgress.pulse(self, owner)
142 self.progress.setValue((self.current_bytes + self.current_items) /
143 float(self.total_bytes + self.total_items))
144 current_item = self.current_items + 1
145 if current_item > self.total_items:
146 current_item = self.total_items
147 if self.current_cps > 0:
148 self.label.setText(_("Downloading additional package files...") + _("File %s of %s at %sB/s") % (self.current_items,self.total_items,apt_pkg.size_to_str(self.current_cps)))
149 else:
150 self.label.setText(_("Downloading additional package files...") + _("File %s of %s") % (self.current_items,self.total_items))
151 KApplication.kApplication().processEvents()
152 return True
153
154 def mediaChange(self, medium, drive):
155 msg = _("Please insert '%s' into the drive '%s'") % (medium,drive)
156 #change = QMessageBox.question(None, _("Media Change"), msg, QMessageBox.Ok, QMessageBox.Cancel)
157 change = KMessageBox.questionYesNo(None, _("Media Change"), _("Media Change") + "<br>" + msg, KStandardGuiItem.ok(), KStandardGuiItem.cancel())
158 if change == KMessageBox.Yes:
159 return True
160 return False
161
162if __name__ == "__main__":
163
164 appName = "dist-upgrade-fetcher"
165 catalog = ""
166 programName = ki18n ("Dist Upgrade Fetcher")
167 version = "0.3.4"
168 description = ki18n ("Dist Upgrade Fetcher")
169 license = KAboutData.License_GPL
170 copyright = ki18n ("(c) 2008 Canonical Ltd")
171 text = ki18n ("none")
172 homePage = "https://launchpad.net/update-manager"
173 bugEmail = ""
174
175 aboutData = KAboutData (appName, catalog, programName, version, description, license, copyright, text, homePage, bugEmail)
176
177 aboutData.addAuthor(ki18n("Jonathan Riddell"), ki18n("Author"))
178
179 options = KCmdLineOptions()
180
181 KCmdLineArgs.init (sys.argv, aboutData)
182 KCmdLineArgs.addCmdLineOptions(options)
183
184 app = KApplication()
185 fetcher = DistUpgradeFetcherKDE()
186 QTimer.singleShot(10, fetcher.run)
187
188 app.exec_()
1890
=== removed file 'UpdateManager/GtkProgress.py'
--- UpdateManager/GtkProgress.py 2012-06-15 20:24:05 +0000
+++ UpdateManager/GtkProgress.py 1970-01-01 00:00:00 +0000
@@ -1,89 +0,0 @@
1# GtkProgress.py
2#
3# Copyright (c) 2004,2005 Canonical
4#
5# Author: Michael Vogt <michael.vogt@ubuntu.com>
6#
7# This program is free software; you can redistribute it and/or
8# modify it under the terms of the GNU General Public License as
9# published by the Free Software Foundation; either version 2 of the
10# License, or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program; if not, write to the Free Software
19# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20# USA
21
22from __future__ import absolute_import, print_function
23
24from gi.repository import Gtk, Gdk
25import apt
26from gettext import gettext as _
27from .Core.utils import humanize_size
28from .SimpleGtk3builderApp import SimpleGtkbuilderApp
29
30class GtkAcquireProgress(apt.progress.base.AcquireProgress):
31 def __init__(self, parent, datadir, summary="", descr=""):
32 uifile = datadir + "gtkbuilder/AcquireProgress.ui"
33 self.widgets = SimpleGtkbuilderApp(uifile, "update-manager")
34 # if this is set to false the download will cancel
35 self._continue = True
36 # init vars here
37 # FIXME: find a more elegant way, this sucks
38 self.summary = self.widgets.label_fetch_summary
39 self.status = self.widgets.label_fetch_status
40 # we need to connect the signal manual here, it won't work
41 # from the main window auto-connect
42 self.widgets.button_fetch_cancel.connect(
43 "clicked", self.on_button_fetch_cancel_clicked)
44 self.progress = self.widgets.progressbar_fetch
45 self.window_fetch = self.widgets.window_fetch
46 self.window_fetch.set_transient_for(parent)
47 self.window_fetch.realize()
48 self.window_fetch.get_window().set_functions(Gdk.WMFunction.MOVE)
49 # set summary
50 if summary != "":
51 self.summary.set_markup("<big><b>%s</b></big> \n\n%s" %
52 (summary, descr))
53 def start(self):
54 self.progress.set_fraction(0)
55 self.window_fetch.show()
56 def stop(self):
57 self.window_fetch.hide()
58 def on_button_fetch_cancel_clicked(self, widget):
59 self._continue = False
60 def pulse(self, owner):
61 apt.progress.base.AcquireProgress.pulse(self, owner)
62 current_item = self.current_items + 1
63 if current_item > self.total_items:
64 current_item = self.total_items
65 if self.current_cps > 0:
66 status_text = (_("Downloading file %(current)li of %(total)li with "
67 "%(speed)s/s") % {"current" : current_item,
68 "total" : self.total_items,
69 "speed" : humanize_size(self.current_cps)})
70 else:
71 status_text = (_("Downloading file %(current)li of %(total)li") % \
72 {"current" : current_item,
73 "total" : self.total_items })
74 self.progress.set_fraction((self.current_bytes + self.current_items) /
75 float(self.total_bytes + self.total_items))
76 self.status.set_markup("<i>%s</i>" % status_text)
77 # TRANSLATORS: show the remaining time in a progress bar:
78 #if self.current_cps > 0:
79 # eta = ((self.total_bytes + self.current_bytes) / float(self.current_cps))
80 #else:
81 # eta = 0.0
82 #self.progress.set_text(_("About %s left" % (apt_pkg.TimeToStr(eta))))
83 # FIXME: show remaining time
84 self.progress.set_text("")
85
86 while Gtk.events_pending():
87 Gtk.main_iteration()
88 return self._continue
89
900
=== removed file 'UpdateManager/HelpViewer.py'
--- UpdateManager/HelpViewer.py 2012-05-28 11:11:59 +0000
+++ UpdateManager/HelpViewer.py 1970-01-01 00:00:00 +0000
@@ -1,33 +0,0 @@
1# helpviewer.py
2
3import os
4import subprocess
5
6# Hardcoded list of available help viewers
7# FIXME: khelpcenter support would be nice
8#KNOWN_VIEWERS = ["/usr/bin/yelp", "/usr/bin/khelpcenter"]
9KNOWN_VIEWERS = ["/usr/bin/yelp"]
10
11class HelpViewer:
12 def __init__(self, docu):
13 self.command = []
14 self.docu = docu
15 for viewer in KNOWN_VIEWERS:
16 if os.path.exists(viewer):
17 self.command = [viewer, "ghelp:%s" % docu]
18 break
19
20 def check(self):
21 """check if a viewer is available"""
22 if self.command == []:
23 return False
24 else:
25 return True
26
27 def run(self):
28 """open the documentation in the viewer"""
29 # avoid running the help viewer as root
30 if os.getuid() == 0 and 'SUDO_USER' in os.environ:
31 self.command = ['sudo', '-u', os.environ['SUDO_USER']] +\
32 self.command
33 subprocess.Popen(self.command)
340
=== removed file 'UpdateManager/InstallProgress.py'
--- UpdateManager/InstallProgress.py 2012-06-15 20:24:05 +0000
+++ UpdateManager/InstallProgress.py 1970-01-01 00:00:00 +0000
@@ -1,93 +0,0 @@
1# InstallProgress.py
2#
3# Copyright (c) 2004-2012 Canonical
4# 2004 Michiel Sikkes
5# 2005 Martin Willemoes Hansen
6# 2010 Mohamed Amine IL Idrissi
7#
8# Author: Michiel Sikkes <michiel@eyesopened.nl>
9# Michael Vogt <mvo@debian.org>
10# Martin Willemoes Hansen <mwh@sysrq.dk>
11# Mohamed Amine IL Idrissi <ilidrissiamine@gmail.com>
12# Alex Launi <alex.launi@canonical.com>
13# Michael Terry <michael.terry@canonical.com>
14#
15# This program is free software; you can redistribute it and/or
16# modify it under the terms of the GNU General Public License as
17# published by the Free Software Foundation; either version 2 of the
18# License, or (at your option) any later version.
19#
20# This program is distributed in the hope that it will be useful,
21# but WITHOUT ANY WARRANTY; without even the implied warranty of
22# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23# GNU General Public License for more details.
24#
25# You should have received a copy of the GNU General Public License
26# along with this program; if not, write to the Free Software
27# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
28# USA
29
30from __future__ import absolute_import, print_function
31
32import warnings
33warnings.filterwarnings("ignore", "Accessed deprecated property", DeprecationWarning)
34
35import os
36import sys
37
38from .backend import get_backend
39
40from .Core.utils import (inhibit_sleep,
41 allow_sleep)
42
43class InstallProgress(object):
44
45 def __init__(self, app):
46 self.window_main = app
47 self.datadir = app.datadir
48 self.options = app.options
49
50 # Used for inhibiting power management
51 self.sleep_cookie = None
52 self.sleep_dev = None
53
54 # get the install backend
55 self.install_backend = get_backend(self.datadir, self.window_main)
56 self.install_backend.connect("action-done", self._on_backend_done)
57
58 def invoke_manager(self):
59 # don't display apt-listchanges, we already showed the changelog
60 os.environ["APT_LISTCHANGES_FRONTEND"]="none"
61
62 # Do not suspend during the update process
63 (self.sleep_dev, self.sleep_cookie) = inhibit_sleep()
64
65 # If the progress dialog should be closed automatically afterwards
66 #settings = Gio.Settings("com.ubuntu.update-manager")
67 #close_on_done = settings.get_boolean("autoclose-install-window")
68 close_on_done = False # FIXME: confirm with mpt whether this should still be a setting
69
70 # Get the packages which should be installed and update
71 pkgs_install = []
72 pkgs_upgrade = []
73 for pkg in self.window_main.cache:
74 if pkg.marked_install:
75 pkgs_install.append(pkg.name)
76 elif pkg.marked_upgrade:
77 pkgs_upgrade.append(pkg.name)
78 self.install_backend.commit(pkgs_install, pkgs_upgrade, close_on_done)
79
80 def _on_backend_done(self, backend, action, authorized, success):
81 # Allow suspend after synaptic is finished
82 if self.sleep_cookie:
83 allow_sleep(self.sleep_dev, self.sleep_cookie)
84 self.sleep_cookie = self.sleep_dev = None
85
86 # Either launch main dialog and continue or quit altogether
87 if success:
88 self.window_main.start_available(allow_restart=True)
89 else:
90 sys.exit(0)
91
92 def main(self):
93 self.invoke_manager()
940
=== removed file 'UpdateManager/MetaReleaseGObject.py'
--- UpdateManager/MetaReleaseGObject.py 2012-06-15 17:36:46 +0000
+++ UpdateManager/MetaReleaseGObject.py 1970-01-01 00:00:00 +0000
@@ -1,57 +0,0 @@
1# Copyright (c) 2004-2007 Canonical
2#
3# Author: Michael Vogt <michael.vogt@ubuntu.com>
4#
5# This program is free software; you can redistribute it and/or
6# modify it under the terms of the GNU General Public License as
7# published by the Free Software Foundation; either version 2 of the
8# License, or (at your option) any later version.
9#
10# This program is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13# GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with this program; if not, write to the Free Software
17# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
18# USA
19
20from __future__ import absolute_import
21
22from gi.repository import GObject
23from .Core.MetaRelease import MetaReleaseCore
24
25class MetaRelease(MetaReleaseCore,GObject.GObject):
26
27 __gsignals__ = {
28 'new_dist_available' : (GObject.SignalFlags.RUN_LAST,
29 None,
30 (GObject.TYPE_PYOBJECT,)),
31 'dist_no_longer_supported' : (GObject.SignalFlags.RUN_LAST,
32 None,
33 ()),
34 'done_downloading' : (GObject.SignalFlags.RUN_LAST,
35 None,
36 ())
37 }
38
39 def __init__(self, useDevelopmentRelease=False, useProposed=False):
40 GObject.GObject.__init__(self)
41 MetaReleaseCore.__init__(self, useDevelopmentRelease, useProposed)
42 # in the gtk space to test if the download already finished
43 # this is needed because gtk is not thread-safe
44 GObject.timeout_add(1000, self.check)
45
46 def check(self):
47 # check if we have a metarelease_information file
48 if self.no_longer_supported is not None:
49 self.emit("dist_no_longer_supported")
50 if self.new_dist is not None:
51 self.emit("new_dist_available", self.new_dist)
52 if self.downloading:
53 return True
54 else:
55 self.emit("done_downloading")
56 return False
57
580
=== removed file 'UpdateManager/ReleaseNotesViewer.py'
--- UpdateManager/ReleaseNotesViewer.py 2012-06-11 16:17:31 +0000
+++ UpdateManager/ReleaseNotesViewer.py 1970-01-01 00:00:00 +0000
@@ -1,186 +0,0 @@
1# ReleaseNotesViewer.py
2#
3# Copyright (c) 2006 Sebastian Heinlein
4#
5# Author: Sebastian Heinlein <sebastian.heinlein@web.de>
6#
7# This modul provides an inheritance of the Gtk.TextView that is
8# aware of http URLs and allows to open them in a browser.
9# It is based on the pygtk-demo "hypertext".
10#
11# This program is free software; you can redistribute it and/or
12# modify it under the terms of the GNU General Public License as
13# published by the Free Software Foundation; either version 2 of the
14# License, or (at your option) any later version.
15#
16# This program is distributed in the hope that it will be useful,
17# but WITHOUT ANY WARRANTY; without even the implied warranty of
18# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19# GNU General Public License for more details.
20#
21# You should have received a copy of the GNU General Public License
22# along with this program; if not, write to the Free Software
23# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
24# USA
25
26from gi.repository import Pango
27from gi.repository import Gtk, GObject, Gdk
28import os
29import subprocess
30
31def open_url(url):
32 """Open the specified URL in a browser"""
33 # Find an appropiate browser
34 if os.path.exists("/usr/bin/xdg-open"):
35 command = ["xdg-open", url]
36 elif os.path.exists("/usr/bin/exo-open"):
37 command = ["exo-open", url]
38 elif os.path.exists('/usr/bin/gnome-open'):
39 command = ['gnome-open', url]
40 else:
41 command = ['x-www-browser', url]
42 # Avoid to run the browser as user root
43 if os.getuid() == 0 and 'SUDO_USER' in os.environ:
44 command = ['sudo', '-u', os.environ['SUDO_USER']] + command
45 subprocess.Popen(command)
46
47
48class ReleaseNotesViewer(Gtk.TextView):
49 def __init__(self, notes):
50 """Init the ReleaseNotesViewer as an Inheritance of the Gtk.TextView.
51 Load the notes into the buffer and make links clickable"""
52 # init the parent
53 GObject.GObject.__init__(self)
54 # global hovering over link state
55 self.hovering = False
56 self.first = True
57 # setup the buffer and signals
58 self.set_property("editable", False)
59 self.set_cursor_visible(False)
60 self.modify_font(Pango.FontDescription("monospace"))
61 self.buffer = Gtk.TextBuffer()
62 self.set_buffer(self.buffer)
63 self.buffer.set_text(notes)
64 self.connect("button-press-event", self.button_press_event)
65 self.connect("motion-notify-event", self.motion_notify_event)
66 self.connect("visibility-notify-event", self.visibility_notify_event)
67 # search for links in the notes and make them clickable
68 self.search_links()
69
70 def tag_link(self, start, end, url):
71 """Apply the tag that marks links to the specified buffer selection"""
72 tag = self.buffer.create_tag(None, foreground="blue",
73 underline=Pango.Underline.SINGLE)
74 tag.url = url
75 self.buffer.apply_tag(tag , start, end)
76
77 def search_links(self):
78 """Search for http URLs in the buffer and call the tag_link method
79 for each one to tag them as links"""
80 # start at the beginning of the buffer
81 iter = self.buffer.get_iter_at_offset(0)
82 while 1:
83 # search for the next URL in the buffer
84 ret = iter.forward_search("http://", Gtk.TextSearchFlags.VISIBLE_ONLY,
85 None)
86 # if we reach the end break the loop
87 if not ret:
88 break
89 # get the position of the protocol prefix
90 (match_start, match_end) = ret
91 match_tmp = match_end.copy()
92 while 1:
93 # extend the selection to the complete URL
94 if match_tmp.forward_char():
95 text = match_end.get_text(match_tmp)
96 if text in (" ", ")", "]", "\n", "\t"):
97 break
98 else:
99 break
100 match_end = match_tmp.copy()
101 # call the tagging method for the complete URL
102 url = match_start.get_text(match_end)
103 self.tag_link(match_start, match_end, url)
104 # set the starting point for the next search
105 iter = match_end
106
107 def button_press_event(self, text_view, event):
108 """callback for mouse click events"""
109 if event.button != 1:
110 return False
111
112 # try to get a selection
113 try:
114 (start, end) = self.buffer.get_selection_bounds()
115 except ValueError:
116 pass
117 else:
118 if start.get_offset() != end.get_offset():
119 return False
120
121 # get the iter at the mouse position
122 (x, y) = self.window_to_buffer_coords(Gtk.TextWindowType.WIDGET,
123 int(event.x), int(event.y))
124 iter = self.get_iter_at_location(x, y)
125
126 # call open_url if an URL is assigned to the iter
127 tags = iter.get_tags()
128 for tag in tags:
129 url = getattr(tag, "url", None)
130 if url != "":
131 open_url(url)
132 break
133
134 def motion_notify_event(self, text_view, event):
135 """callback for the mouse movement event, that calls the
136 check_hovering method with the mouse postition coordiantes"""
137 x, y = text_view.window_to_buffer_coords(Gtk.TextWindowType.WIDGET,
138 int(event.x), int(event.y))
139 self.check_hovering(x, y)
140 self.get_window(Gtk.TextWindowType.TEXT).get_pointer()
141 return False
142
143 def visibility_notify_event(self, text_view, event):
144 """callback if the widgets gets visible (e.g. moves to the foreground)
145 that calls the check_hovering method with the mouse position
146 coordinates"""
147 (screen, wx, wy, mod) = text_view.get_window(Gtk.TextWindowType.TEXT).get_pointer()
148 (bx, by) = text_view.window_to_buffer_coords(
149 Gtk.TextWindowType.WIDGET, wx, wy)
150 self.check_hovering(bx, by)
151 return False
152
153 def check_hovering(self, x, y):
154 """Check if the mouse is above a tagged link and if yes show
155 a hand cursor"""
156 _hovering = False
157 # get the iter at the mouse position
158 iter = self.get_iter_at_location(x, y)
159
160 # set _hovering if the iter has the tag "url"
161 tags = iter.get_tags()
162 for tag in tags:
163 url = getattr(tag, "url", None)
164 if url != "":
165 _hovering = True
166 break
167
168 # change the global hovering state
169 if _hovering != self.hovering or self.first == True:
170 self.first = False
171 self.hovering = _hovering
172 # Set the appropriate cursur icon
173 if self.hovering:
174 self.get_window(Gtk.TextWindowType.TEXT).\
175 set_cursor(Gdk.Cursor.new(Gdk.CursorType.HAND2))
176 else:
177 self.get_window(Gtk.TextWindowType.TEXT).\
178 set_cursor(Gdk.Cursor.new(Gdk.CursorType.LEFT_PTR))
179
180if __name__ == "__main__":
181 # some simple test code
182 win = Gtk.Window()
183 rv = ReleaseNotesViewer(open("../DistUpgrade/ReleaseAnnouncement").read())
184 win.add(rv)
185 win.show_all()
186 Gtk.main()
1870
=== removed file 'UpdateManager/ReleaseNotesViewerWebkit.py'
--- UpdateManager/ReleaseNotesViewerWebkit.py 2012-05-01 14:01:29 +0000
+++ UpdateManager/ReleaseNotesViewerWebkit.py 1970-01-01 00:00:00 +0000
@@ -1,54 +0,0 @@
1# ReleaseNotesViewer.py
2#
3# Copyright (c) 2011 Canonical
4#
5# Author: Michael Vogt <mvo@ubutnu.com>
6#
7# This modul provides an inheritance of the Gtk.TextView that is
8# aware of http URLs and allows to open them in a browser.
9# It is based on the pygtk-demo "hypertext".
10#
11# This program is free software; you can redistribute it and/or
12# modify it under the terms of the GNU General Public License as
13# published by the Free Software Foundation; either version 2 of the
14# License, or (at your option) any later version.
15#
16# This program is distributed in the hope that it will be useful,
17# but WITHOUT ANY WARRANTY; without even the implied warranty of
18# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19# GNU General Public License for more details.
20#
21# You should have received a copy of the GNU General Public License
22# along with this program; if not, write to the Free Software
23# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
24# USA
25
26from __future__ import absolute_import
27
28from gi.repository import Gtk
29from gi.repository import WebKit
30
31from .ReleaseNotesViewer import open_url
32
33class ReleaseNotesViewerWebkit(WebKit.WebView):
34 def __init__(self, notes_url):
35 super(ReleaseNotesViewerWebkit, self).__init__()
36 self.load_uri(notes_url)
37 self.connect("navigation-policy-decision-requested", self._on_navigation_policy_decision_requested)
38 def _on_navigation_policy_decision_requested(self, view, frame, request, action, policy):
39 open_url(request.get_uri())
40 policy.ignore()
41 return True
42
43
44if __name__ == "__main__":
45 win = Gtk.Window()
46 win.set_size_request(600, 400)
47 scroll = Gtk.ScrolledWindow()
48 rv = ReleaseNotesViewerWebkit("http://archive.ubuntu.com/ubuntu/dists/natty/main/dist-upgrader-all/0.150/ReleaseAnnouncement.html")
49 scroll.add(rv)
50 win.add(scroll)
51 win.show_all()
52 Gtk.main()
53
54
550
=== removed file 'UpdateManager/SimpleGtk3builderApp.py'
--- UpdateManager/SimpleGtk3builderApp.py 2011-07-15 15:32:30 +0000
+++ UpdateManager/SimpleGtk3builderApp.py 1970-01-01 00:00:00 +0000
@@ -1,61 +0,0 @@
1"""
2 SimpleGladeApp.py
3 Module that provides an object oriented abstraction to pygtk and libglade.
4 Copyright (C) 2004 Sandino Flores Moreno
5"""
6
7# This library is free software; you can redistribute it and/or
8# modify it under the terms of the GNU Lesser General Public
9# License as published by the Free Software Foundation; either
10# version 2.1 of the License, or (at your option) any later version.
11#
12# This library is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15# Lesser General Public License for more details.
16#
17# You should have received a copy of the GNU Lesser General Public
18# License along with this library; if not, write to the Free Software
19# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20# USA
21
22import logging
23
24from gi.repository import Gtk
25
26# based on SimpleGladeApp
27class SimpleGtkbuilderApp:
28
29 def __init__(self, path, domain):
30 self.builder = Gtk.Builder()
31 self.builder.set_translation_domain(domain)
32 self.builder.add_from_file(path)
33 self.builder.connect_signals(self)
34 for o in self.builder.get_objects():
35 if issubclass(type(o), Gtk.Buildable):
36 name = Gtk.Buildable.get_name(o)
37 setattr(self, name, o)
38 else:
39 logging.debug("WARNING: can not get name for '%s'" % o)
40
41 def run(self):
42 """
43 Starts the main loop of processing events checking for Control-C.
44
45 The default implementation checks wheter a Control-C is pressed,
46 then calls on_keyboard_interrupt().
47
48 Use this method for starting programs.
49 """
50 try:
51 Gtk.main()
52 except KeyboardInterrupt:
53 self.on_keyboard_interrupt()
54
55 def on_keyboard_interrupt(self):
56 """
57 This method is called by the default implementation of run()
58 after a program is finished by pressing Control-C.
59 """
60 pass
61
620
=== removed file 'UpdateManager/SimpleGtkbuilderApp.py'
--- UpdateManager/SimpleGtkbuilderApp.py 2011-07-15 15:32:30 +0000
+++ UpdateManager/SimpleGtkbuilderApp.py 1970-01-01 00:00:00 +0000
@@ -1,61 +0,0 @@
1"""
2 SimpleGladeApp.py
3 Module that provides an object oriented abstraction to pygtk and libglade.
4 Copyright (C) 2004 Sandino Flores Moreno
5"""
6
7# This library is free software; you can redistribute it and/or
8# modify it under the terms of the GNU Lesser General Public
9# License as published by the Free Software Foundation; either
10# version 2.1 of the License, or (at your option) any later version.
11#
12# This library is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15# Lesser General Public License for more details.
16#
17# You should have received a copy of the GNU Lesser General Public
18# License along with this library; if not, write to the Free Software
19# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20# USA
21
22import logging
23
24import gtk
25
26# based on SimpleGladeApp
27class SimpleGtkbuilderApp:
28
29 def __init__(self, path, domain):
30 self.builder = gtk.Builder()
31 self.builder.set_translation_domain(domain)
32 self.builder.add_from_file(path)
33 self.builder.connect_signals(self)
34 for o in self.builder.get_objects():
35 if issubclass(type(o), gtk.Buildable):
36 name = gtk.Buildable.get_name(o)
37 setattr(self, name, o)
38 else:
39 logging.debug("WARNING: can not get name for '%s'" % o)
40
41 def run(self):
42 """
43 Starts the main loop of processing events checking for Control-C.
44
45 The default implementation checks wheter a Control-C is pressed,
46 then calls on_keyboard_interrupt().
47
48 Use this method for starting programs.
49 """
50 try:
51 gtk.main()
52 except KeyboardInterrupt:
53 self.on_keyboard_interrupt()
54
55 def on_keyboard_interrupt(self):
56 """
57 This method is called by the default implementation of run()
58 after a program is finished by pressing Control-C.
59 """
60 pass
61
620
=== removed file 'UpdateManager/UnitySupport.py'
--- UpdateManager/UnitySupport.py 2012-05-30 20:47:45 +0000
+++ UpdateManager/UnitySupport.py 1970-01-01 00:00:00 +0000
@@ -1,94 +0,0 @@
1# UnitySupport.py
2#
3# Copyright (c) 2011 Canonical
4#
5# Author: Michael Vogt <mvo@ubuntu.com>
6# Bilal Akhtar <bilalakhtar@ubuntu.com>
7#
8# This program is free software; you can redistribute it and/or
9# modify it under the terms of the GNU General Public License as
10# published by the Free Software Foundation; either version 2 of the
11# License, or (at your option) any later version.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16# GNU General Public License for more details.
17#
18# You should have received a copy of the GNU General Public License
19# along with this program; if not, write to the Free Software
20# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
21# USA
22
23import logging
24from gettext import gettext as _
25
26HAVE_UNITY_SUPPORT=False
27try:
28 from gi.repository import Dbusmenu, Unity
29 HAVE_UNITY_SUPPORT=True
30except ImportError as e:
31 logging.warn("can not import unity GI %s" % e)
32
33class IUnitySupport(object):
34 """ interface for unity support """
35 def __init__(self, parent=None): pass
36 def set_updates_count(self, num_updates): pass
37 def set_urgency(self, urgent): pass
38 def set_install_menuitem_visible(self, visible): pass
39 def set_progress(self, progress): pass
40
41class UnitySupportImpl(IUnitySupport):
42 """ implementation of unity support (if unity is available) """
43
44 def __init__(self, parent=None):
45 # create launcher and quicklist
46 um_launcher_entry = Unity.LauncherEntry.get_for_desktop_id(
47 "update-manager.desktop")
48 self._unity = um_launcher_entry
49 if parent:
50 self._add_quicklist(parent)
51
52 def _add_quicklist(self, parent):
53 quicklist = Dbusmenu.Menuitem.new()
54 # install
55 self.install_dbusmenuitem = Dbusmenu.Menuitem.new()
56 self.install_dbusmenuitem.property_set (Dbusmenu.MENUITEM_PROP_LABEL,
57 _("Install All Available Updates"))
58 self.install_dbusmenuitem.property_set_bool (Dbusmenu.MENUITEM_PROP_VISIBLE, True)
59 self.install_dbusmenuitem.connect (
60 "item-activated", parent.install_all_updates, None)
61 quicklist.child_append (self.install_dbusmenuitem)
62 # add it
63 self._unity.set_property ("quicklist", quicklist)
64
65 def set_progress(self, progress):
66 """ set the progress [0,100] """
67 self._unity.set_property("progress", progress/100.0)
68 # hide progress when out of bounds
69 if progress < 0 or progress > 100:
70 self._unity.set_property("progress_visible", False)
71 else:
72 self._unity.set_property("progress_visible", True)
73
74 def set_updates_count(self, num_updates):
75 self._unity.set_property("count", num_updates)
76 # FIXME: setup emblem as well(?)
77 if num_updates > 0:
78 self._unity.set_property("count-visible", True)
79 else:
80 self._unity.set_property("count-visible", False)
81
82 def set_urgency(self, urgent):
83 self._unity.set_property("urgent", urgent)
84
85 def set_install_menuitem_visible(self, visible):
86 self.install_dbusmenuitem.property_set_bool(Dbusmenu.MENUITEM_PROP_VISIBLE, visible)
87
88
89# check what to export to the clients
90if HAVE_UNITY_SUPPORT:
91 UnitySupport = UnitySupportImpl
92else:
93 # we just provide the empty interface
94 UnitySupport = IUnitySupport
950
=== removed file 'UpdateManager/UpdateManager.py'
--- UpdateManager/UpdateManager.py 2012-06-15 20:02:33 +0000
+++ UpdateManager/UpdateManager.py 1970-01-01 00:00:00 +0000
@@ -1,335 +0,0 @@
1# UpdateManager.py
2# -*- Mode: Python; indent-tabs-mode: nil; tab-width: 2; coding: utf-8 -*-
3#
4# Copyright (c) 2012 Canonical
5#
6# Author: Michael Terry <michael.terry@canonical.com>
7#
8# This program is free software; you can redistribute it and/or
9# modify it under the terms of the GNU General Public License as
10# published by the Free Software Foundation; either version 2 of the
11# License, or (at your option) any later version.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16# GNU General Public License for more details.
17#
18# You should have received a copy of the GNU General Public License
19# along with this program; if not, write to the Free Software
20# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
21# USA
22
23from __future__ import absolute_import, print_function
24
25from gi.repository import Gtk
26from gi.repository import Gdk
27from gi.repository import Gio
28from gi.repository import GLib
29
30import warnings
31warnings.filterwarnings("ignore", "Accessed deprecated property", DeprecationWarning)
32
33import apt_pkg
34import os
35import sys
36from gettext import gettext as _
37
38import dbus
39import dbus.service
40from dbus.mainloop.glib import DBusGMainLoop
41DBusGMainLoop(set_as_default=True)
42
43from .UnitySupport import UnitySupport
44from .Dialogs import (DistUpgradeDialog,
45 ErrorDialog,
46 NeedRestartDialog,
47 NoUpdatesDialog,
48 PartialUpgradeDialog,
49 UnsupportedDialog)
50from .InstallProgress import InstallProgress
51from .MetaReleaseGObject import MetaRelease
52from .UpdateProgress import UpdateProgress
53from .UpdatesAvailable import UpdatesAvailable
54from .Core.AlertWatcher import AlertWatcher
55from .Core.MyCache import MyCache
56from .Core.roam import NetworkManagerHelper
57from .Core.UpdateList import UpdateList
58
59# file that signals if we need to reboot
60REBOOT_REQUIRED_FILE = "/var/run/reboot-required"
61
62class UpdateManager(Gtk.Window):
63 """ This class is the main window and work flow controller. Panes will add
64 themselves to the main window and it will morph between them."""
65
66 def __init__(self, datadir, options):
67 Gtk.Window.__init__(self)
68
69 # Public members
70 self.datadir = datadir
71 self.options = options
72 self.unity = UnitySupport()
73 self.controller = None
74 self.cache = None
75 self.update_list = None
76 self.meta_release = None
77
78 # Basic GTK+ parameters
79 self.set_title(_("Software Updater"))
80 self.set_icon_name("system-software-update")
81 self.set_resizable(False)
82 self.set_position(Gtk.WindowPosition.CENTER)
83 self.set_size_request(500,-1)
84
85 # Signals
86 self.connect("delete-event", self.close)
87
88 self._setup_dbus()
89
90 # deal with no-focus-on-map
91 if self.options and self.options.no_focus_on_map:
92 self.set_focus_on_map(False)
93 self.iconify()
94 self.stick()
95 self.set_urgency_hint(True)
96 self.unity.set_urgency(True)
97 self.initial_focus_id = self.connect(
98 "focus-in-event", self.on_initial_focus_in)
99
100 # Look for a new release in a thread
101 self.meta_release = MetaRelease(self.options and self.options.devel_release,
102 self.options and self.options.use_proposed)
103
104
105 def on_initial_focus_in(self, widget, event):
106 """callback run on initial focus-in (if started unmapped)"""
107 self.unstick()
108 self.set_urgency_hint(False)
109 self.unity.set_urgency(False)
110 self.disconnect(self.initial_focus_id)
111 return False
112
113 def push(self, pane, controller):
114 child = self.get_child()
115 if child is not None:
116 if self.controller and hasattr(self.controller, "save_state"):
117 self.controller.save_state()
118 child.destroy()
119
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches