Merge lp:~ubuntu-core-dev/ubuntu-release-upgrader/split into lp:ubuntu-release-upgrader
- split
- Merge into trunk
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 |
Related bugs: |
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 |
Commit message
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-
* I re-enabled some tests that had been dormant (chmod +x)
* A couple apport-oriented Python bits pretend to be /usr/bin/
* I split packages into core/gtk/qt, matching what they were in update-manager, although the frontend packages are real tiny.
- 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
- 2461. By Michael Terry
-
merge from trunk again
- 2462. By Michael Terry
-
merge from trunk
Michael Terry (mterry) wrote : | # |
Updated to match latest update-manager trunk again.
Ken VanDine (ken-vandine) wrote : | # |
The symlinks to files included in python-
- 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
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_
Traceback (most recent call last):
File "./test_
from DistUpgrade.
ImportError: No module named MetaRelease
- 2465. By Michael Terry
-
more import fixes
Ken VanDine (ken-vandine) wrote : | # |
All tests that are expected to pass are passing. Looks good now that the symlinks are fixed up.
- 2466. By Michael Terry
-
fix versions of update-manager that we Break, the other branch got merged earlier than I expected
Preview Diff
1 | === removed file 'BUGS' | |||
2 | --- BUGS 2006-09-11 08:13:06 +0000 | |||
3 | +++ BUGS 1970-01-01 00:00:00 +0000 | |||
4 | @@ -1,5 +0,0 @@ | |||
5 | 1 | * aptsources.py: | ||
6 | 2 | - when turning off a new sources.list entry for the runing distro | ||
7 | 3 | (e.g. multiverse in a full edgy) and it is turned on again, the | ||
8 | 4 | source code checkbox becomes only half-checked | ||
9 | 5 | - when turning off/on a entry the comments become disordered | ||
10 | 6 | 0 | ||
11 | === removed file 'ChangeLog' | |||
12 | --- ChangeLog 2005-11-15 13:18:07 +0000 | |||
13 | +++ ChangeLog 1970-01-01 00:00:00 +0000 | |||
14 | @@ -1,62 +0,0 @@ | |||
15 | 1 | 2005-04-04 Michael Vogt <mvo@debian.org> | ||
16 | 2 | |||
17 | 3 | * configure.in: Added "xh" to ALL_LINGUAS. | ||
18 | 4 | |||
19 | 5 | 2005-04-01 Steve Murphy <murf@e-tools.com> | ||
20 | 6 | |||
21 | 7 | * configure.in: Added "rw" to ALL_LINGUAS. | ||
22 | 8 | |||
23 | 9 | 2005-03-29 Raphael Higino <raphaelh@cvs.gnome.org> | ||
24 | 10 | |||
25 | 11 | * configure.in: Added pt_BR to ALL_LINGUAS. | ||
26 | 12 | |||
27 | 13 | 2005-03-29 Zygmunt Krynicki <zyga@www.suxx.pl> | ||
28 | 14 | |||
29 | 15 | * src/dialog_apt_key.py.in: Enabled translation of known keys | ||
30 | 16 | |||
31 | 17 | 2005-03-24 Michiel Sikkes <michiel@eyesopened.nl> | ||
32 | 18 | |||
33 | 19 | * data/update-manager.glade: Added help button. Put package count next | ||
34 | 20 | to reload button above updatelist. | ||
35 | 21 | * src/update-manager.in: Implemented help button. | ||
36 | 22 | * configure.in: Added ja to ALL_LINGUAS. | ||
37 | 23 | |||
38 | 24 | 2005-03-21 Adam Weinberger <adamw@gnome.org> | ||
39 | 25 | |||
40 | 26 | * configure.in: Added en_CA to ALL_LINGUAS. | ||
41 | 27 | |||
42 | 28 | 2005-03-21 Christian Rose <menthos@menthos.com> | ||
43 | 29 | |||
44 | 30 | * configure.in: Added "sv" to ALL_LINGUAS. | ||
45 | 31 | Also sorted the language entries in the ALL_LINGUAS line, | ||
46 | 32 | so that it will be possible to spot duplicates or omissions. | ||
47 | 33 | |||
48 | 34 | 2005-03-11 Michiel Sikkes <michiel@eyesopened.nl> | ||
49 | 35 | |||
50 | 36 | * configure.in: Added el (Greek) to ALL_LINGUAS. | ||
51 | 37 | |||
52 | 38 | 2005-03-03 Dan Damian <dand@gnome.ro> | ||
53 | 39 | |||
54 | 40 | * configure.in: Added ro (Romanian) to ALL_LINGUAS. | ||
55 | 41 | |||
56 | 42 | 2005-03-10 Zygmunt Krynicki <zyga@www.suxx.pl> | ||
57 | 43 | |||
58 | 44 | * Improved translation support | ||
59 | 45 | |||
60 | 46 | 2005-02-18 Michiel Sikkes <michiel@eyesopened.nl> | ||
61 | 47 | |||
62 | 48 | * Added window title to the synaptic gtk socket window. | ||
63 | 49 | |||
64 | 50 | 2005-02-18 Michiel Sikkes <michiel@eyesopened.nl> | ||
65 | 51 | |||
66 | 52 | * Updated strings to have more consistent messages and it's not a pain | ||
67 | 53 | in the ass to translate ;). | ||
68 | 54 | * Merge from branches/release-37-2. | ||
69 | 55 | |||
70 | 56 | 2005-01-27 Martin Willemoes Hansen <mwh@sysrq.dk> | ||
71 | 57 | |||
72 | 58 | * da.po: Added Danish translation. | ||
73 | 59 | |||
74 | 60 | 2004-10-25 Michiel Sikkes <michiel@eyesopened.nl> | ||
75 | 61 | |||
76 | 62 | * Initial release. | ||
77 | 63 | 0 | ||
78 | === modified file 'DistUpgrade/DistUpgradeApport.py' | |||
79 | --- DistUpgrade/DistUpgradeApport.py 2012-06-18 18:41:13 +0000 | |||
80 | +++ DistUpgrade/DistUpgradeApport.py 2012-06-27 19:25:24 +0000 | |||
81 | @@ -15,11 +15,11 @@ | |||
82 | 15 | except ImportError as e: | 15 | except ImportError as e: |
83 | 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) |
84 | 17 | return False | 17 | return False |
87 | 18 | # we pretend we are update-manager | 18 | # we pretend we are do-release-upgrade |
88 | 19 | sys.argv[0] = "/usr/bin/update-manager" | 19 | sys.argv[0] = "/usr/bin/do-release-upgrade" |
89 | 20 | apport_excepthook(type, value, tb) | 20 | apport_excepthook(type, value, tb) |
90 | 21 | # now add the files in /var/log/dist-upgrade/* | 21 | # now add the files in /var/log/dist-upgrade/* |
92 | 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'): |
93 | 23 | report = Report() | 23 | report = Report() |
94 | 24 | report.setdefault('Tags', 'dist-upgrade') | 24 | report.setdefault('Tags', 'dist-upgrade') |
95 | 25 | report['Tags'] += ' dist-upgrade' | 25 | report['Tags'] += ' dist-upgrade' |
96 | @@ -28,7 +28,7 @@ | |||
97 | 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: |
98 | 29 | continue | 29 | continue |
99 | 30 | report[f.replace(".", "").replace("-", "")] = (open(f), ) | 30 | report[f.replace(".", "").replace("-", "")] = (open(f), ) |
101 | 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') |
102 | 32 | return True | 32 | return True |
103 | 33 | 33 | ||
104 | 34 | 34 | ||
105 | 35 | 35 | ||
106 | === modified file 'DistUpgrade/DistUpgradeCache.py' | |||
107 | --- DistUpgrade/DistUpgradeCache.py 2012-06-13 12:45:49 +0000 | |||
108 | +++ DistUpgrade/DistUpgradeCache.py 2012-06-27 19:25:24 +0000 | |||
109 | @@ -40,7 +40,7 @@ | |||
110 | 40 | from .DistUpgradeGettext import gettext as _ | 40 | from .DistUpgradeGettext import gettext as _ |
111 | 41 | from .DistUpgradeGettext import ngettext | 41 | from .DistUpgradeGettext import ngettext |
112 | 42 | 42 | ||
114 | 43 | from .utils import inside_chroot, estimate_kernel_size_in_boot | 43 | from UpdateManager.Core.utils import inside_chroot, estimate_kernel_size_in_boot |
115 | 44 | 44 | ||
116 | 45 | class CacheException(Exception): | 45 | class CacheException(Exception): |
117 | 46 | pass | 46 | pass |
118 | @@ -704,7 +704,7 @@ | |||
119 | 704 | "please try again later.") | 704 | "please try again later.") |
120 | 705 | else: | 705 | else: |
121 | 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 " |
123 | 707 | "the command 'ubuntu-bug update-manager' in a terminal.") | 707 | "the command 'ubuntu-bug ubuntu-release-upgrader-core' in a terminal.") |
124 | 708 | # make the error text available again on stdout for the | 708 | # make the error text available again on stdout for the |
125 | 709 | # text frontend | 709 | # text frontend |
126 | 710 | self._stopAptResolverLog() | 710 | self._stopAptResolverLog() |
127 | @@ -915,7 +915,7 @@ | |||
128 | 915 | _("It was impossible to install a " | 915 | _("It was impossible to install a " |
129 | 916 | "required package. Please report " | 916 | "required package. Please report " |
130 | 917 | "this as a bug using " | 917 | "this as a bug using " |
132 | 918 | "'ubuntu-bug update-manager' in " | 918 | "'ubuntu-bug ubuntu-release-upgrader-core' in " |
133 | 919 | "a terminal.")) | 919 | "a terminal.")) |
134 | 920 | return False | 920 | return False |
135 | 921 | logging.debug("marked_install: '%s' -> '%s'" % (key, self[key].marked_install)) | 921 | logging.debug("marked_install: '%s' -> '%s'" % (key, self[key].marked_install)) |
136 | 922 | 922 | ||
137 | === modified file 'DistUpgrade/DistUpgradeConfigParser.py' | |||
138 | --- DistUpgrade/DistUpgradeConfigParser.py 2012-06-11 10:46:56 +0000 | |||
139 | +++ DistUpgrade/DistUpgradeConfigParser.py 2012-06-27 19:25:24 +0000 | |||
140 | @@ -16,7 +16,7 @@ | |||
141 | 16 | import logging | 16 | import logging |
142 | 17 | import glob | 17 | import glob |
143 | 18 | 18 | ||
145 | 19 | CONFIG_OVERRIDE_DIR = "/etc/update-manager/release-upgrades.d" | 19 | CONFIG_OVERRIDE_DIR = "/etc/ubuntu-release-upgrader/release-upgrades.d" |
146 | 20 | 20 | ||
147 | 21 | class DistUpgradeConfig(SafeConfigParser): | 21 | class DistUpgradeConfig(SafeConfigParser): |
148 | 22 | def __init__(self, datadir, name="DistUpgrade.cfg", | 22 | def __init__(self, datadir, name="DistUpgrade.cfg", |
149 | 23 | 23 | ||
150 | === modified file 'DistUpgrade/DistUpgradeController.py' | |||
151 | --- DistUpgrade/DistUpgradeController.py 2012-06-11 12:09:52 +0000 | |||
152 | +++ DistUpgrade/DistUpgradeController.py 2012-06-27 19:25:24 +0000 | |||
153 | @@ -45,14 +45,14 @@ | |||
154 | 45 | except ImportError: | 45 | except ImportError: |
155 | 46 | # < 3.0 | 46 | # < 3.0 |
156 | 47 | from ConfigParser import SafeConfigParser, NoOptionError | 47 | from ConfigParser import SafeConfigParser, NoOptionError |
165 | 48 | from .utils import (country_mirror, | 48 | from UpdateManager.Core.utils import (country_mirror, |
166 | 49 | url_downloadable, | 49 | url_downloadable, |
167 | 50 | check_and_fix_xbit, | 50 | check_and_fix_xbit, |
168 | 51 | get_arch, | 51 | get_arch, |
169 | 52 | iptables_active, | 52 | iptables_active, |
170 | 53 | inside_chroot, | 53 | inside_chroot, |
171 | 54 | get_string_with_no_auth_from_source_entry, | 54 | get_string_with_no_auth_from_source_entry, |
172 | 55 | is_child_of_process_name) | 55 | is_child_of_process_name) |
173 | 56 | from string import Template | 56 | from string import Template |
174 | 57 | try: | 57 | try: |
175 | 58 | from urllib.parse import urlsplit | 58 | from urllib.parse import urlsplit |
176 | @@ -105,8 +105,8 @@ | |||
177 | 105 | self.options = options | 105 | self.options = options |
178 | 106 | 106 | ||
179 | 107 | # init gettext | 107 | # init gettext |
182 | 108 | gettext.bindtextdomain("update-manager",localedir) | 108 | gettext.bindtextdomain("ubuntu-release-upgrader",localedir) |
183 | 109 | gettext.textdomain("update-manager") | 109 | gettext.textdomain("ubuntu-release-upgrader") |
184 | 110 | 110 | ||
185 | 111 | # setup the view | 111 | # setup the view |
186 | 112 | logging.debug("Using '%s' view" % distUpgradeView.__class__.__name__) | 112 | logging.debug("Using '%s' view" % distUpgradeView.__class__.__name__) |
187 | @@ -305,7 +305,7 @@ | |||
188 | 305 | and we have network - we will then try to fetch a update | 305 | and we have network - we will then try to fetch a update |
189 | 306 | of ourself | 306 | of ourself |
190 | 307 | """ | 307 | """ |
192 | 308 | from .MetaRelease import MetaReleaseCore | 308 | from UpdateManager.Core.MetaRelease import MetaReleaseCore |
193 | 309 | from .DistUpgradeFetcherSelf import DistUpgradeFetcherSelf | 309 | from .DistUpgradeFetcherSelf import DistUpgradeFetcherSelf |
194 | 310 | # check if we run from a LTS | 310 | # check if we run from a LTS |
195 | 311 | forceLTS=False | 311 | forceLTS=False |
196 | @@ -534,7 +534,7 @@ | |||
197 | 534 | # we replace the sources.list with a single | 534 | # we replace the sources.list with a single |
198 | 535 | # line to ubuntu-main | 535 | # line to ubuntu-main |
199 | 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') |
201 | 537 | s = "# auto generated by update-manager" | 537 | s = "# auto generated by ubuntu-release-upgrader" |
202 | 538 | s += "deb http://archive.ubuntu.com/ubuntu %s main restricted" % self.toDist | 538 | s += "deb http://archive.ubuntu.com/ubuntu %s main restricted" % self.toDist |
203 | 539 | s += "deb http://archive.ubuntu.com/ubuntu %s-updates main restricted" % self.toDist | 539 | s += "deb http://archive.ubuntu.com/ubuntu %s-updates main restricted" % self.toDist |
204 | 540 | s += "deb http://security.ubuntu.com/ubuntu %s-security main restricted" % self.toDist | 540 | s += "deb http://security.ubuntu.com/ubuntu %s-security main restricted" % self.toDist |
205 | @@ -771,7 +771,7 @@ | |||
206 | 771 | _("Upgrading the repository information " | 771 | _("Upgrading the repository information " |
207 | 772 | "resulted in a invalid file so a bug " | 772 | "resulted in a invalid file so a bug " |
208 | 773 | "reporting process is being started.")) | 773 | "reporting process is being started.")) |
210 | 774 | subprocess.Popen(["apport-bug", "update-manager"]) | 774 | subprocess.Popen(["apport-bug", "ubuntu-release-upgrader"]) |
211 | 775 | return False | 775 | return False |
212 | 776 | 776 | ||
213 | 777 | if self.sources_disabled: | 777 | if self.sources_disabled: |
214 | @@ -1083,8 +1083,8 @@ | |||
215 | 1083 | # if its a ordering bug we can cleanly revert to | 1083 | # if its a ordering bug we can cleanly revert to |
216 | 1084 | # the previous release, no packages have been installed | 1084 | # the previous release, no packages have been installed |
217 | 1085 | # yet (LP: #328655, #356781) | 1085 | # yet (LP: #328655, #356781) |
220 | 1086 | if os.path.exists("/var/run/update-manager-apt-exception"): | 1086 | if os.path.exists("/var/run/ubuntu-release-upgrader-apt-exception"): |
221 | 1087 | e = open("/var/run/update-manager-apt-exception").read() | 1087 | e = open("/var/run/ubuntu-release-upgrader-apt-exception").read() |
222 | 1088 | logging.error("found exception: '%s'" % e) | 1088 | logging.error("found exception: '%s'" % e) |
223 | 1089 | # if its a ordering bug we can cleanly revert but we need to write | 1089 | # if its a ordering bug we can cleanly revert but we need to write |
224 | 1090 | # a marker for the parent process to know its this kind of error | 1090 | # a marker for the parent process to know its this kind of error |
225 | @@ -1111,7 +1111,7 @@ | |||
226 | 1111 | if not self._partialUpgrade: | 1111 | if not self._partialUpgrade: |
227 | 1112 | if not run_apport(): | 1112 | if not run_apport(): |
228 | 1113 | msg += _("\n\nPlease report this bug in a browser at " | 1113 | msg += _("\n\nPlease report this bug in a browser at " |
230 | 1114 | "http://bugs.launchpad.net/ubuntu/+source/update-manager/+filebug " | 1114 | "http://bugs.launchpad.net/ubuntu/+source/ubuntu-release-upgrader/+filebug " |
231 | 1115 | "and attach the files in /var/log/dist-upgrade/ " | 1115 | "and attach the files in /var/log/dist-upgrade/ " |
232 | 1116 | "to the bug report.\n" | 1116 | "to the bug report.\n" |
233 | 1117 | "%s" % e) | 1117 | "%s" % e) |
234 | @@ -1594,7 +1594,7 @@ | |||
235 | 1594 | _("Preparing the system for the upgrade " | 1594 | _("Preparing the system for the upgrade " |
236 | 1595 | "failed so a bug reporting process is " | 1595 | "failed so a bug reporting process is " |
237 | 1596 | "being started.")) | 1596 | "being started.")) |
239 | 1597 | subprocess.Popen(["apport-bug", "update-manager"]) | 1597 | subprocess.Popen(["apport-bug", "ubuntu-release-upgrader"]) |
240 | 1598 | sys.exit(1) | 1598 | sys.exit(1) |
241 | 1599 | 1599 | ||
242 | 1600 | # mvo: commented out for now, see #54234, this needs to be | 1600 | # mvo: commented out for now, see #54234, this needs to be |
243 | @@ -1613,7 +1613,7 @@ | |||
244 | 1613 | "\n" | 1613 | "\n" |
245 | 1614 | "Additionally, a bug reporting process is " | 1614 | "Additionally, a bug reporting process is " |
246 | 1615 | "being started.")) | 1615 | "being started.")) |
248 | 1616 | subprocess.Popen(["apport-bug", "update-manager"]) | 1616 | subprocess.Popen(["apport-bug", "ubuntu-release-upgrader"]) |
249 | 1617 | self.abort() | 1617 | self.abort() |
250 | 1618 | 1618 | ||
251 | 1619 | # run a "apt-get update" now, its ok to ignore errors, | 1619 | # run a "apt-get update" now, its ok to ignore errors, |
252 | @@ -1684,7 +1684,7 @@ | |||
253 | 1684 | "In the case of an overloaded mirror, you " | 1684 | "In the case of an overloaded mirror, you " |
254 | 1685 | "may want to try the upgrade again later.") | 1685 | "may want to try the upgrade again later.") |
255 | 1686 | % pkg) | 1686 | % pkg) |
257 | 1687 | subprocess.Popen(["apport-bug", "update-manager"]) | 1687 | subprocess.Popen(["apport-bug", "ubuntu-release-upgrader"]) |
258 | 1688 | self.abort() | 1688 | self.abort() |
259 | 1689 | 1689 | ||
260 | 1690 | # calc the dist-upgrade and see if the removals are ok/expected | 1690 | # calc the dist-upgrade and see if the removals are ok/expected |
261 | 1691 | 1691 | ||
262 | === modified file 'DistUpgrade/DistUpgradeFetcherCore.py' | |||
263 | --- DistUpgrade/DistUpgradeFetcherCore.py 2012-05-28 10:20:51 +0000 | |||
264 | +++ DistUpgrade/DistUpgradeFetcherCore.py 2012-06-27 19:25:24 +0000 | |||
265 | @@ -33,7 +33,7 @@ | |||
266 | 33 | from gettext import gettext as _ | 33 | from gettext import gettext as _ |
267 | 34 | from aptsources.sourceslist import SourcesList | 34 | from aptsources.sourceslist import SourcesList |
268 | 35 | 35 | ||
270 | 36 | from .utils import get_dist, url_downloadable, country_mirror | 36 | from UpdateManager.Core.utils import get_dist, url_downloadable, country_mirror |
271 | 37 | 37 | ||
272 | 38 | class DistUpgradeFetcherCore(object): | 38 | class DistUpgradeFetcherCore(object): |
273 | 39 | " base class (without GUI) for the upgrade fetcher " | 39 | " base class (without GUI) for the upgrade fetcher " |
274 | @@ -150,7 +150,7 @@ | |||
275 | 150 | if not os.path.exists(script): | 150 | if not os.path.exists(script): |
276 | 151 | return self.error(_("Could not run the upgrade tool"), | 151 | return self.error(_("Could not run the upgrade tool"), |
277 | 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. " |
279 | 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'.")) |
280 | 154 | return True | 154 | return True |
281 | 155 | 155 | ||
282 | 156 | def mirror_from_sources_list(self, uri, default_uri): | 156 | def mirror_from_sources_list(self, uri, default_uri): |
283 | @@ -211,7 +211,7 @@ | |||
284 | 211 | 211 | ||
285 | 212 | def fetchDistUpgrader(self): | 212 | def fetchDistUpgrader(self): |
286 | 213 | " download the tarball with the upgrade script " | 213 | " download the tarball with the upgrade script " |
288 | 214 | self.tmpdir = tmpdir = tempfile.mkdtemp(prefix="update-manager-") | 214 | self.tmpdir = tmpdir = tempfile.mkdtemp(prefix="ubuntu-release-upgrader-") |
289 | 215 | os.chdir(tmpdir) | 215 | os.chdir(tmpdir) |
290 | 216 | logging.debug("using tmpdir: '%s'" % tmpdir) | 216 | logging.debug("using tmpdir: '%s'" % tmpdir) |
291 | 217 | # turn debugging on here (if required) | 217 | # turn debugging on here (if required) |
292 | 218 | 218 | ||
293 | === modified file 'DistUpgrade/DistUpgradeQuirks.py' | |||
294 | --- DistUpgrade/DistUpgradeQuirks.py 2012-06-12 01:00:52 +0000 | |||
295 | +++ DistUpgrade/DistUpgradeQuirks.py 2012-06-27 19:25:24 +0000 | |||
296 | @@ -34,7 +34,7 @@ | |||
297 | 34 | from subprocess import PIPE, Popen | 34 | from subprocess import PIPE, Popen |
298 | 35 | from hashlib import md5 | 35 | from hashlib import md5 |
299 | 36 | 36 | ||
301 | 37 | from .utils import lsmod, get_arch | 37 | from UpdateManager.Core.utils import lsmod, get_arch |
302 | 38 | 38 | ||
303 | 39 | from .DistUpgradeGettext import gettext as _ | 39 | from .DistUpgradeGettext import gettext as _ |
304 | 40 | from janitor.plugincore.manager import PluginManager | 40 | from janitor.plugincore.manager import PluginManager |
305 | 41 | 41 | ||
306 | === modified file 'DistUpgrade/DistUpgradeView.py' | |||
307 | --- DistUpgrade/DistUpgradeView.py 2012-06-13 11:57:10 +0000 | |||
308 | +++ DistUpgrade/DistUpgradeView.py 2012-06-27 19:25:24 +0000 | |||
309 | @@ -206,7 +206,7 @@ | |||
310 | 206 | except Exception as e: | 206 | except Exception as e: |
311 | 207 | print("Exception during pm.DoInstall(): ", e) | 207 | print("Exception during pm.DoInstall(): ", e) |
312 | 208 | logging.exception("Exception during pm.DoInstall()") | 208 | logging.exception("Exception during pm.DoInstall()") |
314 | 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)) |
315 | 210 | os._exit(pm.ResultFailed) | 210 | os._exit(pm.ResultFailed) |
316 | 211 | os._exit(res) | 211 | os._exit(res) |
317 | 212 | self.child_pid = pid | 212 | self.child_pid = pid |
318 | 213 | 213 | ||
319 | === modified file 'DistUpgrade/DistUpgradeViewGtk.py' | |||
320 | --- DistUpgrade/DistUpgradeViewGtk.py 2012-06-13 11:40:17 +0000 | |||
321 | +++ DistUpgrade/DistUpgradeViewGtk.py 2012-06-27 19:25:24 +0000 | |||
322 | @@ -387,8 +387,8 @@ | |||
323 | 387 | gtk.init_check() | 387 | gtk.init_check() |
324 | 388 | 388 | ||
325 | 389 | try: | 389 | try: |
328 | 390 | locale.bindtextdomain("update-manager",localedir) | 390 | locale.bindtextdomain("ubuntu-release-upgrader",localedir) |
329 | 391 | gettext.textdomain("update-manager") | 391 | gettext.textdomain("ubuntu-release-upgrader") |
330 | 392 | except Exception as e: | 392 | except Exception as e: |
331 | 393 | logging.warning("Error setting locales (%s)" % e) | 393 | logging.warning("Error setting locales (%s)" % e) |
332 | 394 | 394 | ||
333 | @@ -400,7 +400,7 @@ | |||
334 | 400 | pass | 400 | pass |
335 | 401 | SimpleGtkbuilderApp.__init__(self, | 401 | SimpleGtkbuilderApp.__init__(self, |
336 | 402 | gladedir+"/DistUpgrade.ui", | 402 | gladedir+"/DistUpgrade.ui", |
338 | 403 | "update-manager") | 403 | "ubuntu-release-upgrader") |
339 | 404 | # terminal stuff | 404 | # terminal stuff |
340 | 405 | self.create_terminal() | 405 | self.create_terminal() |
341 | 406 | 406 | ||
342 | 407 | 407 | ||
343 | === modified file 'DistUpgrade/DistUpgradeViewGtk3.py' | |||
344 | --- DistUpgrade/DistUpgradeViewGtk3.py 2012-06-13 11:40:17 +0000 | |||
345 | +++ DistUpgrade/DistUpgradeViewGtk3.py 2012-06-27 19:25:24 +0000 | |||
346 | @@ -407,14 +407,14 @@ | |||
347 | 407 | Gtk.init_check(sys.argv) | 407 | Gtk.init_check(sys.argv) |
348 | 408 | 408 | ||
349 | 409 | try: | 409 | try: |
352 | 410 | locale.bindtextdomain("update-manager",localedir) | 410 | locale.bindtextdomain("ubuntu-release-upgrader",localedir) |
353 | 411 | gettext.textdomain("update-manager") | 411 | gettext.textdomain("ubuntu-release-upgrader") |
354 | 412 | except Exception as e: | 412 | except Exception as e: |
355 | 413 | logging.warning("Error setting locales (%s)" % e) | 413 | logging.warning("Error setting locales (%s)" % e) |
356 | 414 | 414 | ||
357 | 415 | SimpleGtkbuilderApp.__init__(self, | 415 | SimpleGtkbuilderApp.__init__(self, |
358 | 416 | gladedir+"/DistUpgrade.ui", | 416 | gladedir+"/DistUpgrade.ui", |
360 | 417 | "update-manager") | 417 | "ubuntu-release-upgrader") |
361 | 418 | 418 | ||
362 | 419 | icons = Gtk.IconTheme.get_default() | 419 | icons = Gtk.IconTheme.get_default() |
363 | 420 | try: | 420 | try: |
364 | 421 | 421 | ||
365 | === modified file 'DistUpgrade/DistUpgradeViewKDE.py' | |||
366 | --- DistUpgrade/DistUpgradeViewKDE.py 2012-06-13 11:41:10 +0000 | |||
367 | +++ DistUpgrade/DistUpgradeViewKDE.py 2012-06-27 19:25:24 +0000 | |||
368 | @@ -455,12 +455,12 @@ | |||
369 | 455 | if not datadir: | 455 | if not datadir: |
370 | 456 | localedir=os.path.join(os.getcwd(),"mo") | 456 | localedir=os.path.join(os.getcwd(),"mo") |
371 | 457 | else: | 457 | else: |
373 | 458 | localedir="/usr/share/locale/update-manager" | 458 | localedir="/usr/share/locale/ubuntu-release-upgrader" |
374 | 459 | 459 | ||
375 | 460 | # FIXME: i18n must be somewhere relative do this dir | 460 | # FIXME: i18n must be somewhere relative do this dir |
376 | 461 | try: | 461 | try: |
379 | 462 | gettext.bindtextdomain("update-manager", localedir) | 462 | gettext.bindtextdomain("ubuntu-release-upgrader", localedir) |
380 | 463 | gettext.textdomain("update-manager") | 463 | gettext.textdomain("ubuntu-release-upgrader") |
381 | 464 | except Exception as e: | 464 | except Exception as e: |
382 | 465 | logging.warning("Error setting locales (%s)" % e) | 465 | logging.warning("Error setting locales (%s)" % e) |
383 | 466 | 466 | ||
384 | @@ -474,7 +474,7 @@ | |||
385 | 474 | # exception when run without DISPLAY but dies instead | 474 | # exception when run without DISPLAY but dies instead |
386 | 475 | if not "DISPLAY" in os.environ: | 475 | if not "DISPLAY" in os.environ: |
387 | 476 | raise Exception("No DISPLAY in os.environ found") | 476 | raise Exception("No DISPLAY in os.environ found") |
389 | 477 | self.app = QApplication(["update-manager"]) | 477 | self.app = QApplication(["ubuntu-release-upgrader"]) |
390 | 478 | 478 | ||
391 | 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"): |
392 | 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") |
393 | @@ -524,8 +524,8 @@ | |||
394 | 524 | subprocess.call(["killall", "adept_updater"]) | 524 | subprocess.call(["killall", "adept_updater"]) |
395 | 525 | 525 | ||
396 | 526 | # init gettext | 526 | # init gettext |
399 | 527 | gettext.bindtextdomain("update-manager",localedir) | 527 | gettext.bindtextdomain("ubuntu-release-upgrader",localedir) |
400 | 528 | gettext.textdomain("update-manager") | 528 | gettext.textdomain("ubuntu-release-upgrader") |
401 | 529 | self.translate_widget_children() | 529 | self.translate_widget_children() |
402 | 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")) |
403 | 531 | 531 | ||
404 | @@ -610,7 +610,7 @@ | |||
405 | 610 | """start konqueror""" | 610 | """start konqueror""" |
406 | 611 | #need to run this else kdesu can't run Konqueror | 611 | #need to run this else kdesu can't run Konqueror |
407 | 612 | #subprocess.call(['su', 'ubuntu', 'xhost', '+localhost']) | 612 | #subprocess.call(['su', 'ubuntu', 'xhost', '+localhost']) |
409 | 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")) |
410 | 614 | 614 | ||
411 | 615 | def showTerminal(self): | 615 | def showTerminal(self): |
412 | 616 | if self.window_main.konsole_frame.isVisible(): | 616 | if self.window_main.konsole_frame.isVisible(): |
413 | 617 | 617 | ||
414 | === modified file 'DistUpgrade/DistUpgradeViewText.py' | |||
415 | --- DistUpgrade/DistUpgradeViewText.py 2012-06-13 11:19:42 +0000 | |||
416 | +++ DistUpgrade/DistUpgradeViewText.py 2012-06-27 19:25:24 +0000 | |||
417 | @@ -33,7 +33,7 @@ | |||
418 | 33 | 33 | ||
419 | 34 | import gettext | 34 | import gettext |
420 | 35 | from .DistUpgradeGettext import gettext as _ | 35 | from .DistUpgradeGettext import gettext as _ |
422 | 36 | from .utils import twrap | 36 | from UpdateManager.Core.utils import twrap |
423 | 37 | 37 | ||
424 | 38 | class TextAcquireProgress(AcquireProgress, apt.progress.text.AcquireProgress): | 38 | class TextAcquireProgress(AcquireProgress, apt.progress.text.AcquireProgress): |
425 | 39 | def __init__(self): | 39 | def __init__(self): |
426 | @@ -68,11 +68,11 @@ | |||
427 | 68 | if not datadir: | 68 | if not datadir: |
428 | 69 | localedir=os.path.join(os.getcwd(),"mo") | 69 | localedir=os.path.join(os.getcwd(),"mo") |
429 | 70 | else: | 70 | else: |
431 | 71 | localedir="/usr/share/locale/update-manager" | 71 | localedir="/usr/share/locale/ubuntu-release-upgrader" |
432 | 72 | 72 | ||
433 | 73 | try: | 73 | try: |
436 | 74 | gettext.bindtextdomain("update-manager", localedir) | 74 | gettext.bindtextdomain("ubuntu-release-upgrader", localedir) |
437 | 75 | gettext.textdomain("update-manager") | 75 | gettext.textdomain("ubuntu-release-upgrader") |
438 | 76 | except Exception as e: | 76 | except Exception as e: |
439 | 77 | logging.warning("Error setting locales (%s)" % e) | 77 | logging.warning("Error setting locales (%s)" % e) |
440 | 78 | 78 | ||
441 | 79 | 79 | ||
442 | === removed symlink 'DistUpgrade/MetaRelease.py' | |||
443 | === target was u'../UpdateManager/Core/MetaRelease.py' | |||
444 | === added file 'DistUpgrade/SimpleGtk3builderApp.py' | |||
445 | --- DistUpgrade/SimpleGtk3builderApp.py 1970-01-01 00:00:00 +0000 | |||
446 | +++ DistUpgrade/SimpleGtk3builderApp.py 2012-06-27 19:25:24 +0000 | |||
447 | @@ -0,0 +1,61 @@ | |||
448 | 1 | """ | ||
449 | 2 | SimpleGladeApp.py | ||
450 | 3 | Module that provides an object oriented abstraction to pygtk and libglade. | ||
451 | 4 | Copyright (C) 2004 Sandino Flores Moreno | ||
452 | 5 | """ | ||
453 | 6 | |||
454 | 7 | # This library is free software; you can redistribute it and/or | ||
455 | 8 | # modify it under the terms of the GNU Lesser General Public | ||
456 | 9 | # License as published by the Free Software Foundation; either | ||
457 | 10 | # version 2.1 of the License, or (at your option) any later version. | ||
458 | 11 | # | ||
459 | 12 | # This library is distributed in the hope that it will be useful, | ||
460 | 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
461 | 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
462 | 15 | # Lesser General Public License for more details. | ||
463 | 16 | # | ||
464 | 17 | # You should have received a copy of the GNU Lesser General Public | ||
465 | 18 | # License along with this library; if not, write to the Free Software | ||
466 | 19 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 | ||
467 | 20 | # USA | ||
468 | 21 | |||
469 | 22 | import logging | ||
470 | 23 | |||
471 | 24 | from gi.repository import Gtk | ||
472 | 25 | |||
473 | 26 | # based on SimpleGladeApp | ||
474 | 27 | class SimpleGtkbuilderApp: | ||
475 | 28 | |||
476 | 29 | def __init__(self, path, domain): | ||
477 | 30 | self.builder = Gtk.Builder() | ||
478 | 31 | self.builder.set_translation_domain(domain) | ||
479 | 32 | self.builder.add_from_file(path) | ||
480 | 33 | self.builder.connect_signals(self) | ||
481 | 34 | for o in self.builder.get_objects(): | ||
482 | 35 | if issubclass(type(o), Gtk.Buildable): | ||
483 | 36 | name = Gtk.Buildable.get_name(o) | ||
484 | 37 | setattr(self, name, o) | ||
485 | 38 | else: | ||
486 | 39 | logging.debug("WARNING: can not get name for '%s'" % o) | ||
487 | 40 | |||
488 | 41 | def run(self): | ||
489 | 42 | """ | ||
490 | 43 | Starts the main loop of processing events checking for Control-C. | ||
491 | 44 | |||
492 | 45 | The default implementation checks wheter a Control-C is pressed, | ||
493 | 46 | then calls on_keyboard_interrupt(). | ||
494 | 47 | |||
495 | 48 | Use this method for starting programs. | ||
496 | 49 | """ | ||
497 | 50 | try: | ||
498 | 51 | Gtk.main() | ||
499 | 52 | except KeyboardInterrupt: | ||
500 | 53 | self.on_keyboard_interrupt() | ||
501 | 54 | |||
502 | 55 | def on_keyboard_interrupt(self): | ||
503 | 56 | """ | ||
504 | 57 | This method is called by the default implementation of run() | ||
505 | 58 | after a program is finished by pressing Control-C. | ||
506 | 59 | """ | ||
507 | 60 | pass | ||
508 | 61 | |||
509 | 0 | 62 | ||
510 | === removed symlink 'DistUpgrade/SimpleGtk3builderApp.py' | |||
511 | === target was u'../UpdateManager/SimpleGtk3builderApp.py' | |||
512 | === added file 'DistUpgrade/SimpleGtkbuilderApp.py' | |||
513 | --- DistUpgrade/SimpleGtkbuilderApp.py 1970-01-01 00:00:00 +0000 | |||
514 | +++ DistUpgrade/SimpleGtkbuilderApp.py 2012-06-27 19:25:24 +0000 | |||
515 | @@ -0,0 +1,61 @@ | |||
516 | 1 | """ | ||
517 | 2 | SimpleGladeApp.py | ||
518 | 3 | Module that provides an object oriented abstraction to pygtk and libglade. | ||
519 | 4 | Copyright (C) 2004 Sandino Flores Moreno | ||
520 | 5 | """ | ||
521 | 6 | |||
522 | 7 | # This library is free software; you can redistribute it and/or | ||
523 | 8 | # modify it under the terms of the GNU Lesser General Public | ||
524 | 9 | # License as published by the Free Software Foundation; either | ||
525 | 10 | # version 2.1 of the License, or (at your option) any later version. | ||
526 | 11 | # | ||
527 | 12 | # This library is distributed in the hope that it will be useful, | ||
528 | 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
529 | 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
530 | 15 | # Lesser General Public License for more details. | ||
531 | 16 | # | ||
532 | 17 | # You should have received a copy of the GNU Lesser General Public | ||
533 | 18 | # License along with this library; if not, write to the Free Software | ||
534 | 19 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 | ||
535 | 20 | # USA | ||
536 | 21 | |||
537 | 22 | import logging | ||
538 | 23 | |||
539 | 24 | import gtk | ||
540 | 25 | |||
541 | 26 | # based on SimpleGladeApp | ||
542 | 27 | class SimpleGtkbuilderApp: | ||
543 | 28 | |||
544 | 29 | def __init__(self, path, domain): | ||
545 | 30 | self.builder = gtk.Builder() | ||
546 | 31 | self.builder.set_translation_domain(domain) | ||
547 | 32 | self.builder.add_from_file(path) | ||
548 | 33 | self.builder.connect_signals(self) | ||
549 | 34 | for o in self.builder.get_objects(): | ||
550 | 35 | if issubclass(type(o), gtk.Buildable): | ||
551 | 36 | name = gtk.Buildable.get_name(o) | ||
552 | 37 | setattr(self, name, o) | ||
553 | 38 | else: | ||
554 | 39 | logging.debug("WARNING: can not get name for '%s'" % o) | ||
555 | 40 | |||
556 | 41 | def run(self): | ||
557 | 42 | """ | ||
558 | 43 | Starts the main loop of processing events checking for Control-C. | ||
559 | 44 | |||
560 | 45 | The default implementation checks wheter a Control-C is pressed, | ||
561 | 46 | then calls on_keyboard_interrupt(). | ||
562 | 47 | |||
563 | 48 | Use this method for starting programs. | ||
564 | 49 | """ | ||
565 | 50 | try: | ||
566 | 51 | gtk.main() | ||
567 | 52 | except KeyboardInterrupt: | ||
568 | 53 | self.on_keyboard_interrupt() | ||
569 | 54 | |||
570 | 55 | def on_keyboard_interrupt(self): | ||
571 | 56 | """ | ||
572 | 57 | This method is called by the default implementation of run() | ||
573 | 58 | after a program is finished by pressing Control-C. | ||
574 | 59 | """ | ||
575 | 60 | pass | ||
576 | 61 | |||
577 | 0 | 62 | ||
578 | === removed symlink 'DistUpgrade/SimpleGtkbuilderApp.py' | |||
579 | === target was u'../UpdateManager/SimpleGtkbuilderApp.py' | |||
580 | === modified file 'DistUpgrade/TODO' | |||
581 | --- DistUpgrade/TODO 2006-10-05 14:36:09 +0000 | |||
582 | +++ DistUpgrade/TODO 2012-06-27 19:25:24 +0000 | |||
583 | @@ -8,8 +8,8 @@ | |||
584 | 8 | * if run from CDROM and we have network -> do a self update | 8 | * if run from CDROM and we have network -> do a self update |
585 | 9 | * support dapper-commercial in sources.list rewriting | 9 | * support dapper-commercial in sources.list rewriting |
586 | 10 | * after "no-network" dist-upgrade it is most likely that the system | 10 | * after "no-network" dist-upgrade it is most likely that the system |
589 | 11 | is only half-upgraded and update-manager will not be able to do | 11 | is only half-upgraded and ubuntu-release-upgrader will not be able to do |
590 | 12 | the full upgrade. update-manager needs to be changed to support | 12 | the full upgrade. ubuntu-release-upgrader needs to be changed to support |
591 | 13 | full dist-upgrades (possible by just calling the dist-upgrader | 13 | full dist-upgrades (possible by just calling the dist-upgrader |
592 | 14 | in a special mode) | 14 | in a special mode) |
593 | 15 | 15 | ||
594 | 16 | 16 | ||
595 | === modified file 'DistUpgrade/build-tarball.sh' | |||
596 | --- DistUpgrade/build-tarball.sh 2012-06-11 15:08:35 +0000 | |||
597 | +++ DistUpgrade/build-tarball.sh 2012-06-27 19:25:24 +0000 | |||
598 | @@ -7,7 +7,7 @@ | |||
599 | 7 | # cleanup | 7 | # cleanup |
600 | 8 | echo "Cleaning up" | 8 | echo "Cleaning up" |
601 | 9 | 9 | ||
603 | 10 | for d in ./ janitor/; do | 10 | for d in ./; do |
604 | 11 | rm -f $d/*~ $d/*.bak $d/*.pyc $d/*.moved $d/'#'* $d/*.rej $d/*.orig | 11 | rm -f $d/*~ $d/*.bak $d/*.pyc $d/*.moved $d/'#'* $d/*.rej $d/*.orig |
605 | 12 | rm -rf $d/__pycache__ | 12 | rm -rf $d/__pycache__ |
606 | 13 | rm -f *.tar.gz *.tar | 13 | rm -f *.tar.gz *.tar |
607 | @@ -38,4 +38,4 @@ | |||
608 | 38 | tar --append -v -f $DIST.tar ./DistUpgrade | 38 | tar --append -v -f $DIST.tar ./DistUpgrade |
609 | 39 | 39 | ||
610 | 40 | # and compress it | 40 | # and compress it |
611 | 41 | gzip -9 $DIST.tar | ||
612 | 42 | \ No newline at end of file | 41 | \ No newline at end of file |
613 | 42 | gzip -9 $DIST.tar | ||
614 | 43 | 43 | ||
615 | === modified file 'DistUpgrade/crashdialog.ui' | |||
616 | --- DistUpgrade/crashdialog.ui 2008-07-28 17:48:53 +0000 | |||
617 | +++ DistUpgrade/crashdialog.ui 2012-06-27 19:25:24 +0000 | |||
618 | @@ -59,7 +59,7 @@ | |||
619 | 59 | <item> | 59 | <item> |
620 | 60 | <widget class="QLabel" name="crash_info_text" > | 60 | <widget class="QLabel" name="crash_info_text" > |
621 | 61 | <property name="text" > | 61 | <property name="text" > |
623 | 62 | <string><qt>We're sorry; the upgrade tool crashed. Please file a new bug report at <a href="http://launchpad.net/ubuntu/+source/update-manager">http://launchpad.net/ubuntu/+source/update-manager</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><qt>We're sorry; the upgrade tool crashed. Please file a new bug report at <a href="http://launchpad.net/ubuntu/+source/ubuntu-release-upgrader">http://launchpad.net/ubuntu/+source/ubuntu-release-upgrader</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> |
624 | 63 | </property> | 63 | </property> |
625 | 64 | <property name="alignment" > | 64 | <property name="alignment" > |
626 | 65 | <set>Qt::AlignVCenter</set> | 65 | <set>Qt::AlignVCenter</set> |
627 | 66 | 66 | ||
628 | === removed symlink 'DistUpgrade/janitor' | |||
629 | === target was u'../janitor' | |||
630 | === modified file 'DistUpgrade/removal_blacklist.cfg' | |||
631 | --- DistUpgrade/removal_blacklist.cfg 2012-04-17 19:26:33 +0000 | |||
632 | +++ DistUpgrade/removal_blacklist.cfg 2012-06-27 19:25:24 +0000 | |||
633 | @@ -5,9 +5,10 @@ | |||
634 | 5 | kubuntu-desktop | 5 | kubuntu-desktop |
635 | 6 | xubuntu-desktop | 6 | xubuntu-desktop |
636 | 7 | lubuntu-desktop | 7 | lubuntu-desktop |
638 | 8 | # update-manager itself should not remove itself | 8 | # ubuntu-release-upgrader should not remove itself or update-manager |
639 | 9 | update-manager | 9 | update-manager |
640 | 10 | update-manager-core | 10 | update-manager-core |
641 | 11 | ubuntu-release-upgrader | ||
642 | 11 | # posgresql (LP: #871893) | 12 | # posgresql (LP: #871893) |
643 | 12 | ^postgresql-.*[0-9]\.[0-9].* | 13 | ^postgresql-.*[0-9]\.[0-9].* |
644 | 13 | # the upgrade runs in it | 14 | # the upgrade runs in it |
645 | 14 | 15 | ||
646 | === removed symlink 'DistUpgrade/utils.py' | |||
647 | === target was u'../UpdateManager/Core/utils.py' | |||
648 | === modified file 'DistUpgrade/xorg_fix_proprietary.py' | |||
649 | --- DistUpgrade/xorg_fix_proprietary.py 2012-05-28 10:20:51 +0000 | |||
650 | +++ DistUpgrade/xorg_fix_proprietary.py 2012-06-27 19:25:24 +0000 | |||
651 | @@ -31,7 +31,7 @@ | |||
652 | 31 | if (line.lower().startswith("section") and | 31 | if (line.lower().startswith("section") and |
653 | 32 | line.lower().split("#")[0].strip().endswith('"inputdevice"')): | 32 | line.lower().split("#")[0].strip().endswith('"inputdevice"')): |
654 | 33 | logging.debug("found 'InputDevice' section") | 33 | logging.debug("found 'InputDevice' section") |
656 | 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") |
657 | 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") |
658 | 36 | content.append("#"+raw) | 36 | content.append("#"+raw) |
659 | 37 | in_input_devices=True | 37 | in_input_devices=True |
660 | @@ -40,7 +40,7 @@ | |||
661 | 40 | in_input_devices=False | 40 | in_input_devices=False |
662 | 41 | elif line.lower().startswith("inputdevice"): | 41 | elif line.lower().startswith("inputdevice"): |
663 | 42 | logging.debug("commenting out '%s' " % line) | 42 | logging.debug("commenting out '%s' " % line) |
665 | 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") |
666 | 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") |
667 | 45 | content.append("#"+raw) | 45 | content.append("#"+raw) |
668 | 46 | elif in_input_devices: | 46 | elif in_input_devices: |
669 | @@ -123,8 +123,8 @@ | |||
670 | 123 | print("Need to run as root") | 123 | print("Need to run as root") |
671 | 124 | sys.exit(1) | 124 | sys.exit(1) |
672 | 125 | 125 | ||
675 | 126 | # we pretend to be update-manger so that apport picks up when we crash | 126 | # we pretend to be do-release-upgrade so that apport picks up when we crash |
676 | 127 | sys.argv[0] = "/usr/bin/update-manager" | 127 | sys.argv[0] = "/usr/bin/do-release-upgrade" |
677 | 128 | 128 | ||
678 | 129 | # setup logging | 129 | # setup logging |
679 | 130 | logging.basicConfig(level=logging.DEBUG, | 130 | logging.basicConfig(level=logging.DEBUG, |
680 | 131 | 131 | ||
681 | === removed file 'LGPL' | |||
682 | --- LGPL 2007-02-07 15:47:06 +0000 | |||
683 | +++ LGPL 1970-01-01 00:00:00 +0000 | |||
684 | @@ -1,510 +0,0 @@ | |||
685 | 1 | |||
686 | 2 | GNU LESSER GENERAL PUBLIC LICENSE | ||
687 | 3 | Version 2.1, February 1999 | ||
688 | 4 | |||
689 | 5 | Copyright (C) 1991, 1999 Free Software Foundation, Inc. | ||
690 | 6 | 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
691 | 7 | Everyone is permitted to copy and distribute verbatim copies | ||
692 | 8 | of this license document, but changing it is not allowed. | ||
693 | 9 | |||
694 | 10 | [This is the first released version of the Lesser GPL. It also counts | ||
695 | 11 | as the successor of the GNU Library Public License, version 2, hence | ||
696 | 12 | the version number 2.1.] | ||
697 | 13 | |||
698 | 14 | Preamble | ||
699 | 15 | |||
700 | 16 | The licenses for most software are designed to take away your | ||
701 | 17 | freedom to share and change it. By contrast, the GNU General Public | ||
702 | 18 | Licenses are intended to guarantee your freedom to share and change | ||
703 | 19 | free software--to make sure the software is free for all its users. | ||
704 | 20 | |||
705 | 21 | This license, the Lesser General Public License, applies to some | ||
706 | 22 | specially designated software packages--typically libraries--of the | ||
707 | 23 | Free Software Foundation and other authors who decide to use it. You | ||
708 | 24 | can use it too, but we suggest you first think carefully about whether | ||
709 | 25 | this license or the ordinary General Public License is the better | ||
710 | 26 | strategy to use in any particular case, based on the explanations | ||
711 | 27 | below. | ||
712 | 28 | |||
713 | 29 | When we speak of free software, we are referring to freedom of use, | ||
714 | 30 | not price. Our General Public Licenses are designed to make sure that | ||
715 | 31 | you have the freedom to distribute copies of free software (and charge | ||
716 | 32 | for this service if you wish); that you receive source code or can get | ||
717 | 33 | it if you want it; that you can change the software and use pieces of | ||
718 | 34 | it in new free programs; and that you are informed that you can do | ||
719 | 35 | these things. | ||
720 | 36 | |||
721 | 37 | To protect your rights, we need to make restrictions that forbid | ||
722 | 38 | distributors to deny you these rights or to ask you to surrender these | ||
723 | 39 | rights. These restrictions translate to certain responsibilities for | ||
724 | 40 | you if you distribute copies of the library or if you modify it. | ||
725 | 41 | |||
726 | 42 | For example, if you distribute copies of the library, whether gratis | ||
727 | 43 | or for a fee, you must give the recipients all the rights that we gave | ||
728 | 44 | you. You must make sure that they, too, receive or can get the source | ||
729 | 45 | code. If you link other code with the library, you must provide | ||
730 | 46 | complete object files to the recipients, so that they can relink them | ||
731 | 47 | with the library after making changes to the library and recompiling | ||
732 | 48 | it. And you must show them these terms so they know their rights. | ||
733 | 49 | |||
734 | 50 | We protect your rights with a two-step method: (1) we copyright the | ||
735 | 51 | library, and (2) we offer you this license, which gives you legal | ||
736 | 52 | permission to copy, distribute and/or modify the library. | ||
737 | 53 | |||
738 | 54 | To protect each distributor, we want to make it very clear that | ||
739 | 55 | there is no warranty for the free library. Also, if the library is | ||
740 | 56 | modified by someone else and passed on, the recipients should know | ||
741 | 57 | that what they have is not the original version, so that the original | ||
742 | 58 | author's reputation will not be affected by problems that might be | ||
743 | 59 | introduced by others. | ||
744 | 60 | |||
745 | 61 | 0 | ||
746 | 62 | Finally, software patents pose a constant threat to the existence of | ||
747 | 63 | any free program. We wish to make sure that a company cannot | ||
748 | 64 | effectively restrict the users of a free program by obtaining a | ||
749 | 65 | restrictive license from a patent holder. Therefore, we insist that | ||
750 | 66 | any patent license obtained for a version of the library must be | ||
751 | 67 | consistent with the full freedom of use specified in this license. | ||
752 | 68 | |||
753 | 69 | Most GNU software, including some libraries, is covered by the | ||
754 | 70 | ordinary GNU General Public License. This license, the GNU Lesser | ||
755 | 71 | General Public License, applies to certain designated libraries, and | ||
756 | 72 | is quite different from the ordinary General Public License. We use | ||
757 | 73 | this license for certain libraries in order to permit linking those | ||
758 | 74 | libraries into non-free programs. | ||
759 | 75 | |||
760 | 76 | When a program is linked with a library, whether statically or using | ||
761 | 77 | a shared library, the combination of the two is legally speaking a | ||
762 | 78 | combined work, a derivative of the original library. The ordinary | ||
763 | 79 | General Public License therefore permits such linking only if the | ||
764 | 80 | entire combination fits its criteria of freedom. The Lesser General | ||
765 | 81 | Public License permits more lax criteria for linking other code with | ||
766 | 82 | the library. | ||
767 | 83 | |||
768 | 84 | We call this license the "Lesser" General Public License because it | ||
769 | 85 | does Less to protect the user's freedom than the ordinary General | ||
770 | 86 | Public License. It also provides other free software developers Less | ||
771 | 87 | of an advantage over competing non-free programs. These disadvantages | ||
772 | 88 | are the reason we use the ordinary General Public License for many | ||
773 | 89 | libraries. However, the Lesser license provides advantages in certain | ||
774 | 90 | special circumstances. | ||
775 | 91 | |||
776 | 92 | For example, on rare occasions, there may be a special need to | ||
777 | 93 | encourage the widest possible use of a certain library, so that it | ||
778 | 94 | becomes a de-facto standard. To achieve this, non-free programs must | ||
779 | 95 | be allowed to use the library. A more frequent case is that a free | ||
780 | 96 | library does the same job as widely used non-free libraries. In this | ||
781 | 97 | case, there is little to gain by limiting the free library to free | ||
782 | 98 | software only, so we use the Lesser General Public License. | ||
783 | 99 | |||
784 | 100 | In other cases, permission to use a particular library in non-free | ||
785 | 101 | programs enables a greater number of people to use a large body of | ||
786 | 102 | free software. For example, permission to use the GNU C Library in | ||
787 | 103 | non-free programs enables many more people to use the whole GNU | ||
788 | 104 | operating system, as well as its variant, the GNU/Linux operating | ||
789 | 105 | system. | ||
790 | 106 | |||
791 | 107 | Although the Lesser General Public License is Less protective of the | ||
792 | 108 | users' freedom, it does ensure that the user of a program that is | ||
793 | 109 | linked with the Library has the freedom and the wherewithal to run | ||
794 | 110 | that program using a modified version of the Library. | ||
795 | 111 | |||
796 | 112 | The precise terms and conditions for copying, distribution and | ||
797 | 113 | modification follow. Pay close attention to the difference between a | ||
798 | 114 | "work based on the library" and a "work that uses the library". The | ||
799 | 115 | former contains code derived from the library, whereas the latter must | ||
800 | 116 | be combined with the library in order to run. | ||
801 | 117 | |||
802 | 118 | 1 | ||
803 | 119 | GNU LESSER GENERAL PUBLIC LICENSE | ||
804 | 120 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION | ||
805 | 121 | |||
806 | 122 | 0. This License Agreement applies to any software library or other | ||
807 | 123 | program which contains a notice placed by the copyright holder or | ||
808 | 124 | other authorized party saying it may be distributed under the terms of | ||
809 | 125 | this Lesser General Public License (also called "this License"). | ||
810 | 126 | Each licensee is addressed as "you". | ||
811 | 127 | |||
812 | 128 | A "library" means a collection of software functions and/or data | ||
813 | 129 | prepared so as to be conveniently linked with application programs | ||
814 | 130 | (which use some of those functions and data) to form executables. | ||
815 | 131 | |||
816 | 132 | The "Library", below, refers to any such software library or work | ||
817 | 133 | which has been distributed under these terms. A "work based on the | ||
818 | 134 | Library" means either the Library or any derivative work under | ||
819 | 135 | copyright law: that is to say, a work containing the Library or a | ||
820 | 136 | portion of it, either verbatim or with modifications and/or translated | ||
821 | 137 | straightforwardly into another language. (Hereinafter, translation is | ||
822 | 138 | included without limitation in the term "modification".) | ||
823 | 139 | |||
824 | 140 | "Source code" for a work means the preferred form of the work for | ||
825 | 141 | making modifications to it. For a library, complete source code means | ||
826 | 142 | all the source code for all modules it contains, plus any associated | ||
827 | 143 | interface definition files, plus the scripts used to control | ||
828 | 144 | compilation and installation of the library. | ||
829 | 145 | |||
830 | 146 | Activities other than copying, distribution and modification are not | ||
831 | 147 | covered by this License; they are outside its scope. The act of | ||
832 | 148 | running a program using the Library is not restricted, and output from | ||
833 | 149 | such a program is covered only if its contents constitute a work based | ||
834 | 150 | on the Library (independent of the use of the Library in a tool for | ||
835 | 151 | writing it). Whether that is true depends on what the Library does | ||
836 | 152 | and what the program that uses the Library does. | ||
837 | 153 | |||
838 | 154 | 1. You may copy and distribute verbatim copies of the Library's | ||
839 | 155 | complete source code as you receive it, in any medium, provided that | ||
840 | 156 | you conspicuously and appropriately publish on each copy an | ||
841 | 157 | appropriate copyright notice and disclaimer of warranty; keep intact | ||
842 | 158 | all the notices that refer to this License and to the absence of any | ||
843 | 159 | warranty; and distribute a copy of this License along with the | ||
844 | 160 | Library. | ||
845 | 161 | |||
846 | 162 | You may charge a fee for the physical act of transferring a copy, | ||
847 | 163 | and you may at your option offer warranty protection in exchange for a | ||
848 | 164 | fee. | ||
849 | 165 | |||
850 | 166 | 2 | ||
851 | 167 | 2. You may modify your copy or copies of the Library or any portion | ||
852 | 168 | of it, thus forming a work based on the Library, and copy and | ||
853 | 169 | distribute such modifications or work under the terms of Section 1 | ||
854 | 170 | above, provided that you also meet all of these conditions: | ||
855 | 171 | |||
856 | 172 | a) The modified work must itself be a software library. | ||
857 | 173 | |||
858 | 174 | b) You must cause the files modified to carry prominent notices | ||
859 | 175 | stating that you changed the files and the date of any change. | ||
860 | 176 | |||
861 | 177 | c) You must cause the whole of the work to be licensed at no | ||
862 | 178 | charge to all third parties under the terms of this License. | ||
863 | 179 | |||
864 | 180 | d) If a facility in the modified Library refers to a function or a | ||
865 | 181 | table of data to be supplied by an application program that uses | ||
866 | 182 | the facility, other than as an argument passed when the facility | ||
867 | 183 | is invoked, then you must make a good faith effort to ensure that, | ||
868 | 184 | in the event an application does not supply such function or | ||
869 | 185 | table, the facility still operates, and performs whatever part of | ||
870 | 186 | its purpose remains meaningful. | ||
871 | 187 | |||
872 | 188 | (For example, a function in a library to compute square roots has | ||
873 | 189 | a purpose that is entirely well-defined independent of the | ||
874 | 190 | application. Therefore, Subsection 2d requires that any | ||
875 | 191 | application-supplied function or table used by this function must | ||
876 | 192 | be optional: if the application does not supply it, the square | ||
877 | 193 | root function must still compute square roots.) | ||
878 | 194 | |||
879 | 195 | These requirements apply to the modified work as a whole. If | ||
880 | 196 | identifiable sections of that work are not derived from the Library, | ||
881 | 197 | and can be reasonably considered independent and separate works in | ||
882 | 198 | themselves, then this License, and its terms, do not apply to those | ||
883 | 199 | sections when you distribute them as separate works. But when you | ||
884 | 200 | distribute the same sections as part of a whole which is a work based | ||
885 | 201 | on the Library, the distribution of the whole must be on the terms of | ||
886 | 202 | this License, whose permissions for other licensees extend to the | ||
887 | 203 | entire whole, and thus to each and every part regardless of who wrote | ||
888 | 204 | it. | ||
889 | 205 | |||
890 | 206 | Thus, it is not the intent of this section to claim rights or contest | ||
891 | 207 | your rights to work written entirely by you; rather, the intent is to | ||
892 | 208 | exercise the right to control the distribution of derivative or | ||
893 | 209 | collective works based on the Library. | ||
894 | 210 | |||
895 | 211 | In addition, mere aggregation of another work not based on the Library | ||
896 | 212 | with the Library (or with a work based on the Library) on a volume of | ||
897 | 213 | a storage or distribution medium does not bring the other work under | ||
898 | 214 | the scope of this License. | ||
899 | 215 | |||
900 | 216 | 3. You may opt to apply the terms of the ordinary GNU General Public | ||
901 | 217 | License instead of this License to a given copy of the Library. To do | ||
902 | 218 | this, you must alter all the notices that refer to this License, so | ||
903 | 219 | that they refer to the ordinary GNU General Public License, version 2, | ||
904 | 220 | instead of to this License. (If a newer version than version 2 of the | ||
905 | 221 | ordinary GNU General Public License has appeared, then you can specify | ||
906 | 222 | that version instead if you wish.) Do not make any other change in | ||
907 | 223 | these notices. | ||
908 | 224 | |||
909 | 225 | 3 | ||
910 | 226 | Once this change is made in a given copy, it is irreversible for | ||
911 | 227 | that copy, so the ordinary GNU General Public License applies to all | ||
912 | 228 | subsequent copies and derivative works made from that copy. | ||
913 | 229 | |||
914 | 230 | This option is useful when you wish to copy part of the code of | ||
915 | 231 | the Library into a program that is not a library. | ||
916 | 232 | |||
917 | 233 | 4. You may copy and distribute the Library (or a portion or | ||
918 | 234 | derivative of it, under Section 2) in object code or executable form | ||
919 | 235 | under the terms of Sections 1 and 2 above provided that you accompany | ||
920 | 236 | it with the complete corresponding machine-readable source code, which | ||
921 | 237 | must be distributed under the terms of Sections 1 and 2 above on a | ||
922 | 238 | medium customarily used for software interchange. | ||
923 | 239 | |||
924 | 240 | If distribution of object code is made by offering access to copy | ||
925 | 241 | from a designated place, then offering equivalent access to copy the | ||
926 | 242 | source code from the same place satisfies the requirement to | ||
927 | 243 | distribute the source code, even though third parties are not | ||
928 | 244 | compelled to copy the source along with the object code. | ||
929 | 245 | |||
930 | 246 | 5. A program that contains no derivative of any portion of the | ||
931 | 247 | Library, but is designed to work with the Library by being compiled or | ||
932 | 248 | linked with it, is called a "work that uses the Library". Such a | ||
933 | 249 | work, in isolation, is not a derivative work of the Library, and | ||
934 | 250 | therefore falls outside the scope of this License. | ||
935 | 251 | |||
936 | 252 | However, linking a "work that uses the Library" with the Library | ||
937 | 253 | creates an executable that is a derivative of the Library (because it | ||
938 | 254 | contains portions of the Library), rather than a "work that uses the | ||
939 | 255 | library". The executable is therefore covered by this License. | ||
940 | 256 | Section 6 states terms for distribution of such executables. | ||
941 | 257 | |||
942 | 258 | When a "work that uses the Library" uses material from a header file | ||
943 | 259 | that is part of the Library, the object code for the work may be a | ||
944 | 260 | derivative work of the Library even though the source code is not. | ||
945 | 261 | Whether this is true is especially significant if the work can be | ||
946 | 262 | linked without the Library, or if the work is itself a library. The | ||
947 | 263 | threshold for this to be true is not precisely defined by law. | ||
948 | 264 | |||
949 | 265 | If such an object file uses only numerical parameters, data | ||
950 | 266 | structure layouts and accessors, and small macros and small inline | ||
951 | 267 | functions (ten lines or less in length), then the use of the object | ||
952 | 268 | file is unrestricted, regardless of whether it is legally a derivative | ||
953 | 269 | work. (Executables containing this object code plus portions of the | ||
954 | 270 | Library will still fall under Section 6.) | ||
955 | 271 | |||
956 | 272 | Otherwise, if the work is a derivative of the Library, you may | ||
957 | 273 | distribute the object code for the work under the terms of Section 6. | ||
958 | 274 | Any executables containing that work also fall under Section 6, | ||
959 | 275 | whether or not they are linked directly with the Library itself. | ||
960 | 276 | |||
961 | 277 | 4 | ||
962 | 278 | 6. As an exception to the Sections above, you may also combine or | ||
963 | 279 | link a "work that uses the Library" with the Library to produce a | ||
964 | 280 | work containing portions of the Library, and distribute that work | ||
965 | 281 | under terms of your choice, provided that the terms permit | ||
966 | 282 | modification of the work for the customer's own use and reverse | ||
967 | 283 | engineering for debugging such modifications. | ||
968 | 284 | |||
969 | 285 | You must give prominent notice with each copy of the work that the | ||
970 | 286 | Library is used in it and that the Library and its use are covered by | ||
971 | 287 | this License. You must supply a copy of this License. If the work | ||
972 | 288 | during execution displays copyright notices, you must include the | ||
973 | 289 | copyright notice for the Library among them, as well as a reference | ||
974 | 290 | directing the user to the copy of this License. Also, you must do one | ||
975 | 291 | of these things: | ||
976 | 292 | |||
977 | 293 | a) Accompany the work with the complete corresponding | ||
978 | 294 | machine-readable source code for the Library including whatever | ||
979 | 295 | changes were used in the work (which must be distributed under | ||
980 | 296 | Sections 1 and 2 above); and, if the work is an executable linked | ||
981 | 297 | with the Library, with the complete machine-readable "work that | ||
982 | 298 | uses the Library", as object code and/or source code, so that the | ||
983 | 299 | user can modify the Library and then relink to produce a modified | ||
984 | 300 | executable containing the modified Library. (It is understood | ||
985 | 301 | that the user who changes the contents of definitions files in the | ||
986 | 302 | Library will not necessarily be able to recompile the application | ||
987 | 303 | to use the modified definitions.) | ||
988 | 304 | |||
989 | 305 | b) Use a suitable shared library mechanism for linking with the | ||
990 | 306 | Library. A suitable mechanism is one that (1) uses at run time a | ||
991 | 307 | copy of the library already present on the user's computer system, | ||
992 | 308 | rather than copying library functions into the executable, and (2) | ||
993 | 309 | will operate properly with a modified version of the library, if | ||
994 | 310 | the user installs one, as long as the modified version is | ||
995 | 311 | interface-compatible with the version that the work was made with. | ||
996 | 312 | |||
997 | 313 | c) Accompany the work with a written offer, valid for at least | ||
998 | 314 | three years, to give the same user the materials specified in | ||
999 | 315 | Subsection 6a, above, for a charge no more than the cost of | ||
1000 | 316 | performing this distribution. | ||
1001 | 317 | |||
1002 | 318 | d) If distribution of the work is made by offering access to copy | ||
1003 | 319 | from a designated place, offer equivalent access to copy the above | ||
1004 | 320 | specified materials from the same place. | ||
1005 | 321 | |||
1006 | 322 | e) Verify that the user has already received a copy of these | ||
1007 | 323 | materials or that you have already sent this user a copy. | ||
1008 | 324 | |||
1009 | 325 | For an executable, the required form of the "work that uses the | ||
1010 | 326 | Library" must include any data and utility programs needed for | ||
1011 | 327 | reproducing the executable from it. However, as a special exception, | ||
1012 | 328 | the materials to be distributed need not include anything that is | ||
1013 | 329 | normally distributed (in either source or binary form) with the major | ||
1014 | 330 | components (compiler, kernel, and so on) of the operating system on | ||
1015 | 331 | which the executable runs, unless that component itself accompanies | ||
1016 | 332 | the executable. | ||
1017 | 333 | |||
1018 | 334 | It may happen that this requirement contradicts the license | ||
1019 | 335 | restrictions of other proprietary libraries that do not normally | ||
1020 | 336 | accompany the operating system. Such a contradiction means you cannot | ||
1021 | 337 | use both them and the Library together in an executable that you | ||
1022 | 338 | distribute. | ||
1023 | 339 | |||
1024 | 340 | 5 | ||
1025 | 341 | 7. You may place library facilities that are a work based on the | ||
1026 | 342 | Library side-by-side in a single library together with other library | ||
1027 | 343 | facilities not covered by this License, and distribute such a combined | ||
1028 | 344 | library, provided that the separate distribution of the work based on | ||
1029 | 345 | the Library and of the other library facilities is otherwise | ||
1030 | 346 | permitted, and provided that you do these two things: | ||
1031 | 347 | |||
1032 | 348 | a) Accompany the combined library with a copy of the same work | ||
1033 | 349 | based on the Library, uncombined with any other library | ||
1034 | 350 | facilities. This must be distributed under the terms of the | ||
1035 | 351 | Sections above. | ||
1036 | 352 | |||
1037 | 353 | b) Give prominent notice with the combined library of the fact | ||
1038 | 354 | that part of it is a work based on the Library, and explaining | ||
1039 | 355 | where to find the accompanying uncombined form of the same work. | ||
1040 | 356 | |||
1041 | 357 | 8. You may not copy, modify, sublicense, link with, or distribute | ||
1042 | 358 | the Library except as expressly provided under this License. Any | ||
1043 | 359 | attempt otherwise to copy, modify, sublicense, link with, or | ||
1044 | 360 | distribute the Library is void, and will automatically terminate your | ||
1045 | 361 | rights under this License. However, parties who have received copies, | ||
1046 | 362 | or rights, from you under this License will not have their licenses | ||
1047 | 363 | terminated so long as such parties remain in full compliance. | ||
1048 | 364 | |||
1049 | 365 | 9. You are not required to accept this License, since you have not | ||
1050 | 366 | signed it. However, nothing else grants you permission to modify or | ||
1051 | 367 | distribute the Library or its derivative works. These actions are | ||
1052 | 368 | prohibited by law if you do not accept this License. Therefore, by | ||
1053 | 369 | modifying or distributing the Library (or any work based on the | ||
1054 | 370 | Library), you indicate your acceptance of this License to do so, and | ||
1055 | 371 | all its terms and conditions for copying, distributing or modifying | ||
1056 | 372 | the Library or works based on it. | ||
1057 | 373 | |||
1058 | 374 | 10. Each time you redistribute the Library (or any work based on the | ||
1059 | 375 | Library), the recipient automatically receives a license from the | ||
1060 | 376 | original licensor to copy, distribute, link with or modify the Library | ||
1061 | 377 | subject to these terms and conditions. You may not impose any further | ||
1062 | 378 | restrictions on the recipients' exercise of the rights granted herein. | ||
1063 | 379 | You are not responsible for enforcing compliance by third parties with | ||
1064 | 380 | this License. | ||
1065 | 381 | |||
1066 | 382 | 6 | ||
1067 | 383 | 11. If, as a consequence of a court judgment or allegation of patent | ||
1068 | 384 | infringement or for any other reason (not limited to patent issues), | ||
1069 | 385 | conditions are imposed on you (whether by court order, agreement or | ||
1070 | 386 | otherwise) that contradict the conditions of this License, they do not | ||
1071 | 387 | excuse you from the conditions of this License. If you cannot | ||
1072 | 388 | distribute so as to satisfy simultaneously your obligations under this | ||
1073 | 389 | License and any other pertinent obligations, then as a consequence you | ||
1074 | 390 | may not distribute the Library at all. For example, if a patent | ||
1075 | 391 | license would not permit royalty-free redistribution of the Library by | ||
1076 | 392 | all those who receive copies directly or indirectly through you, then | ||
1077 | 393 | the only way you could satisfy both it and this License would be to | ||
1078 | 394 | refrain entirely from distribution of the Library. | ||
1079 | 395 | |||
1080 | 396 | If any portion of this section is held invalid or unenforceable under | ||
1081 | 397 | any particular circumstance, the balance of the section is intended to | ||
1082 | 398 | apply, and the section as a whole is intended to apply in other | ||
1083 | 399 | circumstances. | ||
1084 | 400 | |||
1085 | 401 | It is not the purpose of this section to induce you to infringe any | ||
1086 | 402 | patents or other property right claims or to contest validity of any | ||
1087 | 403 | such claims; this section has the sole purpose of protecting the | ||
1088 | 404 | integrity of the free software distribution system which is | ||
1089 | 405 | implemented by public license practices. Many people have made | ||
1090 | 406 | generous contributions to the wide range of software distributed | ||
1091 | 407 | through that system in reliance on consistent application of that | ||
1092 | 408 | system; it is up to the author/donor to decide if he or she is willing | ||
1093 | 409 | to distribute software through any other system and a licensee cannot | ||
1094 | 410 | impose that choice. | ||
1095 | 411 | |||
1096 | 412 | This section is intended to make thoroughly clear what is believed to | ||
1097 | 413 | be a consequence of the rest of this License. | ||
1098 | 414 | |||
1099 | 415 | 12. If the distribution and/or use of the Library is restricted in | ||
1100 | 416 | certain countries either by patents or by copyrighted interfaces, the | ||
1101 | 417 | original copyright holder who places the Library under this License | ||
1102 | 418 | may add an explicit geographical distribution limitation excluding those | ||
1103 | 419 | countries, so that distribution is permitted only in or among | ||
1104 | 420 | countries not thus excluded. In such case, this License incorporates | ||
1105 | 421 | the limitation as if written in the body of this License. | ||
1106 | 422 | |||
1107 | 423 | 13. The Free Software Foundation may publish revised and/or new | ||
1108 | 424 | versions of the Lesser General Public License from time to time. | ||
1109 | 425 | Such new versions will be similar in spirit to the present version, | ||
1110 | 426 | but may differ in detail to address new problems or concerns. | ||
1111 | 427 | |||
1112 | 428 | Each version is given a distinguishing version number. If the Library | ||
1113 | 429 | specifies a version number of this License which applies to it and | ||
1114 | 430 | "any later version", you have the option of following the terms and | ||
1115 | 431 | conditions either of that version or of any later version published by | ||
1116 | 432 | the Free Software Foundation. If the Library does not specify a | ||
1117 | 433 | license version number, you may choose any version ever published by | ||
1118 | 434 | the Free Software Foundation. | ||
1119 | 435 | |||
1120 | 436 | 7 | ||
1121 | 437 | 14. If you wish to incorporate parts of the Library into other free | ||
1122 | 438 | programs whose distribution conditions are incompatible with these, | ||
1123 | 439 | write to the author to ask for permission. For software which is | ||
1124 | 440 | copyrighted by the Free Software Foundation, write to the Free | ||
1125 | 441 | Software Foundation; we sometimes make exceptions for this. Our | ||
1126 | 442 | decision will be guided by the two goals of preserving the free status | ||
1127 | 443 | of all derivatives of our free software and of promoting the sharing | ||
1128 | 444 | and reuse of software generally. | ||
1129 | 445 | |||
1130 | 446 | NO WARRANTY | ||
1131 | 447 | |||
1132 | 448 | 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO | ||
1133 | 449 | WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. | ||
1134 | 450 | EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR | ||
1135 | 451 | OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY | ||
1136 | 452 | KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE | ||
1137 | 453 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
1138 | 454 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE | ||
1139 | 455 | LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME | ||
1140 | 456 | THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. | ||
1141 | 457 | |||
1142 | 458 | 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN | ||
1143 | 459 | WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY | ||
1144 | 460 | AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU | ||
1145 | 461 | FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR | ||
1146 | 462 | CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE | ||
1147 | 463 | LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING | ||
1148 | 464 | RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A | ||
1149 | 465 | FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF | ||
1150 | 466 | SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH | ||
1151 | 467 | DAMAGES. | ||
1152 | 468 | |||
1153 | 469 | END OF TERMS AND CONDITIONS | ||
1154 | 470 | |||
1155 | 471 | 8 | ||
1156 | 472 | How to Apply These Terms to Your New Libraries | ||
1157 | 473 | |||
1158 | 474 | If you develop a new library, and you want it to be of the greatest | ||
1159 | 475 | possible use to the public, we recommend making it free software that | ||
1160 | 476 | everyone can redistribute and change. You can do so by permitting | ||
1161 | 477 | redistribution under these terms (or, alternatively, under the terms | ||
1162 | 478 | of the ordinary General Public License). | ||
1163 | 479 | |||
1164 | 480 | To apply these terms, attach the following notices to the library. | ||
1165 | 481 | It is safest to attach them to the start of each source file to most | ||
1166 | 482 | effectively convey the exclusion of warranty; and each file should | ||
1167 | 483 | have at least the "copyright" line and a pointer to where the full | ||
1168 | 484 | notice is found. | ||
1169 | 485 | |||
1170 | 486 | |||
1171 | 487 | <one line to give the library's name and a brief idea of what it does.> | ||
1172 | 488 | Copyright (C) <year> <name of author> | ||
1173 | 489 | |||
1174 | 490 | This library is free software; you can redistribute it and/or | ||
1175 | 491 | modify it under the terms of the GNU Lesser General Public | ||
1176 | 492 | License as published by the Free Software Foundation; either | ||
1177 | 493 | version 2.1 of the License, or (at your option) any later version. | ||
1178 | 494 | |||
1179 | 495 | This library is distributed in the hope that it will be useful, | ||
1180 | 496 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1181 | 497 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
1182 | 498 | Lesser General Public License for more details. | ||
1183 | 499 | |||
1184 | 500 | You should have received a copy of the GNU Lesser General Public | ||
1185 | 501 | License along with this library; if not, write to the Free Software | ||
1186 | 502 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
1187 | 503 | |||
1188 | 504 | Also add information on how to contact you by electronic and paper mail. | ||
1189 | 505 | |||
1190 | 506 | You should also get your employer (if you work as a programmer) or | ||
1191 | 507 | your school, if any, to sign a "copyright disclaimer" for the library, | ||
1192 | 508 | if necessary. Here is a sample; alter the names: | ||
1193 | 509 | |||
1194 | 510 | Yoyodyne, Inc., hereby disclaims all copyright interest in the | ||
1195 | 511 | library `Frob' (a library for tweaking knobs) written by James | ||
1196 | 512 | Random Hacker. | ||
1197 | 513 | |||
1198 | 514 | <signature of Ty Coon>, 1 April 1990 | ||
1199 | 515 | Ty Coon, President of Vice | ||
1200 | 516 | |||
1201 | 517 | That's all there is to it! | ||
1202 | 518 | |||
1203 | 519 | |||
1204 | 520 | 9 | ||
1205 | === removed file 'README' | |||
1206 | --- README 2012-05-15 19:43:43 +0000 | |||
1207 | +++ README 1970-01-01 00:00:00 +0000 | |||
1208 | @@ -1,18 +0,0 @@ | |||
1209 | 1 | Software Updater for apt | ||
1210 | 2 | ------------------------ | ||
1211 | 3 | |||
1212 | 4 | This is an application which lets you manage available updates for your | ||
1213 | 5 | computer via apt and python-apt. | ||
1214 | 6 | |||
1215 | 7 | It also supports easy release upgrades. The following environment variables | ||
1216 | 8 | are honored: | ||
1217 | 9 | |||
1218 | 10 | DEBUG_UPDATE_MANAGER: | ||
1219 | 11 | - If set, debug information is printed to sys.stderr. This is useful for | ||
1220 | 12 | testing e.g. release upgrade checking/fetching. | ||
1221 | 13 | |||
1222 | 14 | |||
1223 | 15 | If the release upgrade is running in text mode and gnu screen is | ||
1224 | 16 | available it will automatically use gnu screen. This means that if | ||
1225 | 17 | e.g. the network connection is dropping just running the upgrader | ||
1226 | 18 | again will just reconnect to the running upgrade. | ||
1227 | 19 | 0 | ||
1228 | === renamed file 'README.dist-upgrade' => 'README' | |||
1229 | === removed file 'TODO' | |||
1230 | --- TODO 2007-07-31 10:55:22 +0000 | |||
1231 | +++ TODO 1970-01-01 00:00:00 +0000 | |||
1232 | @@ -1,22 +0,0 @@ | |||
1233 | 1 | * offer removal of no-longer-supported apps | ||
1234 | 2 | * improve countrymirror detection | ||
1235 | 3 | |||
1236 | 4 | |||
1237 | 5 | UpdateManager.Common.aptsources.py: | ||
1238 | 6 | - make the distro detection in sources.list more clever by using the | ||
1239 | 7 | origin informaton to avoid adding full uris to (unofficial/internal) | ||
1240 | 8 | mirrors | ||
1241 | 9 | - make it possible to inherit the mirrros from a ParentSuite (for | ||
1242 | 10 | the childs) | ||
1243 | 11 | |||
1244 | 12 | Misc: | ||
1245 | 13 | - have a common error dialog readymade and rib out all those | ||
1246 | 14 | GtkMessageDialogs | ||
1247 | 15 | - add download size to treeview | ||
1248 | 16 | - add /etc/apt/software-properties.d dir where the user can | ||
1249 | 17 | install matchers and templates | ||
1250 | 18 | - handle cases like "deb http://bla/ dist sec1 sec2 # comment" | ||
1251 | 19 | - rework the add channel/cdrom dialogs | ||
1252 | 20 | - d'n'd for key files | ||
1253 | 21 | - use one row per section and not one per channel in the treeview | ||
1254 | 22 | - sort the sources by dist | ||
1255 | 23 | 0 | ||
1256 | === removed directory 'UpdateManager' | |||
1257 | === removed file 'UpdateManager/ChangelogViewer.py' | |||
1258 | --- UpdateManager/ChangelogViewer.py 2012-06-11 16:17:31 +0000 | |||
1259 | +++ UpdateManager/ChangelogViewer.py 1970-01-01 00:00:00 +0000 | |||
1260 | @@ -1,283 +0,0 @@ | |||
1261 | 1 | # ReleaseNotesViewer.py | ||
1262 | 2 | # | ||
1263 | 3 | # Copyright (c) 2006 Sebastian Heinlein | ||
1264 | 4 | # 2007 Canonical | ||
1265 | 5 | # | ||
1266 | 6 | # Author: Sebastian Heinlein <sebastian.heinlein@web.de> | ||
1267 | 7 | # Michael Vogt <michael.vogt@ubuntu.com> | ||
1268 | 8 | # | ||
1269 | 9 | # This modul provides an inheritance of the Gtk.TextView that is | ||
1270 | 10 | # aware of http URLs and allows to open them in a browser. | ||
1271 | 11 | # It is based on the pygtk-demo "hypertext". | ||
1272 | 12 | # | ||
1273 | 13 | # This program is free software; you can redistribute it and/or | ||
1274 | 14 | # modify it under the terms of the GNU General Public License as | ||
1275 | 15 | # published by the Free Software Foundation; either version 2 of the | ||
1276 | 16 | # License, or (at your option) any later version. | ||
1277 | 17 | # | ||
1278 | 18 | # This program is distributed in the hope that it will be useful, | ||
1279 | 19 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1280 | 20 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1281 | 21 | # GNU General Public License for more details. | ||
1282 | 22 | # | ||
1283 | 23 | # You should have received a copy of the GNU General Public License | ||
1284 | 24 | # along with this program; if not, write to the Free Software | ||
1285 | 25 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 | ||
1286 | 26 | # USA | ||
1287 | 27 | |||
1288 | 28 | |||
1289 | 29 | from __future__ import absolute_import | ||
1290 | 30 | |||
1291 | 31 | from gi.repository import Gtk | ||
1292 | 32 | from gi.repository import Gdk | ||
1293 | 33 | from gi.repository import GObject | ||
1294 | 34 | from gi.repository import Pango | ||
1295 | 35 | from gettext import gettext as _ | ||
1296 | 36 | |||
1297 | 37 | from .ReleaseNotesViewer import open_url | ||
1298 | 38 | |||
1299 | 39 | class ChangelogViewer(Gtk.TextView): | ||
1300 | 40 | def __init__(self, changelog=None): | ||
1301 | 41 | """Init the ChangelogViewer as an Inheritance of the Gtk.TextView""" | ||
1302 | 42 | # init the parent | ||
1303 | 43 | GObject.GObject.__init__(self) | ||
1304 | 44 | # global hovering over link state | ||
1305 | 45 | self.hovering = False | ||
1306 | 46 | self.first = True | ||
1307 | 47 | # setup the buffer and signals | ||
1308 | 48 | self.set_property("editable", False) | ||
1309 | 49 | self.set_cursor_visible(False) | ||
1310 | 50 | # set some margin | ||
1311 | 51 | self.set_right_margin(4) | ||
1312 | 52 | self.set_left_margin(4) | ||
1313 | 53 | self.set_pixels_above_lines(4) | ||
1314 | 54 | self.buffer = Gtk.TextBuffer() | ||
1315 | 55 | self.set_buffer(self.buffer) | ||
1316 | 56 | self.connect("button-press-event", self.button_press_event) | ||
1317 | 57 | self.connect("motion-notify-event", self.motion_notify_event) | ||
1318 | 58 | self.connect("visibility-notify-event", self.visibility_notify_event) | ||
1319 | 59 | #self.buffer.connect("changed", self.search_links) | ||
1320 | 60 | self.buffer.connect_after("insert-text", self.on_insert_text) | ||
1321 | 61 | # search for links in the changelog and make them clickable | ||
1322 | 62 | if changelog != None: | ||
1323 | 63 | self.buffer.set_text(changelog) | ||
1324 | 64 | |||
1325 | 65 | def create_context_menu(self, url): | ||
1326 | 66 | """Create the context menu to be displayed when links are right clicked""" | ||
1327 | 67 | self.menu = Gtk.Menu() | ||
1328 | 68 | |||
1329 | 69 | # create menu items | ||
1330 | 70 | item_grey_link = Gtk.MenuItem() | ||
1331 | 71 | item_grey_link.set_label(url) | ||
1332 | 72 | item_grey_link.connect("activate", self.handle_context_menu, "open", url) | ||
1333 | 73 | item_seperator = Gtk.MenuItem() | ||
1334 | 74 | item_open_link = Gtk.MenuItem() | ||
1335 | 75 | item_open_link.set_label(_("Open Link in Browser")) | ||
1336 | 76 | item_open_link.connect("activate", self.handle_context_menu, "open", url) | ||
1337 | 77 | item_copy_link = Gtk.MenuItem() | ||
1338 | 78 | item_copy_link.set_label(_("Copy Link to Clipboard")) | ||
1339 | 79 | item_copy_link.connect("activate", self.handle_context_menu, "copy", url) | ||
1340 | 80 | |||
1341 | 81 | # add menu items | ||
1342 | 82 | self.menu.add(item_grey_link) | ||
1343 | 83 | self.menu.add(item_seperator) | ||
1344 | 84 | self.menu.add(item_open_link) | ||
1345 | 85 | self.menu.add(item_copy_link) | ||
1346 | 86 | self.menu.show_all() | ||
1347 | 87 | |||
1348 | 88 | def handle_context_menu(self, menuitem, action, url): | ||
1349 | 89 | """Handle activate event for the links' context menu""" | ||
1350 | 90 | if action == "open": | ||
1351 | 91 | open_url(url) | ||
1352 | 92 | if action == "copy": | ||
1353 | 93 | # the following two lines used to be enough - then gtk3/pygi | ||
1354 | 94 | # came along ... | ||
1355 | 95 | #cb = Gtk.Clipboard() | ||
1356 | 96 | #cb.set_text(url) | ||
1357 | 97 | display = Gdk.Display.get_default() | ||
1358 | 98 | selection = Gdk.Atom.intern ("CLIPBOARD", False) | ||
1359 | 99 | cb = Gtk.Clipboard.get_for_display(display, selection) | ||
1360 | 100 | cb.set_text(url, -1) | ||
1361 | 101 | cb.store() | ||
1362 | 102 | |||
1363 | 103 | def tag_link(self, start, end, url): | ||
1364 | 104 | """Apply the tag that marks links to the specified buffer selection""" | ||
1365 | 105 | tags = start.get_tags() | ||
1366 | 106 | for tag in tags: | ||
1367 | 107 | url = getattr(tag, "url", None) | ||
1368 | 108 | if url != "": | ||
1369 | 109 | return | ||
1370 | 110 | tag = self.buffer.create_tag(None, foreground="blue", | ||
1371 | 111 | underline=Pango.Underline.SINGLE) | ||
1372 | 112 | tag.url = url | ||
1373 | 113 | self.buffer.apply_tag(tag , start, end) | ||
1374 | 114 | |||
1375 | 115 | def on_insert_text(self, buffer, iter_end, text, *args): | ||
1376 | 116 | """Search for http URLs in newly inserted text | ||
1377 | 117 | and tag them accordingly""" | ||
1378 | 118 | |||
1379 | 119 | # some convenient urls | ||
1380 | 120 | MALONE = "https://launchpad.net/bugs/" | ||
1381 | 121 | DEBIAN = "http://bugs.debian.org/" | ||
1382 | 122 | CVE = "http://cve.mitre.org/cgi-bin/cvename.cgi?name=" | ||
1383 | 123 | # some convinient end-markers | ||
1384 | 124 | ws = [" ","\t","\n"] | ||
1385 | 125 | brak = [")","]",">"] | ||
1386 | 126 | punct = [",","!",":"] | ||
1387 | 127 | dot = ["."]+punct | ||
1388 | 128 | dot_cr = [".\n"] | ||
1389 | 129 | |||
1390 | 130 | # search items are start-str, list-of-end-strs, url-prefix | ||
1391 | 131 | # a lot of this search is "TEH SUCK"(tm) because of limitations | ||
1392 | 132 | # in iter.forward_search() | ||
1393 | 133 | # - i.e. no insensitive searching, no regexp | ||
1394 | 134 | search_items = [ ("http://", ws+brak+punct+dot_cr, "http://"), | ||
1395 | 135 | ("LP#", ws+brak+dot, MALONE), | ||
1396 | 136 | ("LP: #", ws+brak+dot, MALONE), | ||
1397 | 137 | ("lp: #", ws+brak+dot, MALONE), | ||
1398 | 138 | ("LP:#", ws+brak+dot, MALONE), | ||
1399 | 139 | ("Malone: #", ws+brak+dot, MALONE), | ||
1400 | 140 | ("Malone:#", ws+brak+dot, MALONE), | ||
1401 | 141 | ("Ubuntu: #", ws+brak+dot, MALONE), | ||
1402 | 142 | ("Ubuntu:#", ws+brak+dot, MALONE), | ||
1403 | 143 | ("Closes: #",ws+brak+dot, DEBIAN), | ||
1404 | 144 | ("Closes:#",ws+brak+dot, DEBIAN), | ||
1405 | 145 | ("closes:#",ws+brak+dot, DEBIAN), | ||
1406 | 146 | ("closes: #",ws+brak+dot, DEBIAN), | ||
1407 | 147 | ("CVE-", ws+brak+dot, CVE), | ||
1408 | 148 | ] | ||
1409 | 149 | # init | ||
1410 | 150 | iter = buffer.get_iter_at_offset(iter_end.get_offset() - len(text)) | ||
1411 | 151 | |||
1412 | 152 | # search for the next match in the buffer | ||
1413 | 153 | for (start_str, end_list, url_prefix) in search_items: | ||
1414 | 154 | while True: | ||
1415 | 155 | ret = iter.forward_search(start_str, | ||
1416 | 156 | Gtk.TextSearchFlags.VISIBLE_ONLY, | ||
1417 | 157 | iter_end) | ||
1418 | 158 | # if we reach the end break the loop | ||
1419 | 159 | if not ret: | ||
1420 | 160 | break | ||
1421 | 161 | # get the position of the protocol prefix | ||
1422 | 162 | (match_start, match_end) = ret | ||
1423 | 163 | match_suffix = match_end.copy() | ||
1424 | 164 | match_tmp = match_end.copy() | ||
1425 | 165 | while True: | ||
1426 | 166 | # extend the selection to the complete search item | ||
1427 | 167 | if match_tmp.forward_char(): | ||
1428 | 168 | text = match_end.get_text(match_tmp) | ||
1429 | 169 | if text in end_list: | ||
1430 | 170 | break | ||
1431 | 171 | # move one char futher to get two char | ||
1432 | 172 | # end-markers (and back later) LP: #396393 | ||
1433 | 173 | match_tmp.forward_char() | ||
1434 | 174 | text = match_end.get_text(match_tmp) | ||
1435 | 175 | if text in end_list: | ||
1436 | 176 | break | ||
1437 | 177 | match_tmp.backward_char() | ||
1438 | 178 | else: | ||
1439 | 179 | break | ||
1440 | 180 | match_end = match_tmp.copy() | ||
1441 | 181 | |||
1442 | 182 | # call the tagging method for the complete URL | ||
1443 | 183 | url = url_prefix + match_suffix.get_text(match_end) | ||
1444 | 184 | |||
1445 | 185 | self.tag_link(match_start, match_end, url) | ||
1446 | 186 | # set the starting point for the next search | ||
1447 | 187 | iter = match_end | ||
1448 | 188 | |||
1449 | 189 | def button_press_event(self, text_view, event): | ||
1450 | 190 | """callback for mouse click events""" | ||
1451 | 191 | # we only react on left or right mouse clicks | ||
1452 | 192 | if event.button != 1 and event.button != 3: | ||
1453 | 193 | return False | ||
1454 | 194 | |||
1455 | 195 | # try to get a selection | ||
1456 | 196 | try: | ||
1457 | 197 | (start, end) = self.buffer.get_selection_bounds() | ||
1458 | 198 | except ValueError: | ||
1459 | 199 | pass | ||
1460 | 200 | else: | ||
1461 | 201 | if start.get_offset() != end.get_offset(): | ||
1462 | 202 | return False | ||
1463 | 203 | |||
1464 | 204 | # get the iter at the mouse position | ||
1465 | 205 | (x, y) = self.window_to_buffer_coords(Gtk.TextWindowType.WIDGET, | ||
1466 | 206 | int(event.x), int(event.y)) | ||
1467 | 207 | iter = self.get_iter_at_location(x, y) | ||
1468 | 208 | |||
1469 | 209 | # call open_url or menu.popup if an URL is assigned to the iter | ||
1470 | 210 | tags = iter.get_tags() | ||
1471 | 211 | for tag in tags: | ||
1472 | 212 | if hasattr(tag, "url"): | ||
1473 | 213 | if event.button == 1: | ||
1474 | 214 | open_url(tag.url) | ||
1475 | 215 | break | ||
1476 | 216 | if event.button == 3: | ||
1477 | 217 | self.create_context_menu(tag.url) | ||
1478 | 218 | self.menu.popup(None, None, None, None, event.button, event.time) | ||
1479 | 219 | return True | ||
1480 | 220 | |||
1481 | 221 | def motion_notify_event(self, text_view, event): | ||
1482 | 222 | """callback for the mouse movement event, that calls the | ||
1483 | 223 | check_hovering method with the mouse postition coordiantes""" | ||
1484 | 224 | x, y = text_view.window_to_buffer_coords(Gtk.TextWindowType.WIDGET, | ||
1485 | 225 | int(event.x), int(event.y)) | ||
1486 | 226 | self.check_hovering(x, y) | ||
1487 | 227 | self.get_window(Gtk.TextWindowType.TEXT).get_pointer() | ||
1488 | 228 | return False | ||
1489 | 229 | |||
1490 | 230 | def visibility_notify_event(self, text_view, event): | ||
1491 | 231 | """callback if the widgets gets visible (e.g. moves to the foreground) | ||
1492 | 232 | that calls the check_hovering method with the mouse position | ||
1493 | 233 | coordinates""" | ||
1494 | 234 | (screen, wx, wy, mod) = text_view.get_window(Gtk.TextWindowType.TEXT).get_pointer() | ||
1495 | 235 | (bx, by) = text_view.window_to_buffer_coords(Gtk.TextWindowType.WIDGET, wx, | ||
1496 | 236 | wy) | ||
1497 | 237 | self.check_hovering(bx, by) | ||
1498 | 238 | return False | ||
1499 | 239 | |||
1500 | 240 | def check_hovering(self, x, y): | ||
1501 | 241 | """Check if the mouse is above a tagged link and if yes show | ||
1502 | 242 | a hand cursor""" | ||
1503 | 243 | _hovering = False | ||
1504 | 244 | # get the iter at the mouse position | ||
1505 | 245 | iter = self.get_iter_at_location(x, y) | ||
1506 | 246 | |||
1507 | 247 | # set _hovering if the iter has the tag "url" | ||
1508 | 248 | tags = iter.get_tags() | ||
1509 | 249 | for tag in tags: | ||
1510 | 250 | if hasattr(tag, "url"): | ||
1511 | 251 | _hovering = True | ||
1512 | 252 | break | ||
1513 | 253 | |||
1514 | 254 | # change the global hovering state | ||
1515 | 255 | if _hovering != self.hovering or self.first == True: | ||
1516 | 256 | self.first = False | ||
1517 | 257 | self.hovering = _hovering | ||
1518 | 258 | # Set the appropriate cursur icon | ||
1519 | 259 | if self.hovering: | ||
1520 | 260 | self.get_window(Gtk.TextWindowType.TEXT).\ | ||
1521 | 261 | set_cursor(Gdk.Cursor.new(Gdk.CursorType.HAND2)) | ||
1522 | 262 | else: | ||
1523 | 263 | self.get_window(Gtk.TextWindowType.TEXT).\ | ||
1524 | 264 | set_cursor(Gdk.Cursor.new(Gdk.CursorType.LEFT_PTR)) | ||
1525 | 265 | |||
1526 | 266 | |||
1527 | 267 | if __name__ == "__main__": | ||
1528 | 268 | w = Gtk.Window() | ||
1529 | 269 | cv = ChangelogViewer() | ||
1530 | 270 | changes = cv.get_buffer() | ||
1531 | 271 | changes.create_tag("versiontag", weight=Pango.Weight.BOLD) | ||
1532 | 272 | changes.set_text(""" | ||
1533 | 273 | |||
1534 | 274 | Version 6-14-0ubuntu1.9.04: | ||
1535 | 275 | |||
1536 | 276 | * New upstream version. LP: #382918. | ||
1537 | 277 | Release notes at http://java.sun.com/javase/6/webnotes/ReleaseNotes.html. | ||
1538 | 278 | |||
1539 | 279 | """) | ||
1540 | 280 | |||
1541 | 281 | w.add(cv) | ||
1542 | 282 | w.show_all() | ||
1543 | 283 | Gtk.main() | ||
1544 | 284 | 0 | ||
1545 | === removed directory 'UpdateManager/Core' | |||
1546 | === removed file 'UpdateManager/Core/AlertWatcher.py' | |||
1547 | --- UpdateManager/Core/AlertWatcher.py 2012-05-01 14:01:29 +0000 | |||
1548 | +++ UpdateManager/Core/AlertWatcher.py 1970-01-01 00:00:00 +0000 | |||
1549 | @@ -1,96 +0,0 @@ | |||
1550 | 1 | # AlertWatcher.py | ||
1551 | 2 | # | ||
1552 | 3 | # Copyright (c) 2010 Mohamed Amine IL Idrissi | ||
1553 | 4 | # | ||
1554 | 5 | # Author: Mohamed Amine IL Idrissi <ilidrissiamine@gmail.com> | ||
1555 | 6 | # | ||
1556 | 7 | # This program is free software; you can redistribute it and/or | ||
1557 | 8 | # modify it under the terms of the GNU General Public License as | ||
1558 | 9 | # published by the Free Software Foundation; either version 2 of the | ||
1559 | 10 | # License, or (at your option) any later version. | ||
1560 | 11 | # | ||
1561 | 12 | # This program is distributed in the hope that it will be useful, | ||
1562 | 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1563 | 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1564 | 15 | # GNU General Public License for more details. | ||
1565 | 16 | # | ||
1566 | 17 | # You should have received a copy of the GNU General Public License | ||
1567 | 18 | # along with this program; if not, write to the Free Software | ||
1568 | 19 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 | ||
1569 | 20 | # USA | ||
1570 | 21 | |||
1571 | 22 | from __future__ import absolute_import | ||
1572 | 23 | |||
1573 | 24 | from gi.repository import GObject | ||
1574 | 25 | import dbus | ||
1575 | 26 | from dbus.mainloop.glib import DBusGMainLoop | ||
1576 | 27 | |||
1577 | 28 | class AlertWatcher(GObject.GObject): | ||
1578 | 29 | """ a class that checks for alerts and reports them, like a battery | ||
1579 | 30 | or network warning """ | ||
1580 | 31 | |||
1581 | 32 | __gsignals__ = {"network-alert": (GObject.SignalFlags.RUN_FIRST, | ||
1582 | 33 | None, | ||
1583 | 34 | (GObject.TYPE_INT,)), | ||
1584 | 35 | "battery-alert": (GObject.SignalFlags.RUN_FIRST, | ||
1585 | 36 | None, | ||
1586 | 37 | (GObject.TYPE_BOOLEAN,)), | ||
1587 | 38 | "network-3g-alert": (GObject.SignalFlags.RUN_FIRST, | ||
1588 | 39 | None, | ||
1589 | 40 | (GObject.TYPE_BOOLEAN, | ||
1590 | 41 | GObject.TYPE_BOOLEAN,)), | ||
1591 | 42 | } | ||
1592 | 43 | |||
1593 | 44 | def __init__(self): | ||
1594 | 45 | GObject.GObject.__init__(self) | ||
1595 | 46 | DBusGMainLoop(set_as_default=True) | ||
1596 | 47 | self.bus = dbus.Bus(dbus.Bus.TYPE_SYSTEM) | ||
1597 | 48 | self.network_state = 3 # make it always connected if NM isn't available | ||
1598 | 49 | |||
1599 | 50 | def check_alert_state(self): | ||
1600 | 51 | try: | ||
1601 | 52 | obj = self.bus.get_object("org.freedesktop.NetworkManager", | ||
1602 | 53 | "/org/freedesktop/NetworkManager") | ||
1603 | 54 | obj.connect_to_signal("StateChanged", | ||
1604 | 55 | self._on_network_state_changed, | ||
1605 | 56 | dbus_interface="org.freedesktop.NetworkManager") | ||
1606 | 57 | interface = dbus.Interface(obj, "org.freedesktop.DBus.Properties") | ||
1607 | 58 | self.network_state = interface.Get("org.freedesktop.NetworkManager", "State") | ||
1608 | 59 | self._network_alert(self.network_state) | ||
1609 | 60 | # power | ||
1610 | 61 | obj = self.bus.get_object('org.freedesktop.UPower', | ||
1611 | 62 | '/org/freedesktop/UPower') | ||
1612 | 63 | obj.connect_to_signal("Changed", self._power_changed, | ||
1613 | 64 | dbus_interface="org.freedesktop.UPower") | ||
1614 | 65 | self._power_changed() | ||
1615 | 66 | # 3g | ||
1616 | 67 | self._update_3g_state() | ||
1617 | 68 | except dbus.exceptions.DBusException: | ||
1618 | 69 | pass | ||
1619 | 70 | |||
1620 | 71 | def _on_network_state_changed(self, state): | ||
1621 | 72 | self._network_alert(state) | ||
1622 | 73 | self._update_3g_state() | ||
1623 | 74 | |||
1624 | 75 | def _update_3g_state(self): | ||
1625 | 76 | from .roam import NetworkManagerHelper | ||
1626 | 77 | nm = NetworkManagerHelper() | ||
1627 | 78 | on_3g = nm.is_active_connection_gsm_or_cdma() | ||
1628 | 79 | is_roaming = nm.is_active_connection_gsm_or_cdma_roaming() | ||
1629 | 80 | self._network_3g_alert(on_3g, is_roaming) | ||
1630 | 81 | |||
1631 | 82 | def _network_3g_alert(self, on_3g, is_roaming): | ||
1632 | 83 | self.emit("network-3g-alert", on_3g, is_roaming) | ||
1633 | 84 | |||
1634 | 85 | def _network_alert(self, state): | ||
1635 | 86 | self.network_state = state | ||
1636 | 87 | self.emit("network-alert", state) | ||
1637 | 88 | |||
1638 | 89 | def _power_changed(self): | ||
1639 | 90 | obj = self.bus.get_object("org.freedesktop.UPower", \ | ||
1640 | 91 | "/org/freedesktop/UPower") | ||
1641 | 92 | interface = dbus.Interface(obj, "org.freedesktop.DBus.Properties") | ||
1642 | 93 | on_battery = interface.Get("org.freedesktop.UPower", "OnBattery") | ||
1643 | 94 | self.emit("battery-alert", on_battery) | ||
1644 | 95 | |||
1645 | 96 | |||
1646 | 97 | 0 | ||
1647 | === removed file 'UpdateManager/Core/DistUpgradeFetcherCore.py' | |||
1648 | --- UpdateManager/Core/DistUpgradeFetcherCore.py 2012-05-28 10:20:51 +0000 | |||
1649 | +++ UpdateManager/Core/DistUpgradeFetcherCore.py 1970-01-01 00:00:00 +0000 | |||
1650 | @@ -1,313 +0,0 @@ | |||
1651 | 1 | # DistUpgradeFetcherCore.py | ||
1652 | 2 | # | ||
1653 | 3 | # Copyright (c) 2006 Canonical | ||
1654 | 4 | # | ||
1655 | 5 | # Author: Michael Vogt <michael.vogt@ubuntu.com> | ||
1656 | 6 | # | ||
1657 | 7 | # This program is free software; you can redistribute it and/or | ||
1658 | 8 | # modify it under the terms of the GNU General Public License as | ||
1659 | 9 | # published by the Free Software Foundation; either version 2 of the | ||
1660 | 10 | # License, or (at your option) any later version. | ||
1661 | 11 | # | ||
1662 | 12 | # This program is distributed in the hope that it will be useful, | ||
1663 | 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1664 | 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1665 | 15 | # GNU General Public License for more details. | ||
1666 | 16 | # | ||
1667 | 17 | # You should have received a copy of the GNU General Public License | ||
1668 | 18 | # along with this program; if not, write to the Free Software | ||
1669 | 19 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 | ||
1670 | 20 | # USA | ||
1671 | 21 | |||
1672 | 22 | from __future__ import absolute_import, print_function | ||
1673 | 23 | |||
1674 | 24 | from string import Template | ||
1675 | 25 | import os | ||
1676 | 26 | import apt_pkg | ||
1677 | 27 | import logging | ||
1678 | 28 | import tarfile | ||
1679 | 29 | import tempfile | ||
1680 | 30 | import shutil | ||
1681 | 31 | import sys | ||
1682 | 32 | import subprocess | ||
1683 | 33 | from gettext import gettext as _ | ||
1684 | 34 | from aptsources.sourceslist import SourcesList | ||
1685 | 35 | |||
1686 | 36 | from .utils import get_dist, url_downloadable, country_mirror | ||
1687 | 37 | |||
1688 | 38 | class DistUpgradeFetcherCore(object): | ||
1689 | 39 | " base class (without GUI) for the upgrade fetcher " | ||
1690 | 40 | |||
1691 | 41 | DEFAULT_MIRROR="http://archive.ubuntu.com/ubuntu" | ||
1692 | 42 | DEFAULT_COMPONENT="main" | ||
1693 | 43 | DEBUG = "DEBUG_UPDATE_MANAGER" in os.environ | ||
1694 | 44 | |||
1695 | 45 | def __init__(self, new_dist, progress): | ||
1696 | 46 | self.new_dist = new_dist | ||
1697 | 47 | self.current_dist_name = get_dist() | ||
1698 | 48 | self._progress = progress | ||
1699 | 49 | # options to pass to the release upgrader when it is run | ||
1700 | 50 | self.run_options = [] | ||
1701 | 51 | |||
1702 | 52 | def _debug(self, msg): | ||
1703 | 53 | " helper to show debug information " | ||
1704 | 54 | if self.DEBUG: | ||
1705 | 55 | sys.stderr.write(msg+"\n") | ||
1706 | 56 | |||
1707 | 57 | def showReleaseNotes(self): | ||
1708 | 58 | return True | ||
1709 | 59 | |||
1710 | 60 | def error(self, summary, message): | ||
1711 | 61 | """ dummy implementation for error display, should be overwriten | ||
1712 | 62 | by subclasses that want to more fancy method | ||
1713 | 63 | """ | ||
1714 | 64 | print(summary) | ||
1715 | 65 | print(message) | ||
1716 | 66 | return False | ||
1717 | 67 | |||
1718 | 68 | def authenticate(self): | ||
1719 | 69 | if self.new_dist.upgradeToolSig: | ||
1720 | 70 | f = self.tmpdir+"/"+os.path.basename(self.new_dist.upgradeTool) | ||
1721 | 71 | sig = self.tmpdir+"/"+os.path.basename(self.new_dist.upgradeToolSig) | ||
1722 | 72 | print(_("authenticate '%(file)s' against '%(signature)s' ") % { | ||
1723 | 73 | 'file' : os.path.basename(f), | ||
1724 | 74 | 'signature' : os.path.basename(sig)}) | ||
1725 | 75 | if self.gpgauthenticate(f, sig): | ||
1726 | 76 | return True | ||
1727 | 77 | return False | ||
1728 | 78 | |||
1729 | 79 | def gpgauthenticate(self, file, signature, | ||
1730 | 80 | keyring='/etc/apt/trusted.gpg'): | ||
1731 | 81 | """ authenticated a file against a given signature, if no keyring | ||
1732 | 82 | is given use the apt default keyring | ||
1733 | 83 | """ | ||
1734 | 84 | status_pipe = os.pipe() | ||
1735 | 85 | logger_pipe = os.pipe() | ||
1736 | 86 | gpg = [ | ||
1737 | 87 | "gpg", | ||
1738 | 88 | "--status-fd", "%d" % status_pipe[1], | ||
1739 | 89 | "--logger-fd", "%d" % logger_pipe[1], | ||
1740 | 90 | "--no-options", | ||
1741 | 91 | "--homedir", self.tmpdir, | ||
1742 | 92 | "--no-default-keyring", | ||
1743 | 93 | "--ignore-time-conflict", | ||
1744 | 94 | "--keyring", keyring, | ||
1745 | 95 | "--verify", signature, file, | ||
1746 | 96 | ] | ||
1747 | 97 | def gpg_preexec(): | ||
1748 | 98 | os.close(status_pipe[0]) | ||
1749 | 99 | os.close(logger_pipe[0]) | ||
1750 | 100 | proc = subprocess.Popen( | ||
1751 | 101 | gpg, stderr=subprocess.PIPE, preexec_fn=gpg_preexec, | ||
1752 | 102 | close_fds=False, universal_newlines=True) | ||
1753 | 103 | os.close(status_pipe[1]) | ||
1754 | 104 | os.close(logger_pipe[1]) | ||
1755 | 105 | status_handle = os.fdopen(status_pipe[0]) | ||
1756 | 106 | logger_handle = os.fdopen(logger_pipe[0]) | ||
1757 | 107 | try: | ||
1758 | 108 | gpgres = status_handle.read() | ||
1759 | 109 | ret = proc.wait() | ||
1760 | 110 | if ret != 0: | ||
1761 | 111 | # gnupg returned a problem (non-zero exit) | ||
1762 | 112 | print("gpg exited %d" % ret) | ||
1763 | 113 | print("Debug information: ") | ||
1764 | 114 | print(status_handle.read()) | ||
1765 | 115 | print(proc.stderr.read()) | ||
1766 | 116 | print(logger_handle.read()) | ||
1767 | 117 | return False | ||
1768 | 118 | if "VALIDSIG" in gpgres: | ||
1769 | 119 | return True | ||
1770 | 120 | print("invalid result from gpg:") | ||
1771 | 121 | print(gpgres) | ||
1772 | 122 | return False | ||
1773 | 123 | finally: | ||
1774 | 124 | status_handle.close() | ||
1775 | 125 | proc.stderr.close() | ||
1776 | 126 | logger_handle.close() | ||
1777 | 127 | |||
1778 | 128 | def extractDistUpgrader(self): | ||
1779 | 129 | # extract the tarbal | ||
1780 | 130 | fname = os.path.join(self.tmpdir,os.path.basename(self.uri)) | ||
1781 | 131 | print(_("extracting '%s'") % os.path.basename(fname)) | ||
1782 | 132 | if not os.path.exists(fname): | ||
1783 | 133 | return False | ||
1784 | 134 | try: | ||
1785 | 135 | tar = tarfile.open(self.tmpdir+"/"+os.path.basename(self.uri),"r") | ||
1786 | 136 | for tarinfo in tar: | ||
1787 | 137 | tar.extract(tarinfo) | ||
1788 | 138 | tar.close() | ||
1789 | 139 | except tarfile.ReadError as e: | ||
1790 | 140 | logging.error("failed to open tarfile (%s)" % e) | ||
1791 | 141 | return False | ||
1792 | 142 | return True | ||
1793 | 143 | |||
1794 | 144 | def verifyDistUprader(self): | ||
1795 | 145 | # FIXME: check a internal dependency file to make sure | ||
1796 | 146 | # that the script will run correctly | ||
1797 | 147 | |||
1798 | 148 | # see if we have a script file that we can run | ||
1799 | 149 | self.script = script = "%s/%s" % (self.tmpdir, self.new_dist.name) | ||
1800 | 150 | if not os.path.exists(script): | ||
1801 | 151 | return self.error(_("Could not run the upgrade tool"), | ||
1802 | 152 | _("Could not run the upgrade tool") + ". " + _("This is most likely a bug in the upgrade tool. " | ||
1803 | 153 | "Please report it as a bug using the command 'ubuntu-bug update-manager'.")) | ||
1804 | 154 | return True | ||
1805 | 155 | |||
1806 | 156 | def mirror_from_sources_list(self, uri, default_uri): | ||
1807 | 157 | """ | ||
1808 | 158 | try to figure what the mirror is from current sources.list | ||
1809 | 159 | |||
1810 | 160 | do this by looing for matching DEFAULT_COMPONENT, current dist | ||
1811 | 161 | in sources.list and then doing a http HEAD/ftp size request | ||
1812 | 162 | to see if the uri is available on this server | ||
1813 | 163 | """ | ||
1814 | 164 | self._debug("mirror_from_sources_list: %s" % self.current_dist_name) | ||
1815 | 165 | sources = SourcesList(withMatcher=False) | ||
1816 | 166 | seen = set() | ||
1817 | 167 | for e in sources.list: | ||
1818 | 168 | if e.disabled or e.invalid or not e.type == "deb": | ||
1819 | 169 | continue | ||
1820 | 170 | # check if we probed this mirror already | ||
1821 | 171 | if e.uri in seen: | ||
1822 | 172 | continue | ||
1823 | 173 | # we are using the main mirror already, so we are fine | ||
1824 | 174 | if (e.uri.startswith(default_uri) and | ||
1825 | 175 | e.dist == self.current_dist_name and | ||
1826 | 176 | self.DEFAULT_COMPONENT in e.comps): | ||
1827 | 177 | return uri | ||
1828 | 178 | elif (e.dist == self.current_dist_name and | ||
1829 | 179 | "main" in e.comps): | ||
1830 | 180 | mirror_uri = e.uri+uri[len(default_uri):] | ||
1831 | 181 | if url_downloadable(mirror_uri, self._debug): | ||
1832 | 182 | return mirror_uri | ||
1833 | 183 | seen.add(e.uri) | ||
1834 | 184 | self._debug("no mirror found") | ||
1835 | 185 | return "" | ||
1836 | 186 | |||
1837 | 187 | def _expandUri(self, uri): | ||
1838 | 188 | """ | ||
1839 | 189 | expand the uri so that it uses a mirror if the url starts | ||
1840 | 190 | with a well know string (like archive.ubuntu.com) | ||
1841 | 191 | """ | ||
1842 | 192 | # try to guess the mirror from the sources.list | ||
1843 | 193 | if uri.startswith(self.DEFAULT_MIRROR): | ||
1844 | 194 | self._debug("trying to find suitable mirror") | ||
1845 | 195 | new_uri = self.mirror_from_sources_list(uri, self.DEFAULT_MIRROR) | ||
1846 | 196 | if new_uri: | ||
1847 | 197 | return new_uri | ||
1848 | 198 | # if that fails, use old method | ||
1849 | 199 | uri_template = Template(uri) | ||
1850 | 200 | m = country_mirror() | ||
1851 | 201 | new_uri = uri_template.safe_substitute(countrymirror=m) | ||
1852 | 202 | # be paranoid and check if the given uri is really downloadable | ||
1853 | 203 | try: | ||
1854 | 204 | if not url_downloadable(new_uri, self._debug): | ||
1855 | 205 | raise Exception("failed to download %s" % new_uri) | ||
1856 | 206 | except Exception as e: | ||
1857 | 207 | self._debug("url '%s' could not be downloaded" % e) | ||
1858 | 208 | # else fallback to main server | ||
1859 | 209 | new_uri = uri_template.safe_substitute(countrymirror='') | ||
1860 | 210 | return new_uri | ||
1861 | 211 | |||
1862 | 212 | def fetchDistUpgrader(self): | ||
1863 | 213 | " download the tarball with the upgrade script " | ||
1864 | 214 | self.tmpdir = tmpdir = tempfile.mkdtemp(prefix="update-manager-") | ||
1865 | 215 | os.chdir(tmpdir) | ||
1866 | 216 | logging.debug("using tmpdir: '%s'" % tmpdir) | ||
1867 | 217 | # turn debugging on here (if required) | ||
1868 | 218 | if self.DEBUG > 0: | ||
1869 | 219 | apt_pkg.config.set("Debug::Acquire::http","1") | ||
1870 | 220 | apt_pkg.config.set("Debug::Acquire::ftp","1") | ||
1871 | 221 | #os.listdir(tmpdir) | ||
1872 | 222 | fetcher = apt_pkg.Acquire(self._progress) | ||
1873 | 223 | if self.new_dist.upgradeToolSig != None: | ||
1874 | 224 | uri = self._expandUri(self.new_dist.upgradeToolSig) | ||
1875 | 225 | af1 = apt_pkg.AcquireFile(fetcher, | ||
1876 | 226 | uri, | ||
1877 | 227 | descr=_("Upgrade tool signature")) | ||
1878 | 228 | # reference it here to shut pyflakes up | ||
1879 | 229 | af1 | ||
1880 | 230 | if self.new_dist.upgradeTool != None: | ||
1881 | 231 | self.uri = self._expandUri(self.new_dist.upgradeTool) | ||
1882 | 232 | af2 = apt_pkg.AcquireFile(fetcher, | ||
1883 | 233 | self.uri, | ||
1884 | 234 | descr=_("Upgrade tool")) | ||
1885 | 235 | # reference it here to shut pyflakes up | ||
1886 | 236 | af2 | ||
1887 | 237 | result = fetcher.run() | ||
1888 | 238 | if result != fetcher.RESULT_CONTINUE: | ||
1889 | 239 | logging.warn("fetch result != continue (%s)" % result) | ||
1890 | 240 | return False | ||
1891 | 241 | # check that both files are really there and non-null | ||
1892 | 242 | for f in [os.path.basename(self.new_dist.upgradeToolSig), | ||
1893 | 243 | os.path.basename(self.new_dist.upgradeTool)]: | ||
1894 | 244 | if not (os.path.exists(f) and os.path.getsize(f) > 0): | ||
1895 | 245 | logging.warn("file '%s' missing" % f) | ||
1896 | 246 | return False | ||
1897 | 247 | return True | ||
1898 | 248 | return False | ||
1899 | 249 | |||
1900 | 250 | def runDistUpgrader(self): | ||
1901 | 251 | args = [self.script]+self.run_options | ||
1902 | 252 | if os.getuid() != 0: | ||
1903 | 253 | os.execv("/usr/bin/sudo",["sudo"]+args) | ||
1904 | 254 | else: | ||
1905 | 255 | os.execv(self.script,args) | ||
1906 | 256 | |||
1907 | 257 | def cleanup(self): | ||
1908 | 258 | # cleanup | ||
1909 | 259 | os.chdir("..") | ||
1910 | 260 | # del tmpdir | ||
1911 | 261 | shutil.rmtree(self.tmpdir) | ||
1912 | 262 | |||
1913 | 263 | def run(self): | ||
1914 | 264 | # see if we have release notes | ||
1915 | 265 | if not self.showReleaseNotes(): | ||
1916 | 266 | return | ||
1917 | 267 | if not self.fetchDistUpgrader(): | ||
1918 | 268 | self.error(_("Failed to fetch"), | ||
1919 | 269 | _("Fetching the upgrade failed. There may be a network " | ||
1920 | 270 | "problem. ")) | ||
1921 | 271 | return | ||
1922 | 272 | if not self.authenticate(): | ||
1923 | 273 | self.error(_("Authentication failed"), | ||
1924 | 274 | _("Authenticating the upgrade failed. There may be a problem " | ||
1925 | 275 | "with the network or with the server. ")) | ||
1926 | 276 | self.cleanup() | ||
1927 | 277 | return | ||
1928 | 278 | if not self.extractDistUpgrader(): | ||
1929 | 279 | self.error(_("Failed to extract"), | ||
1930 | 280 | _("Extracting the upgrade failed. There may be a problem " | ||
1931 | 281 | "with the network or with the server. ")) | ||
1932 | 282 | |||
1933 | 283 | return | ||
1934 | 284 | if not self.verifyDistUprader(): | ||
1935 | 285 | self.error(_("Verification failed"), | ||
1936 | 286 | _("Verifying the upgrade failed. There may be a problem " | ||
1937 | 287 | "with the network or with the server. ")) | ||
1938 | 288 | self.cleanup() | ||
1939 | 289 | return | ||
1940 | 290 | try: | ||
1941 | 291 | # check if we can execute, if we run it via sudo we will | ||
1942 | 292 | # not know otherwise, sudo/gksu will not raise a exception | ||
1943 | 293 | if not os.access(self.script, os.X_OK): | ||
1944 | 294 | ex = OSError("Can not execute '%s'" % self.script) | ||
1945 | 295 | ex.errno = 13 | ||
1946 | 296 | raise ex | ||
1947 | 297 | self.runDistUpgrader() | ||
1948 | 298 | except OSError as e: | ||
1949 | 299 | if e.errno == 13: | ||
1950 | 300 | self.error(_("Can not run the upgrade"), | ||
1951 | 301 | _("This usually is caused by a system where /tmp " | ||
1952 | 302 | "is mounted noexec. Please remount without " | ||
1953 | 303 | "noexec and run the upgrade again.")) | ||
1954 | 304 | return False | ||
1955 | 305 | else: | ||
1956 | 306 | self.error(_("Can not run the upgrade"), | ||
1957 | 307 | _("The error message is '%s'.") % e.strerror) | ||
1958 | 308 | return True | ||
1959 | 309 | |||
1960 | 310 | if __name__ == "__main__": | ||
1961 | 311 | d = DistUpgradeFetcherCore(None,None) | ||
1962 | 312 | # print(d.authenticate('/tmp/Release','/tmp/Release.gpg')) | ||
1963 | 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")) | ||
1964 | 314 | 0 | ||
1965 | === removed file 'UpdateManager/Core/MetaRelease.py' | |||
1966 | --- UpdateManager/Core/MetaRelease.py 2012-06-15 20:13:15 +0000 | |||
1967 | +++ UpdateManager/Core/MetaRelease.py 1970-01-01 00:00:00 +0000 | |||
1968 | @@ -1,350 +0,0 @@ | |||
1969 | 1 | # MetaRelease.py | ||
1970 | 2 | # | ||
1971 | 3 | # Copyright (c) 2004,2005 Canonical | ||
1972 | 4 | # | ||
1973 | 5 | # Author: Michael Vogt <michael.vogt@ubuntu.com> | ||
1974 | 6 | # | ||
1975 | 7 | # This program is free software; you can redistribute it and/or | ||
1976 | 8 | # modify it under the terms of the GNU General Public License as | ||
1977 | 9 | # published by the Free Software Foundation; either version 2 of the | ||
1978 | 10 | # License, or (at your option) any later version. | ||
1979 | 11 | # | ||
1980 | 12 | # This program is distributed in the hope that it will be useful, | ||
1981 | 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1982 | 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1983 | 15 | # GNU General Public License for more details. | ||
1984 | 16 | # | ||
1985 | 17 | # You should have received a copy of the GNU General Public License | ||
1986 | 18 | # along with this program; if not, write to the Free Software | ||
1987 | 19 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 | ||
1988 | 20 | # USA | ||
1989 | 21 | |||
1990 | 22 | from __future__ import absolute_import, print_function | ||
1991 | 23 | |||
1992 | 24 | import apt_pkg | ||
1993 | 25 | try: | ||
1994 | 26 | import configparser | ||
1995 | 27 | except ImportError: | ||
1996 | 28 | import ConfigParser as configparser | ||
1997 | 29 | try: | ||
1998 | 30 | from http.client import BadStatusLine | ||
1999 | 31 | except ImportError: | ||
2000 | 32 | from httplib import BadStatusLine | ||
2001 | 33 | import logging | ||
2002 | 34 | import email.utils | ||
2003 | 35 | import os | ||
2004 | 36 | import sys | ||
2005 | 37 | import time | ||
2006 | 38 | import threading | ||
2007 | 39 | try: | ||
2008 | 40 | from urllib.request import Request, urlopen | ||
2009 | 41 | from urllib.error import HTTPError, URLError | ||
2010 | 42 | except ImportError: | ||
2011 | 43 | from urllib2 import HTTPError, Request, URLError, urlopen | ||
2012 | 44 | |||
2013 | 45 | from .utils import get_lang, get_dist, get_dist_version, get_ubuntu_flavor, get_ubuntu_flavor_name | ||
2014 | 46 | |||
2015 | 47 | class Dist(object): | ||
2016 | 48 | def __init__(self, name, version, date, supported): | ||
2017 | 49 | self.name = name | ||
2018 | 50 | self.version = version | ||
2019 | 51 | self.date = date | ||
2020 | 52 | self.supported = supported | ||
2021 | 53 | self.releaseNotesURI = None | ||
2022 | 54 | self.releaseNotesHtmlUri = None | ||
2023 | 55 | self.upgradeTool = None | ||
2024 | 56 | self.upgradeToolSig = None | ||
2025 | 57 | # the server may report that the upgrade is broken currently | ||
2026 | 58 | self.upgrade_broken = None | ||
2027 | 59 | |||
2028 | 60 | class MetaReleaseCore(object): | ||
2029 | 61 | """ | ||
2030 | 62 | A MetaReleaseCore object astracts the list of released | ||
2031 | 63 | distributions. | ||
2032 | 64 | """ | ||
2033 | 65 | |||
2034 | 66 | DEBUG = "DEBUG_UPDATE_MANAGER" in os.environ | ||
2035 | 67 | |||
2036 | 68 | # some constants | ||
2037 | 69 | CONF = "/etc/update-manager/release-upgrades" | ||
2038 | 70 | CONF_METARELEASE = "/etc/update-manager/meta-release" | ||
2039 | 71 | |||
2040 | 72 | def __init__(self, | ||
2041 | 73 | useDevelopmentRelease=False, | ||
2042 | 74 | useProposed=False, | ||
2043 | 75 | forceLTS=False, | ||
2044 | 76 | forceDownload=False): | ||
2045 | 77 | self._debug("MetaRelease.__init__() useDevel=%s useProposed=%s" % (useDevelopmentRelease, useProposed)) | ||
2046 | 78 | # force download instead of sending if-modified-since | ||
2047 | 79 | self.forceDownload = forceDownload | ||
2048 | 80 | # information about the available dists | ||
2049 | 81 | self.downloading = True | ||
2050 | 82 | self.upgradable_to = None | ||
2051 | 83 | self.new_dist = None | ||
2052 | 84 | self.flavor_name = get_ubuntu_flavor_name() | ||
2053 | 85 | self.current_dist_name = get_dist() | ||
2054 | 86 | self.current_dist_version = get_dist_version() | ||
2055 | 87 | self.no_longer_supported = None | ||
2056 | 88 | |||
2057 | 89 | # default (if the conf file is missing) | ||
2058 | 90 | self.METARELEASE_URI = "http://changelogs.ubuntu.com/meta-release" | ||
2059 | 91 | self.METARELEASE_URI_LTS = "http://changelogs.ubuntu.com/meta-release-lts" | ||
2060 | 92 | self.METARELEASE_URI_UNSTABLE_POSTFIX = "-development" | ||
2061 | 93 | self.METARELEASE_URI_PROPOSED_POSTFIX = "-development" | ||
2062 | 94 | |||
2063 | 95 | # check the meta-release config first | ||
2064 | 96 | parser = configparser.ConfigParser() | ||
2065 | 97 | if os.path.exists(self.CONF_METARELEASE): | ||
2066 | 98 | try: | ||
2067 | 99 | parser.read(self.CONF_METARELEASE) | ||
2068 | 100 | except configparser.Error as e: | ||
2069 | 101 | sys.stderr.write("ERROR: failed to read '%s':\n%s" % ( | ||
2070 | 102 | self.CONF_METARELEASE, e)) | ||
2071 | 103 | return | ||
2072 | 104 | # make changing the metarelease file and the location | ||
2073 | 105 | # for the files easy | ||
2074 | 106 | if parser.has_section("METARELEASE"): | ||
2075 | 107 | sec = "METARELEASE" | ||
2076 | 108 | for k in ["URI", | ||
2077 | 109 | "URI_LTS", | ||
2078 | 110 | "URI_UNSTABLE_POSTFIX", | ||
2079 | 111 | "URI_PROPOSED_POSTFIX"]: | ||
2080 | 112 | if parser.has_option(sec, k): | ||
2081 | 113 | self._debug("%s: %s " % (self.CONF_METARELEASE, | ||
2082 | 114 | parser.get(sec,k))) | ||
2083 | 115 | setattr(self, "%s_%s" % (sec, k), parser.get(sec, k)) | ||
2084 | 116 | |||
2085 | 117 | # check the config file first to figure if we want lts upgrades only | ||
2086 | 118 | parser = configparser.ConfigParser() | ||
2087 | 119 | if os.path.exists(self.CONF): | ||
2088 | 120 | try: | ||
2089 | 121 | parser.read(self.CONF) | ||
2090 | 122 | except configparser.Error as e: | ||
2091 | 123 | sys.stderr.write("ERROR: failed to read '%s':\n%s" % ( | ||
2092 | 124 | self.CONF, e)) | ||
2093 | 125 | return | ||
2094 | 126 | # now check which specific url to use | ||
2095 | 127 | if parser.has_option("DEFAULT","Prompt"): | ||
2096 | 128 | type = parser.get("DEFAULT","Prompt").lower() | ||
2097 | 129 | if (type == "never" or type == "no"): | ||
2098 | 130 | # nothing to do for this object | ||
2099 | 131 | # FIXME: what about no longer supported? | ||
2100 | 132 | self.downloading = False | ||
2101 | 133 | return | ||
2102 | 134 | elif type == "lts": | ||
2103 | 135 | self.METARELEASE_URI = self.METARELEASE_URI_LTS | ||
2104 | 136 | # needed for the _tryUpgradeSelf() code in DistUpgradeController | ||
2105 | 137 | if forceLTS: | ||
2106 | 138 | self.METARELEASE_URI = self.METARELEASE_URI_LTS | ||
2107 | 139 | # devel and proposed "just" change the postfix | ||
2108 | 140 | if useDevelopmentRelease: | ||
2109 | 141 | self.METARELEASE_URI += self.METARELEASE_URI_UNSTABLE_POSTFIX | ||
2110 | 142 | elif useProposed: | ||
2111 | 143 | self.METARELEASE_URI += self.METARELEASE_URI_PROPOSED_POSTFIX | ||
2112 | 144 | |||
2113 | 145 | self._debug("metarelease-uri: %s" % self.METARELEASE_URI) | ||
2114 | 146 | self.metarelease_information = None | ||
2115 | 147 | if not self._buildMetaReleaseFile(): | ||
2116 | 148 | self._debug("_buildMetaReleaseFile failed") | ||
2117 | 149 | return | ||
2118 | 150 | # we start the download thread here and we have a timeout | ||
2119 | 151 | threading.Thread(target=self.download).start() | ||
2120 | 152 | #threading.Thread(target=self.check).start() | ||
2121 | 153 | |||
2122 | 154 | def _buildMetaReleaseFile(self): | ||
2123 | 155 | # build the metarelease_file name | ||
2124 | 156 | self.METARELEASE_FILE = os.path.join("/var/lib/update-manager/", | ||
2125 | 157 | os.path.basename(self.METARELEASE_URI)) | ||
2126 | 158 | # check if we can write to the global location, if not, | ||
2127 | 159 | # write to homedir | ||
2128 | 160 | try: | ||
2129 | 161 | open(self.METARELEASE_FILE,"a") | ||
2130 | 162 | except IOError as e: | ||
2131 | 163 | cache_dir = os.getenv( | ||
2132 | 164 | "XDG_CACHE_HOME", os.path.expanduser("~/.cache")) | ||
2133 | 165 | path = os.path.join(cache_dir, 'update-manager-core') | ||
2134 | 166 | if not os.path.exists(path): | ||
2135 | 167 | try: | ||
2136 | 168 | os.mkdir(path) | ||
2137 | 169 | except OSError as e: | ||
2138 | 170 | sys.stderr.write("mkdir() failed: '%s'" % e) | ||
2139 | 171 | return False | ||
2140 | 172 | self.METARELEASE_FILE = os.path.join(path,os.path.basename(self.METARELEASE_URI)) | ||
2141 | 173 | # if it is empty, remove it to avoid I-M-S hits on empty file | ||
2142 | 174 | try: | ||
2143 | 175 | if os.path.getsize(self.METARELEASE_FILE) == 0: | ||
2144 | 176 | os.unlink(self.METARELEASE_FILE) | ||
2145 | 177 | except Exception as e: | ||
2146 | 178 | pass | ||
2147 | 179 | return True | ||
2148 | 180 | |||
2149 | 181 | def dist_no_longer_supported(self, dist): | ||
2150 | 182 | """ virtual function that is called when the distro is no longer | ||
2151 | 183 | supported | ||
2152 | 184 | """ | ||
2153 | 185 | self.no_longer_supported = dist | ||
2154 | 186 | def new_dist_available(self, dist): | ||
2155 | 187 | """ virtual function that is called when a new distro release | ||
2156 | 188 | is available | ||
2157 | 189 | """ | ||
2158 | 190 | self.new_dist = dist | ||
2159 | 191 | |||
2160 | 192 | def parse(self): | ||
2161 | 193 | self._debug("MetaRelease.parse()") | ||
2162 | 194 | current_dist_name = self.current_dist_name | ||
2163 | 195 | self._debug("current dist name: '%s'" % current_dist_name) | ||
2164 | 196 | current_dist = None | ||
2165 | 197 | dists = [] | ||
2166 | 198 | |||
2167 | 199 | # parse the metarelease_information file | ||
2168 | 200 | index_tag = apt_pkg.TagFile(self.metarelease_information) | ||
2169 | 201 | step_result = index_tag.step() | ||
2170 | 202 | while step_result: | ||
2171 | 203 | if "Dist" in index_tag.section: | ||
2172 | 204 | name = index_tag.section["Dist"] | ||
2173 | 205 | self._debug("found distro name: '%s'" % name) | ||
2174 | 206 | rawdate = index_tag.section["Date"] | ||
2175 | 207 | parseddate = list(email.utils.parsedate(rawdate)) | ||
2176 | 208 | parseddate[8] = 0 # assume no DST | ||
2177 | 209 | date = time.mktime(tuple(parseddate)) | ||
2178 | 210 | supported = int(index_tag.section["Supported"]) | ||
2179 | 211 | version = index_tag.section["Version"] | ||
2180 | 212 | # add the information to a new date object | ||
2181 | 213 | dist = Dist(name, version, date,supported) | ||
2182 | 214 | if "ReleaseNotes" in index_tag.section: | ||
2183 | 215 | dist.releaseNotesURI = index_tag.section["ReleaseNotes"] | ||
2184 | 216 | lang = get_lang() | ||
2185 | 217 | if lang: | ||
2186 | 218 | dist.releaseNotesURI += "?lang=%s" % lang | ||
2187 | 219 | if "ReleaseNotesHtml" in index_tag.section: | ||
2188 | 220 | dist.releaseNotesHtmlUri = index_tag.section["ReleaseNotesHtml"] | ||
2189 | 221 | query = self._get_release_notes_uri_query_string(dist) | ||
2190 | 222 | if query: | ||
2191 | 223 | dist.releaseNotesHtmlUri += query | ||
2192 | 224 | if "UpgradeTool" in index_tag.section: | ||
2193 | 225 | dist.upgradeTool = index_tag.section["UpgradeTool"] | ||
2194 | 226 | if "UpgradeToolSignature" in index_tag.section: | ||
2195 | 227 | dist.upgradeToolSig = index_tag.section["UpgradeToolSignature"] | ||
2196 | 228 | if "UpgradeBroken" in index_tag.section: | ||
2197 | 229 | dist.upgrade_broken = index_tag.section["UpgradeBroken"] | ||
2198 | 230 | dists.append(dist) | ||
2199 | 231 | if name == current_dist_name: | ||
2200 | 232 | current_dist = dist | ||
2201 | 233 | step_result = index_tag.step() | ||
2202 | 234 | |||
2203 | 235 | # first check if the current runing distro is in the meta-release | ||
2204 | 236 | # information. if not, we assume that we run on something not | ||
2205 | 237 | # supported and silently return | ||
2206 | 238 | if current_dist is None: | ||
2207 | 239 | self._debug("current dist not found in meta-release file\n") | ||
2208 | 240 | return False | ||
2209 | 241 | |||
2210 | 242 | # then see what we can upgrade to | ||
2211 | 243 | upgradable_to = "" | ||
2212 | 244 | for dist in dists: | ||
2213 | 245 | if dist.date > current_dist.date: | ||
2214 | 246 | upgradable_to = dist | ||
2215 | 247 | self._debug("new dist: %s" % upgradable_to) | ||
2216 | 248 | break | ||
2217 | 249 | |||
2218 | 250 | # only warn if unsupported and a new dist is available (because | ||
2219 | 251 | # the development version is also unsupported) | ||
2220 | 252 | if upgradable_to != "" and not current_dist.supported: | ||
2221 | 253 | self.upgradable_to = upgradable_to | ||
2222 | 254 | self.dist_no_longer_supported(current_dist) | ||
2223 | 255 | if upgradable_to != "": | ||
2224 | 256 | self.upgradable_to = upgradable_to | ||
2225 | 257 | self.new_dist_available(upgradable_to) | ||
2226 | 258 | |||
2227 | 259 | # parsing done and sucessfully | ||
2228 | 260 | return True | ||
2229 | 261 | |||
2230 | 262 | # the network thread that tries to fetch the meta-index file | ||
2231 | 263 | # can't touch the gui, runs as a thread | ||
2232 | 264 | def download(self): | ||
2233 | 265 | self._debug("MetaRelease.download()") | ||
2234 | 266 | lastmodified = 0 | ||
2235 | 267 | req = Request(self.METARELEASE_URI) | ||
2236 | 268 | # make sure that we always get the latest file (#107716) | ||
2237 | 269 | req.add_header("Cache-Control", "No-Cache") | ||
2238 | 270 | req.add_header("Pragma", "no-cache") | ||
2239 | 271 | if os.access(self.METARELEASE_FILE, os.W_OK): | ||
2240 | 272 | try: | ||
2241 | 273 | lastmodified = os.stat(self.METARELEASE_FILE).st_mtime | ||
2242 | 274 | except OSError as e: | ||
2243 | 275 | pass | ||
2244 | 276 | if lastmodified > 0 and not self.forceDownload: | ||
2245 | 277 | req.add_header("If-Modified-Since", time.asctime(time.gmtime(lastmodified))) | ||
2246 | 278 | try: | ||
2247 | 279 | # open | ||
2248 | 280 | uri=urlopen(req, timeout=20) | ||
2249 | 281 | # sometime there is a root owned meta-relase file | ||
2250 | 282 | # there, try to remove it so that we get it | ||
2251 | 283 | # with proper permissions | ||
2252 | 284 | if (os.path.exists(self.METARELEASE_FILE) and | ||
2253 | 285 | not os.access(self.METARELEASE_FILE,os.W_OK)): | ||
2254 | 286 | try: | ||
2255 | 287 | os.unlink(self.METARELEASE_FILE) | ||
2256 | 288 | except OSError as e: | ||
2257 | 289 | print("Can't unlink '%s' (%s)" % (self.METARELEASE_FILE, e)) | ||
2258 | 290 | # we may get exception here on e.g. disk full | ||
2259 | 291 | try: | ||
2260 | 292 | f=open(self.METARELEASE_FILE,"w+b") | ||
2261 | 293 | for line in uri.readlines(): | ||
2262 | 294 | f.write(line) | ||
2263 | 295 | f.flush() | ||
2264 | 296 | f.seek(0,0) | ||
2265 | 297 | self.metarelease_information=f | ||
2266 | 298 | except IOError as e: | ||
2267 | 299 | pass | ||
2268 | 300 | uri.close() | ||
2269 | 301 | # http error | ||
2270 | 302 | except HTTPError as e: | ||
2271 | 303 | # mvo: only reuse local info on "not-modified" | ||
2272 | 304 | if e.code == 304 and os.path.exists(self.METARELEASE_FILE): | ||
2273 | 305 | self._debug("reading file '%s'" % self.METARELEASE_FILE) | ||
2274 | 306 | self.metarelease_information=open(self.METARELEASE_FILE,"r") | ||
2275 | 307 | else: | ||
2276 | 308 | self._debug("result of meta-release download: '%s'" % e) | ||
2277 | 309 | # generic network error | ||
2278 | 310 | except (URLError, BadStatusLine) as e: | ||
2279 | 311 | self._debug("result of meta-release download: '%s'" % e) | ||
2280 | 312 | # now check the information we have | ||
2281 | 313 | if self.metarelease_information != None: | ||
2282 | 314 | self._debug("have self.metarelease_information") | ||
2283 | 315 | try: | ||
2284 | 316 | self.parse() | ||
2285 | 317 | except: | ||
2286 | 318 | logging.exception("parse failed for '%s'" % self.METARELEASE_FILE) | ||
2287 | 319 | # no use keeping a broken file around | ||
2288 | 320 | os.remove(self.METARELEASE_FILE) | ||
2289 | 321 | # we don't want to keep a meta-release file around when it | ||
2290 | 322 | # has a "Broken" flag, this ensures we are not bitten by | ||
2291 | 323 | # I-M-S/cache issues | ||
2292 | 324 | if self.new_dist and self.new_dist.upgrade_broken: | ||
2293 | 325 | os.remove(self.METARELEASE_FILE) | ||
2294 | 326 | else: | ||
2295 | 327 | self._debug("NO self.metarelease_information") | ||
2296 | 328 | self.downloading = False | ||
2297 | 329 | |||
2298 | 330 | def _get_release_notes_uri_query_string(self, dist): | ||
2299 | 331 | q = "?" | ||
2300 | 332 | # get the lang | ||
2301 | 333 | lang = get_lang() | ||
2302 | 334 | if lang: | ||
2303 | 335 | q += "lang=%s&" % lang | ||
2304 | 336 | # get the os | ||
2305 | 337 | os = get_ubuntu_flavor() | ||
2306 | 338 | q += "os=%s&" % os | ||
2307 | 339 | # get the version to upgrade to | ||
2308 | 340 | q += "ver=%s" % dist.version | ||
2309 | 341 | return q | ||
2310 | 342 | |||
2311 | 343 | def _debug(self, msg): | ||
2312 | 344 | if self.DEBUG: | ||
2313 | 345 | sys.stderr.write(msg+"\n") | ||
2314 | 346 | |||
2315 | 347 | |||
2316 | 348 | if __name__ == "__main__": | ||
2317 | 349 | meta = MetaReleaseCore(False, False) | ||
2318 | 350 | |||
2319 | 351 | 0 | ||
2320 | === removed file 'UpdateManager/Core/MyCache.py' | |||
2321 | --- UpdateManager/Core/MyCache.py 2012-06-12 01:40:26 +0000 | |||
2322 | +++ UpdateManager/Core/MyCache.py 1970-01-01 00:00:00 +0000 | |||
2323 | @@ -1,366 +0,0 @@ | |||
2324 | 1 | # MyCache.py | ||
2325 | 2 | # | ||
2326 | 3 | # Copyright (c) 2004-2008 Canonical | ||
2327 | 4 | # | ||
2328 | 5 | # Author: Michael Vogt <mvo@debian.org> | ||
2329 | 6 | # | ||
2330 | 7 | # This program is free software; you can redistribute it and/or | ||
2331 | 8 | # modify it under the terms of the GNU General Public License as | ||
2332 | 9 | # published by the Free Software Foundation; either version 2 of the | ||
2333 | 10 | # License, or (at your option) any later version. | ||
2334 | 11 | # | ||
2335 | 12 | # This program is distributed in the hope that it will be useful, | ||
2336 | 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
2337 | 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
2338 | 15 | # GNU General Public License for more details. | ||
2339 | 16 | # | ||
2340 | 17 | # You should have received a copy of the GNU General Public License | ||
2341 | 18 | # along with this program; if not, write to the Free Software | ||
2342 | 19 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 | ||
2343 | 20 | # USA | ||
2344 | 21 | |||
2345 | 22 | from __future__ import absolute_import, print_function | ||
2346 | 23 | |||
2347 | 24 | import warnings | ||
2348 | 25 | warnings.filterwarnings("ignore", "apt API not stable yet", FutureWarning) | ||
2349 | 26 | import apt | ||
2350 | 27 | import apt_pkg | ||
2351 | 28 | import logging | ||
2352 | 29 | import os | ||
2353 | 30 | try: | ||
2354 | 31 | from urllib.error import HTTPError | ||
2355 | 32 | from urllib.request import urlopen | ||
2356 | 33 | from urllib.parse import urlsplit | ||
2357 | 34 | except ImportError: | ||
2358 | 35 | from urllib2 import HTTPError, urlopen | ||
2359 | 36 | from urlparse import urlsplit | ||
2360 | 37 | try: | ||
2361 | 38 | from http.client import BadStatusLine | ||
2362 | 39 | except ImportError: | ||
2363 | 40 | from httplib import BadStatusLine | ||
2364 | 41 | import socket | ||
2365 | 42 | import re | ||
2366 | 43 | import DistUpgrade.DistUpgradeCache | ||
2367 | 44 | from gettext import gettext as _ | ||
2368 | 45 | from .UpdateList import UpdateOrigin | ||
2369 | 46 | |||
2370 | 47 | SYNAPTIC_PINFILE = "/var/lib/synaptic/preferences" | ||
2371 | 48 | CHANGELOGS_URI="http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/%s" | ||
2372 | 49 | |||
2373 | 50 | class HttpsChangelogsUnsupportedError(Exception): | ||
2374 | 51 | """ https changelogs with credentials are unsupported because of the | ||
2375 | 52 | lack of certitifcation validation in urllib2 which allows MITM | ||
2376 | 53 | attacks to steal the credentials | ||
2377 | 54 | """ | ||
2378 | 55 | pass | ||
2379 | 56 | |||
2380 | 57 | class MyCache(DistUpgrade.DistUpgradeCache.MyCache): | ||
2381 | 58 | |||
2382 | 59 | CHANGELOG_ORIGIN = "Ubuntu" | ||
2383 | 60 | |||
2384 | 61 | def __init__(self, progress, rootdir=None): | ||
2385 | 62 | apt.Cache.__init__(self, progress, rootdir) | ||
2386 | 63 | # raise if we have packages in reqreinst state | ||
2387 | 64 | # and let the caller deal with that (runs partial upgrade) | ||
2388 | 65 | assert len(self.req_reinstall_pkgs) == 0 | ||
2389 | 66 | # check if the dpkg journal is ok (we need to do that here | ||
2390 | 67 | # too because libapt will only do it when it tries to lock | ||
2391 | 68 | # the packaging system) | ||
2392 | 69 | assert(not self._dpkgJournalDirty()) | ||
2393 | 70 | # init the regular cache | ||
2394 | 71 | self._initDepCache() | ||
2395 | 72 | self.all_changes = {} | ||
2396 | 73 | self.all_news = {} | ||
2397 | 74 | # on broken packages, try to fix via saveDistUpgrade() | ||
2398 | 75 | if self._depcache.broken_count > 0: | ||
2399 | 76 | self.saveDistUpgrade() | ||
2400 | 77 | assert (self._depcache.broken_count == 0 and | ||
2401 | 78 | self._depcache.del_count == 0) | ||
2402 | 79 | |||
2403 | 80 | def _dpkgJournalDirty(self): | ||
2404 | 81 | """ | ||
2405 | 82 | test if the dpkg journal is dirty | ||
2406 | 83 | (similar to debSystem::CheckUpdates) | ||
2407 | 84 | """ | ||
2408 | 85 | d = os.path.dirname( | ||
2409 | 86 | apt_pkg.config.find_file("Dir::State::status"))+"/updates" | ||
2410 | 87 | for f in os.listdir(d): | ||
2411 | 88 | if re.match("[0-9]+", f): | ||
2412 | 89 | return True | ||
2413 | 90 | return False | ||
2414 | 91 | |||
2415 | 92 | def _initDepCache(self): | ||
2416 | 93 | #apt_pkg.config.set("Debug::pkgPolicy","1") | ||
2417 | 94 | #self.depcache = apt_pkg.GetDepCache(self.cache) | ||
2418 | 95 | #self._depcache = apt_pkg.GetDepCache(self._cache) | ||
2419 | 96 | self._depcache.read_pinfile() | ||
2420 | 97 | if os.path.exists(SYNAPTIC_PINFILE): | ||
2421 | 98 | self._depcache.read_pinfile(SYNAPTIC_PINFILE) | ||
2422 | 99 | self._depcache.init() | ||
2423 | 100 | def clear(self): | ||
2424 | 101 | self._initDepCache() | ||
2425 | 102 | @property | ||
2426 | 103 | def required_download(self): | ||
2427 | 104 | """ get the size of the packages that are required to download """ | ||
2428 | 105 | pm = apt_pkg.PackageManager(self._depcache) | ||
2429 | 106 | fetcher = apt_pkg.Acquire() | ||
2430 | 107 | pm.get_archives(fetcher, self._list, self._records) | ||
2431 | 108 | return fetcher.fetch_needed | ||
2432 | 109 | @property | ||
2433 | 110 | def install_count(self): | ||
2434 | 111 | return self._depcache.inst_count | ||
2435 | 112 | def keep_count(self): | ||
2436 | 113 | return self._depcache.keep_count | ||
2437 | 114 | def saveDistUpgrade(self): | ||
2438 | 115 | """ this functions mimics a upgrade but will never remove anything """ | ||
2439 | 116 | #self._apply_dselect_upgrade() | ||
2440 | 117 | self._depcache.upgrade(True) | ||
2441 | 118 | wouldDelete = self._depcache.del_count | ||
2442 | 119 | if self._depcache.del_count > 0: | ||
2443 | 120 | self.clear() | ||
2444 | 121 | assert self._depcache.broken_count == 0 and self._depcache.del_count == 0 | ||
2445 | 122 | #self._apply_dselect_upgrade() | ||
2446 | 123 | self._depcache.upgrade() | ||
2447 | 124 | return wouldDelete | ||
2448 | 125 | def match_package_origin(self, pkg, matcher): | ||
2449 | 126 | """ match 'pkg' origin against 'matcher', take versions between | ||
2450 | 127 | installed.version and candidate.version into account too | ||
2451 | 128 | Useful if installed pkg A v1.0 is available in both | ||
2452 | 129 | -updates (as v1.2) and -security (v1.1). we want to display | ||
2453 | 130 | it as a security update then | ||
2454 | 131 | """ | ||
2455 | 132 | inst_ver = pkg._pkg.current_ver | ||
2456 | 133 | cand_ver = self._depcache.get_candidate_ver(pkg._pkg) | ||
2457 | 134 | # init matcher with candidate.version | ||
2458 | 135 | update_origin = matcher[(None,None)] | ||
2459 | 136 | verFileIter = None | ||
2460 | 137 | for (verFileIter,index) in cand_ver.file_list: | ||
2461 | 138 | if (verFileIter.archive, verFileIter.origin) in matcher: | ||
2462 | 139 | indexfile = pkg._pcache._list.find_index(verFileIter) | ||
2463 | 140 | if indexfile: # and indexfile.IsTrusted: | ||
2464 | 141 | match = matcher[verFileIter.archive, verFileIter.origin] | ||
2465 | 142 | update_origin = match | ||
2466 | 143 | break | ||
2467 | 144 | else: | ||
2468 | 145 | # add a node for each origin/archive combination | ||
2469 | 146 | if verFileIter and verFileIter.origin and verFileIter.archive: | ||
2470 | 147 | matcher[verFileIter.archive, verFileIter.origin] = UpdateOrigin(_("Other updates (%s)") % verFileIter.origin, 0) | ||
2471 | 148 | update_origin = matcher[verFileIter.archive, verFileIter.origin] | ||
2472 | 149 | # if the candidate comes from a unknown source (e.g. a PPA) skip | ||
2473 | 150 | # skip the shadow logic below as it would put e.g. a PPA package | ||
2474 | 151 | # in "Recommended updates" when the version in the PPA | ||
2475 | 152 | # is higher than the one in %s-updates | ||
2476 | 153 | if update_origin.importance <= 0: | ||
2477 | 154 | return update_origin | ||
2478 | 155 | # for known packages, check if we have higher versions that | ||
2479 | 156 | # "shadow" this one | ||
2480 | 157 | for ver in pkg._pkg.version_list: | ||
2481 | 158 | # discard is < than installed ver | ||
2482 | 159 | if (inst_ver and | ||
2483 | 160 | apt_pkg.version_compare(ver.ver_str, inst_ver.ver_str) <= 0): | ||
2484 | 161 | #print("skipping '%s' " % ver.ver_str) | ||
2485 | 162 | continue | ||
2486 | 163 | # check if we have a match | ||
2487 | 164 | for(verFileIter,index) in ver.file_list: | ||
2488 | 165 | if (verFileIter.archive, verFileIter.origin) in matcher: | ||
2489 | 166 | indexfile = pkg._pcache._list.find_index(verFileIter) | ||
2490 | 167 | if indexfile: # and indexfile.IsTrusted: | ||
2491 | 168 | match = matcher[verFileIter.archive, verFileIter.origin] | ||
2492 | 169 | if match.importance > update_origin.importance: | ||
2493 | 170 | update_origin = match | ||
2494 | 171 | return update_origin | ||
2495 | 172 | |||
2496 | 173 | def _strip_epoch(self, verstr): | ||
2497 | 174 | " strip of the epoch " | ||
2498 | 175 | l = verstr.split(":") | ||
2499 | 176 | if len(l) > 1: | ||
2500 | 177 | verstr = "".join(l[1:]) | ||
2501 | 178 | return verstr | ||
2502 | 179 | |||
2503 | 180 | def _get_changelog_or_news(self, name, fname, strict_versioning=False, changelogs_uri=None): | ||
2504 | 181 | " helper that fetches the file in question " | ||
2505 | 182 | # don't touch the gui in this function, it needs to be thread-safe | ||
2506 | 183 | pkg = self[name] | ||
2507 | 184 | |||
2508 | 185 | # get the src package name | ||
2509 | 186 | srcpkg = pkg.candidate.source_name | ||
2510 | 187 | |||
2511 | 188 | # assume "main" section | ||
2512 | 189 | src_section = "main" | ||
2513 | 190 | # use the section of the candidate as a starting point | ||
2514 | 191 | section = pkg._pcache._depcache.get_candidate_ver(pkg._pkg).section | ||
2515 | 192 | |||
2516 | 193 | # get the source version, start with the binaries version | ||
2517 | 194 | srcver_epoch = pkg.candidate.version | ||
2518 | 195 | srcver = self._strip_epoch(srcver_epoch) | ||
2519 | 196 | #print("bin: %s" % binver) | ||
2520 | 197 | |||
2521 | 198 | l = section.split("/") | ||
2522 | 199 | if len(l) > 1: | ||
2523 | 200 | src_section = l[0] | ||
2524 | 201 | |||
2525 | 202 | # lib is handled special | ||
2526 | 203 | prefix = srcpkg[0] | ||
2527 | 204 | if srcpkg.startswith("lib"): | ||
2528 | 205 | prefix = "lib" + srcpkg[3] | ||
2529 | 206 | |||
2530 | 207 | # the changelogs_uri argument overrides the default changelogs_uri, | ||
2531 | 208 | # this is useful for e.g. PPAs where we construct the changelogs | ||
2532 | 209 | # path differently | ||
2533 | 210 | if changelogs_uri: | ||
2534 | 211 | uri = changelogs_uri | ||
2535 | 212 | else: | ||
2536 | 213 | uri = CHANGELOGS_URI % (src_section,prefix,srcpkg,srcpkg, srcver, fname) | ||
2537 | 214 | |||
2538 | 215 | # https uris are not supported when they contain a username/password | ||
2539 | 216 | # because the urllib2 https implementation will not check certificates | ||
2540 | 217 | # and so its possible to do a man-in-the-middle attack to steal the | ||
2541 | 218 | # credentials | ||
2542 | 219 | res = urlsplit(uri) | ||
2543 | 220 | if res.scheme == "https" and res.username != "": | ||
2544 | 221 | raise HttpsChangelogsUnsupportedError( | ||
2545 | 222 | "https locations with username/password are not" | ||
2546 | 223 | "supported to fetch changelogs") | ||
2547 | 224 | |||
2548 | 225 | # print("Trying: %s " % uri) | ||
2549 | 226 | changelog = urlopen(uri) | ||
2550 | 227 | #print(changelog.read()) | ||
2551 | 228 | # do only get the lines that are new | ||
2552 | 229 | alllines = "" | ||
2553 | 230 | regexp = "^%s \((.*)\)(.*)$" % (re.escape(srcpkg)) | ||
2554 | 231 | |||
2555 | 232 | while True: | ||
2556 | 233 | line = changelog.readline().decode("UTF-8", "replace") | ||
2557 | 234 | if line == "": | ||
2558 | 235 | break | ||
2559 | 236 | match = re.match(regexp,line) | ||
2560 | 237 | if match: | ||
2561 | 238 | # strip epoch from installed version | ||
2562 | 239 | # and from changelog too | ||
2563 | 240 | installed = getattr(pkg.installed, "version", None) | ||
2564 | 241 | if installed and ":" in installed: | ||
2565 | 242 | installed = installed.split(":",1)[1] | ||
2566 | 243 | changelogver = match.group(1) | ||
2567 | 244 | if changelogver and ":" in changelogver: | ||
2568 | 245 | changelogver = changelogver.split(":",1)[1] | ||
2569 | 246 | # we test for "==" here for changelogs | ||
2570 | 247 | # to ensure that the version | ||
2571 | 248 | # is actually really in the changelog - if not | ||
2572 | 249 | # just display it all, this catches cases like: | ||
2573 | 250 | # gcc-defaults with "binver=4.3.1" and srcver=1.76 | ||
2574 | 251 | # | ||
2575 | 252 | # for NEWS.Debian we do require the changelogver > installed | ||
2576 | 253 | if strict_versioning: | ||
2577 | 254 | if (installed and | ||
2578 | 255 | apt_pkg.version_compare(changelogver,installed)<0): | ||
2579 | 256 | break | ||
2580 | 257 | else: | ||
2581 | 258 | if (installed and | ||
2582 | 259 | apt_pkg.version_compare(changelogver,installed)==0): | ||
2583 | 260 | break | ||
2584 | 261 | alllines = alllines + line | ||
2585 | 262 | return alllines | ||
2586 | 263 | |||
2587 | 264 | def _guess_third_party_changelogs_uri_by_source(self, name): | ||
2588 | 265 | pkg = self[name] | ||
2589 | 266 | deb_uri = pkg.candidate.uri | ||
2590 | 267 | if deb_uri is None: | ||
2591 | 268 | return None | ||
2592 | 269 | srcrec = pkg.candidate.record.get("Source") | ||
2593 | 270 | if not srcrec: | ||
2594 | 271 | return None | ||
2595 | 272 | # srcpkg can be "apt" or "gcc-default (1.0)" | ||
2596 | 273 | srcpkg = srcrec.split("(")[0].strip() | ||
2597 | 274 | if "(" in srcrec: | ||
2598 | 275 | srcver = srcrec.split("(")[1].rstrip(")") | ||
2599 | 276 | else: | ||
2600 | 277 | srcver = pkg.candidate.version | ||
2601 | 278 | base_uri = deb_uri.rpartition("/")[0] | ||
2602 | 279 | return base_uri + "/%s_%s.changelog" % (srcpkg, srcver) | ||
2603 | 280 | |||
2604 | 281 | def _guess_third_party_changelogs_uri_by_binary(self, name): | ||
2605 | 282 | """ guess changelogs uri based on ArchiveURI by replacing .deb | ||
2606 | 283 | with .changelog | ||
2607 | 284 | """ | ||
2608 | 285 | # there is always a pkg and a pkg.candidate, no need to add | ||
2609 | 286 | # check here | ||
2610 | 287 | pkg = self[name] | ||
2611 | 288 | deb_uri = pkg.candidate.uri | ||
2612 | 289 | if deb_uri: | ||
2613 | 290 | return "%s.changelog" % deb_uri.rsplit(".", 1)[0] | ||
2614 | 291 | return None | ||
2615 | 292 | |||
2616 | 293 | |||
2617 | 294 | def get_news_and_changelog(self, name, lock): | ||
2618 | 295 | self.get_news(name) | ||
2619 | 296 | self.get_changelog(name) | ||
2620 | 297 | try: | ||
2621 | 298 | lock.release() | ||
2622 | 299 | except: | ||
2623 | 300 | pass | ||
2624 | 301 | |||
2625 | 302 | def get_news(self, name): | ||
2626 | 303 | " get the NEWS.Debian file from the changelogs location " | ||
2627 | 304 | try: | ||
2628 | 305 | news = self._get_changelog_or_news(name, "NEWS.Debian", True) | ||
2629 | 306 | except Exception: | ||
2630 | 307 | return | ||
2631 | 308 | if news: | ||
2632 | 309 | self.all_news[name] = news | ||
2633 | 310 | |||
2634 | 311 | def _fetch_changelog_for_third_party_package(self, name): | ||
2635 | 312 | # Try non official changelog location | ||
2636 | 313 | changelogs_uri_binary = self._guess_third_party_changelogs_uri_by_binary(name) | ||
2637 | 314 | changelogs_uri_source = self._guess_third_party_changelogs_uri_by_source(name) | ||
2638 | 315 | error_message = "" | ||
2639 | 316 | for changelogs_uri in [changelogs_uri_binary,changelogs_uri_source]: | ||
2640 | 317 | if changelogs_uri: | ||
2641 | 318 | try: | ||
2642 | 319 | changelog = self._get_changelog_or_news( | ||
2643 | 320 | name, "changelog", False, changelogs_uri) | ||
2644 | 321 | self.all_changes[name] += changelog | ||
2645 | 322 | except (HTTPError, HttpsChangelogsUnsupportedError): | ||
2646 | 323 | # no changelogs_uri or 404 | ||
2647 | 324 | error_message = _( | ||
2648 | 325 | "This update does not come from a " | ||
2649 | 326 | "source that supports changelogs.") | ||
2650 | 327 | except (IOError, BadStatusLine, socket.error): | ||
2651 | 328 | # network errors and others | ||
2652 | 329 | logging.exception("error on changelog fetching") | ||
2653 | 330 | error_message = _( | ||
2654 | 331 | "Failed to download the list of changes. \n" | ||
2655 | 332 | "Please check your Internet connection.") | ||
2656 | 333 | self.all_changes[name] += error_message | ||
2657 | 334 | |||
2658 | 335 | def get_changelog(self, name): | ||
2659 | 336 | " get the changelog file from the changelog location " | ||
2660 | 337 | origins = self[name].candidate.origins | ||
2661 | 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) | ||
2662 | 339 | if not self.CHANGELOG_ORIGIN in [o.origin for o in origins]: | ||
2663 | 340 | self._fetch_changelog_for_third_party_package(name) | ||
2664 | 341 | return | ||
2665 | 342 | # fixup epoch handling version | ||
2666 | 343 | srcpkg = self[name].candidate.source_name | ||
2667 | 344 | srcver_epoch = self[name].candidate.version.replace(':', '%3A') | ||
2668 | 345 | try: | ||
2669 | 346 | changelog = self._get_changelog_or_news(name, "changelog") | ||
2670 | 347 | if len(changelog) == 0: | ||
2671 | 348 | changelog = _("The changelog does not contain any relevant changes.\n\n" | ||
2672 | 349 | "Please use http://launchpad.net/ubuntu/+source/%s/%s/+changelog\n" | ||
2673 | 350 | "until the changes become available or try again " | ||
2674 | 351 | "later.") % (srcpkg, srcver_epoch) | ||
2675 | 352 | except HTTPError as e: | ||
2676 | 353 | changelog = _("The list of changes is not available yet.\n\n" | ||
2677 | 354 | "Please use http://launchpad.net/ubuntu/+source/%s/%s/+changelog\n" | ||
2678 | 355 | "until the changes become available or try again " | ||
2679 | 356 | "later.") % (srcpkg, srcver_epoch) | ||
2680 | 357 | except (IOError, BadStatusLine, socket.error) as e: | ||
2681 | 358 | print("caught exception: ", e) | ||
2682 | 359 | changelog = _("Failed to download the list " | ||
2683 | 360 | "of changes. \nPlease " | ||
2684 | 361 | "check your Internet " | ||
2685 | 362 | "connection.") | ||
2686 | 363 | self.all_changes[name] += changelog | ||
2687 | 364 | |||
2688 | 365 | |||
2689 | 366 | |||
2690 | 367 | 0 | ||
2691 | === removed file 'UpdateManager/Core/UpdateList.py' | |||
2692 | --- UpdateManager/Core/UpdateList.py 2012-06-12 13:17:46 +0000 | |||
2693 | +++ UpdateManager/Core/UpdateList.py 1970-01-01 00:00:00 +0000 | |||
2694 | @@ -1,102 +0,0 @@ | |||
2695 | 1 | # UpdateList.py | ||
2696 | 2 | # | ||
2697 | 3 | # Copyright (c) 2004-2008 Canonical | ||
2698 | 4 | # | ||
2699 | 5 | # Author: Michael Vogt <mvo@debian.org> | ||
2700 | 6 | # | ||
2701 | 7 | # This program is free software; you can redistribute it and/or | ||
2702 | 8 | # modify it under the terms of the GNU General Public License as | ||
2703 | 9 | # published by the Free Software Foundation; either version 2 of the | ||
2704 | 10 | # License, or (at your option) any later version. | ||
2705 | 11 | # | ||
2706 | 12 | # This program is distributed in the hope that it will be useful, | ||
2707 | 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
2708 | 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
2709 | 15 | # GNU General Public License for more details. | ||
2710 | 16 | # | ||
2711 | 17 | # You should have received a copy of the GNU General Public License | ||
2712 | 18 | # along with this program; if not, write to the Free Software | ||
2713 | 19 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 | ||
2714 | 20 | # USA | ||
2715 | 21 | |||
2716 | 22 | from __future__ import print_function | ||
2717 | 23 | |||
2718 | 24 | import warnings | ||
2719 | 25 | warnings.filterwarnings("ignore", "Accessed deprecated property", DeprecationWarning) | ||
2720 | 26 | |||
2721 | 27 | from gettext import gettext as _ | ||
2722 | 28 | import operator | ||
2723 | 29 | import subprocess | ||
2724 | 30 | import sys | ||
2725 | 31 | |||
2726 | 32 | class UpdateOrigin(object): | ||
2727 | 33 | def __init__(self, desc, importance): | ||
2728 | 34 | self.packages = [] | ||
2729 | 35 | self.importance = importance | ||
2730 | 36 | self.description = desc | ||
2731 | 37 | |||
2732 | 38 | class UpdateList(object): | ||
2733 | 39 | """ | ||
2734 | 40 | class that contains the list of available updates in | ||
2735 | 41 | self.pkgs[origin] where origin is the user readable string | ||
2736 | 42 | """ | ||
2737 | 43 | |||
2738 | 44 | def __init__(self, parent): | ||
2739 | 45 | # a map of packages under their origin | ||
2740 | 46 | try: | ||
2741 | 47 | dist = subprocess.check_output( | ||
2742 | 48 | ["lsb_release", "-c", "-s"], universal_newlines=True).strip() | ||
2743 | 49 | except subprocess.CalledProcessError as e: | ||
2744 | 50 | print("Error in lsb_release: %s" % e) | ||
2745 | 51 | parent.error(_("Failed to detect distribution"), | ||
2746 | 52 | _("A error '%s' occurred while checking what system " | ||
2747 | 53 | "you are using.") % e) | ||
2748 | 54 | sys.exit(1) | ||
2749 | 55 | self.distUpgradeWouldDelete = 0 | ||
2750 | 56 | self.pkgs = {} | ||
2751 | 57 | self.num_updates = 0 | ||
2752 | 58 | self.matcher = self.initMatcher(dist) | ||
2753 | 59 | |||
2754 | 60 | def initMatcher(self, dist): | ||
2755 | 61 | # (origin, archive, description, importance) | ||
2756 | 62 | matcher_templates = [ | ||
2757 | 63 | ("%s-security" % dist, "Ubuntu", _("Important security updates"),10), | ||
2758 | 64 | ("%s-updates" % dist, "Ubuntu", _("Recommended updates"), 9), | ||
2759 | 65 | ("%s-proposed" % dist, "Ubuntu", _("Proposed updates"), 8), | ||
2760 | 66 | ("%s-backports" % dist, "Ubuntu", _("Backports"), 7), | ||
2761 | 67 | (dist, "Ubuntu", _("Distribution updates"), 6) | ||
2762 | 68 | ] | ||
2763 | 69 | matcher = {} | ||
2764 | 70 | for (origin, archive, desc, importance) in matcher_templates: | ||
2765 | 71 | matcher[(origin, archive)] = UpdateOrigin(desc, importance) | ||
2766 | 72 | matcher[(None,None)] = UpdateOrigin(_("Other updates"), -1) | ||
2767 | 73 | return matcher | ||
2768 | 74 | |||
2769 | 75 | def update(self, cache): | ||
2770 | 76 | self.held_back = [] | ||
2771 | 77 | |||
2772 | 78 | # do the upgrade | ||
2773 | 79 | self.distUpgradeWouldDelete = cache.saveDistUpgrade() | ||
2774 | 80 | |||
2775 | 81 | #dselect_upgrade_origin = UpdateOrigin(_("Previous selected"), 1) | ||
2776 | 82 | |||
2777 | 83 | # sort by origin | ||
2778 | 84 | for pkg in cache: | ||
2779 | 85 | if pkg.is_upgradable or pkg.marked_install: | ||
2780 | 86 | if getattr(pkg.candidate, "origins", None) == None: | ||
2781 | 87 | # can happen for e.g. locked packages | ||
2782 | 88 | # FIXME: do something more sensible here (but what?) | ||
2783 | 89 | print("WARNING: upgradable but no candidate.origins?!?: ", pkg.name) | ||
2784 | 90 | continue | ||
2785 | 91 | # check where the package belongs | ||
2786 | 92 | origin_node = cache.match_package_origin(pkg, self.matcher) | ||
2787 | 93 | if origin_node not in self.pkgs: | ||
2788 | 94 | self.pkgs[origin_node] = [] | ||
2789 | 95 | self.pkgs[origin_node].append(pkg) | ||
2790 | 96 | self.num_updates = self.num_updates + 1 | ||
2791 | 97 | if pkg.is_upgradable and not (pkg.marked_upgrade or pkg.marked_install): | ||
2792 | 98 | self.held_back.append(pkg.name) | ||
2793 | 99 | for l in self.pkgs.keys(): | ||
2794 | 100 | self.pkgs[l].sort(key=operator.attrgetter("name")) | ||
2795 | 101 | self.keepcount = cache._depcache.keep_count | ||
2796 | 102 | |||
2797 | 103 | 0 | ||
2798 | === removed file 'UpdateManager/Core/__init__.py' | |||
2799 | === removed file 'UpdateManager/Core/roam.py' | |||
2800 | --- UpdateManager/Core/roam.py 2012-05-01 00:29:04 +0000 | |||
2801 | +++ UpdateManager/Core/roam.py 1970-01-01 00:00:00 +0000 | |||
2802 | @@ -1,205 +0,0 @@ | |||
2803 | 1 | # utils.py | ||
2804 | 2 | # | ||
2805 | 3 | # Copyright (c) 2011 Canonical | ||
2806 | 4 | # | ||
2807 | 5 | # Author: Alex Chiang <achiang@canonical.com> | ||
2808 | 6 | # Michael Vogt <michael.vogt@ubuntu.com> | ||
2809 | 7 | # | ||
2810 | 8 | # This program is free software; you can redistribute it and/or | ||
2811 | 9 | # modify it under the terms of the GNU General Public License as | ||
2812 | 10 | # published by the Free Software Foundation; either version 2 of the | ||
2813 | 11 | # License, or (at your option) any later version. | ||
2814 | 12 | # | ||
2815 | 13 | # This program is distributed in the hope that it will be useful, | ||
2816 | 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
2817 | 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
2818 | 16 | # GNU General Public License for more details. | ||
2819 | 17 | # | ||
2820 | 18 | # You should have received a copy of the GNU General Public License | ||
2821 | 19 | # along with this program; if not, write to the Free Software | ||
2822 | 20 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 | ||
2823 | 21 | # USA | ||
2824 | 22 | |||
2825 | 23 | |||
2826 | 24 | from __future__ import print_function | ||
2827 | 25 | |||
2828 | 26 | import dbus | ||
2829 | 27 | import sys | ||
2830 | 28 | |||
2831 | 29 | class ModemManagerHelper(object): | ||
2832 | 30 | |||
2833 | 31 | # data taken from | ||
2834 | 32 | # http://projects.gnome.org/NetworkManager/developers/mm-spec-04.html | ||
2835 | 33 | MM_DBUS_IFACE = "org.freedesktop.ModemManager" | ||
2836 | 34 | MM_DBUS_IFACE_MODEM = MM_DBUS_IFACE + ".Modem" | ||
2837 | 35 | |||
2838 | 36 | # MM_MODEM_TYPE | ||
2839 | 37 | MM_MODEM_TYPE_GSM = 1 | ||
2840 | 38 | MM_MODEM_TYPE_CDMA = 2 | ||
2841 | 39 | |||
2842 | 40 | # GSM | ||
2843 | 41 | # Not registered, not searching for new operator to register. | ||
2844 | 42 | MM_MODEM_GSM_NETWORK_REG_STATUS_IDLE = 0 | ||
2845 | 43 | # Registered on home network. | ||
2846 | 44 | MM_MODEM_GSM_NETWORK_REG_STATUS_HOME = 1 | ||
2847 | 45 | # Not registered, searching for new operator to register with. | ||
2848 | 46 | MM_MODEM_GSM_NETWORK_REG_STATUS_SEARCHING = 2 | ||
2849 | 47 | # Registration denied. | ||
2850 | 48 | MM_MODEM_GSM_NETWORK_REG_STATUS_DENIED = 3 | ||
2851 | 49 | # Unknown registration status. | ||
2852 | 50 | MM_MODEM_GSM_NETWORK_REG_STATUS_UNKNOWN = 4 | ||
2853 | 51 | # Registered on a roaming network. | ||
2854 | 52 | MM_MODEM_GSM_NETWORK_REG_STATUS_ROAMING = 5 | ||
2855 | 53 | |||
2856 | 54 | # CDMA | ||
2857 | 55 | # Registration status is unknown or the device is not registered. | ||
2858 | 56 | MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN = 0 | ||
2859 | 57 | # Registered, but roaming status is unknown or cannot be provided | ||
2860 | 58 | # by the device. The device may or may not be roaming. | ||
2861 | 59 | MM_MODEM_CDMA_REGISTRATION_STATE_REGISTERED = 1 | ||
2862 | 60 | # Currently registered on the home network. | ||
2863 | 61 | MM_MODEM_CDMA_REGISTRATION_STATE_HOME = 2 | ||
2864 | 62 | # Currently registered on a roaming network. | ||
2865 | 63 | MM_MODEM_CDMA_REGISTRATION_STATE_ROAMING = 3 | ||
2866 | 64 | |||
2867 | 65 | def __init__(self): | ||
2868 | 66 | self.bus = dbus.SystemBus() | ||
2869 | 67 | self.proxy = self.bus.get_object("org.freedesktop.ModemManager", | ||
2870 | 68 | "/org/freedesktop/ModemManager") | ||
2871 | 69 | modem_manager = dbus.Interface(self.proxy, self.MM_DBUS_IFACE) | ||
2872 | 70 | self.modems = modem_manager.EnumerateDevices() | ||
2873 | 71 | |||
2874 | 72 | @staticmethod | ||
2875 | 73 | def get_dbus_property(proxy, interface, property): | ||
2876 | 74 | props = dbus.Interface(proxy, "org.freedesktop.DBus.Properties") | ||
2877 | 75 | property = props.Get(interface, property) | ||
2878 | 76 | return property | ||
2879 | 77 | |||
2880 | 78 | def is_gsm_roaming(self): | ||
2881 | 79 | for m in self.modems: | ||
2882 | 80 | dev = self.bus.get_object(self.MM_DBUS_IFACE, m) | ||
2883 | 81 | type = self.get_dbus_property(dev, self.MM_DBUS_IFACE_MODEM, "Type") | ||
2884 | 82 | if type != self.MM_MODEM_TYPE_GSM: | ||
2885 | 83 | continue | ||
2886 | 84 | net = dbus.Interface(dev, self.MM_DBUS_IFACE_MODEM + ".Gsm.Network") | ||
2887 | 85 | reg = net.GetRegistrationInfo() | ||
2888 | 86 | # Be conservative about roaming. If registration unknown, | ||
2889 | 87 | # assume yes. | ||
2890 | 88 | # MM_MODEM_GSM_NETWORK_REG_STATUS | ||
2891 | 89 | if reg[0] in (self.MM_MODEM_GSM_NETWORK_REG_STATUS_UNKNOWN, | ||
2892 | 90 | self.MM_MODEM_GSM_NETWORK_REG_STATUS_ROAMING): | ||
2893 | 91 | return True | ||
2894 | 92 | return False | ||
2895 | 93 | |||
2896 | 94 | def is_cdma_roaming(self): | ||
2897 | 95 | for m in self.modems: | ||
2898 | 96 | dev = self.bus.get_object(self.MM_DBUS_IFACE, m) | ||
2899 | 97 | type = self.get_dbus_property(dev, self.MM_DBUS_IFACE_MODEM, "Type") | ||
2900 | 98 | if type != self.MM_MODEM_TYPE_CDMA: | ||
2901 | 99 | continue | ||
2902 | 100 | cdma = dbus.Interface(dev, self.MM_DBUS_IFACE_MODEM + ".Cdma") | ||
2903 | 101 | (cmda_1x, evdo) = cdma.GetRegistrationState() | ||
2904 | 102 | # Be conservative about roaming. If registration unknown, | ||
2905 | 103 | # assume yes. | ||
2906 | 104 | # MM_MODEM_CDMA_REGISTRATION_STATE | ||
2907 | 105 | roaming_states = (self.MM_MODEM_CDMA_REGISTRATION_STATE_REGISTERED, | ||
2908 | 106 | self.MM_MODEM_CDMA_REGISTRATION_STATE_ROAMING) | ||
2909 | 107 | # evdo trumps cmda_1x (thanks to Mathieu Trudel-Lapierre) | ||
2910 | 108 | if evdo in roaming_states: | ||
2911 | 109 | return True | ||
2912 | 110 | elif cmda_1x in roaming_states: | ||
2913 | 111 | return True | ||
2914 | 112 | return False | ||
2915 | 113 | |||
2916 | 114 | class NetworkManagerHelper(object): | ||
2917 | 115 | NM_DBUS_IFACE = "org.freedesktop.NetworkManager" | ||
2918 | 116 | |||
2919 | 117 | # connection states | ||
2920 | 118 | # Old enum values are for NM 0.7 | ||
2921 | 119 | |||
2922 | 120 | # The NetworkManager daemon is in an unknown state. | ||
2923 | 121 | NM_STATE_UNKNOWN = 0 | ||
2924 | 122 | # The NetworkManager daemon is connecting a device. | ||
2925 | 123 | NM_STATE_CONNECTING_OLD = 2 | ||
2926 | 124 | NM_STATE_CONNECTING = 40 | ||
2927 | 125 | NM_STATE_CONNECTING_LIST = [NM_STATE_CONNECTING_OLD, | ||
2928 | 126 | NM_STATE_CONNECTING] | ||
2929 | 127 | # The NetworkManager daemon is connected. | ||
2930 | 128 | NM_STATE_CONNECTED_OLD = 3 | ||
2931 | 129 | NM_STATE_CONNECTED_LOCAL = 50 | ||
2932 | 130 | NM_STATE_CONNECTED_SITE = 60 | ||
2933 | 131 | NM_STATE_CONNECTED_GLOBAL = 70 | ||
2934 | 132 | NM_STATE_CONNECTED_LIST = [NM_STATE_CONNECTED_OLD, | ||
2935 | 133 | NM_STATE_CONNECTED_LOCAL, | ||
2936 | 134 | NM_STATE_CONNECTED_SITE, | ||
2937 | 135 | NM_STATE_CONNECTED_GLOBAL] | ||
2938 | 136 | |||
2939 | 137 | # The device type is unknown. | ||
2940 | 138 | NM_DEVICE_TYPE_UNKNOWN = 0 | ||
2941 | 139 | # The device is wired Ethernet device. | ||
2942 | 140 | NM_DEVICE_TYPE_ETHERNET = 1 | ||
2943 | 141 | # The device is an 802.11 WiFi device. | ||
2944 | 142 | NM_DEVICE_TYPE_WIFI = 2 | ||
2945 | 143 | # The device is a GSM-based cellular WAN device. | ||
2946 | 144 | NM_DEVICE_TYPE_GSM = 3 | ||
2947 | 145 | # The device is a CDMA/IS-95-based cellular WAN device. | ||
2948 | 146 | NM_DEVICE_TYPE_CDMA = 4 | ||
2949 | 147 | |||
2950 | 148 | def __init__(self): | ||
2951 | 149 | self.bus = dbus.SystemBus() | ||
2952 | 150 | self.proxy = self.bus.get_object("org.freedesktop.NetworkManager", | ||
2953 | 151 | "/org/freedesktop/NetworkManager") | ||
2954 | 152 | |||
2955 | 153 | @staticmethod | ||
2956 | 154 | def get_dbus_property(proxy, interface, property): | ||
2957 | 155 | props = dbus.Interface(proxy, "org.freedesktop.DBus.Properties") | ||
2958 | 156 | property = props.Get(interface, property) | ||
2959 | 157 | return property | ||
2960 | 158 | |||
2961 | 159 | def is_active_connection_gsm_or_cdma(self): | ||
2962 | 160 | res = False | ||
2963 | 161 | actives = self.get_dbus_property( | ||
2964 | 162 | self.proxy, self.NM_DBUS_IFACE, 'ActiveConnections') | ||
2965 | 163 | for a in actives: | ||
2966 | 164 | active = self.bus.get_object(self.NM_DBUS_IFACE, a) | ||
2967 | 165 | default_route = self.get_dbus_property( | ||
2968 | 166 | active, self.NM_DBUS_IFACE + ".Connection.Active", 'Default') | ||
2969 | 167 | if not default_route: | ||
2970 | 168 | continue | ||
2971 | 169 | devs = self.get_dbus_property( | ||
2972 | 170 | active, self.NM_DBUS_IFACE + ".Connection.Active", 'Devices') | ||
2973 | 171 | for d in devs: | ||
2974 | 172 | dev = self.bus.get_object(self.NM_DBUS_IFACE, d) | ||
2975 | 173 | type = self.get_dbus_property( | ||
2976 | 174 | dev, self.NM_DBUS_IFACE + ".Device", 'DeviceType') | ||
2977 | 175 | if type == self.NM_DEVICE_TYPE_GSM: | ||
2978 | 176 | return True | ||
2979 | 177 | elif type == self.NM_DEVICE_TYPE_CDMA: | ||
2980 | 178 | return True | ||
2981 | 179 | else: | ||
2982 | 180 | continue | ||
2983 | 181 | return res | ||
2984 | 182 | |||
2985 | 183 | def is_active_connection_gsm_or_cdma_roaming(self): | ||
2986 | 184 | res = False | ||
2987 | 185 | if self.is_active_connection_gsm_or_cdma(): | ||
2988 | 186 | mmhelper = ModemManagerHelper() | ||
2989 | 187 | res |= mmhelper.is_gsm_roaming() | ||
2990 | 188 | res |= mmhelper.is_cdma_roaming() | ||
2991 | 189 | return res | ||
2992 | 190 | |||
2993 | 191 | if __name__ == "__main__": | ||
2994 | 192 | |||
2995 | 193 | # test code | ||
2996 | 194 | if sys.argv[1:] and sys.argv[1] == "--test": | ||
2997 | 195 | mmhelper = ModemManagerHelper() | ||
2998 | 196 | print("is_gsm_roaming", mmhelper.is_gsm_roaming()) | ||
2999 | 197 | print("is_cdma_romaing", mmhelper.is_cdma_roaming()) | ||
3000 | 198 | |||
3001 | 199 | # roaming? | ||
3002 | 200 | nmhelper = NetworkManagerHelper() | ||
3003 | 201 | is_roaming = nmhelper.is_active_connection_gsm_or_cdma_roaming() | ||
3004 | 202 | print("roam: ", is_roaming) | ||
3005 | 203 | if is_roaming: | ||
3006 | 204 | sys.exit(1) | ||
3007 | 205 | sys.exit(0) | ||
3008 | 206 | 0 | ||
3009 | === removed file 'UpdateManager/Core/utils.py' | |||
3010 | --- UpdateManager/Core/utils.py 2012-06-15 20:13:15 +0000 | |||
3011 | +++ UpdateManager/Core/utils.py 1970-01-01 00:00:00 +0000 | |||
3012 | @@ -1,510 +0,0 @@ | |||
3013 | 1 | # utils.py | ||
3014 | 2 | # | ||
3015 | 3 | # Copyright (c) 2004-2008 Canonical | ||
3016 | 4 | # | ||
3017 | 5 | # Author: Michael Vogt <mvo@debian.org> | ||
3018 | 6 | # | ||
3019 | 7 | # This program is free software; you can redistribute it and/or | ||
3020 | 8 | # modify it under the terms of the GNU General Public License as | ||
3021 | 9 | # published by the Free Software Foundation; either version 2 of the | ||
3022 | 10 | # License, or (at your option) any later version. | ||
3023 | 11 | # | ||
3024 | 12 | # This program is distributed in the hope that it will be useful, | ||
3025 | 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
3026 | 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
3027 | 15 | # GNU General Public License for more details. | ||
3028 | 16 | # | ||
3029 | 17 | # You should have received a copy of the GNU General Public License | ||
3030 | 18 | # along with this program; if not, write to the Free Software | ||
3031 | 19 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 | ||
3032 | 20 | # USA | ||
3033 | 21 | |||
3034 | 22 | from __future__ import print_function | ||
3035 | 23 | |||
3036 | 24 | from gettext import gettext as _ | ||
3037 | 25 | from gettext import ngettext | ||
3038 | 26 | from stat import (S_IMODE, ST_MODE, S_IXUSR) | ||
3039 | 27 | from math import ceil | ||
3040 | 28 | |||
3041 | 29 | import apt_pkg | ||
3042 | 30 | apt_pkg.init_config() | ||
3043 | 31 | |||
3044 | 32 | import locale | ||
3045 | 33 | import logging | ||
3046 | 34 | import re | ||
3047 | 35 | import os | ||
3048 | 36 | import glob | ||
3049 | 37 | import subprocess | ||
3050 | 38 | import sys | ||
3051 | 39 | import time | ||
3052 | 40 | try: | ||
3053 | 41 | from urllib.request import ( | ||
3054 | 42 | ProxyHandler, | ||
3055 | 43 | Request, | ||
3056 | 44 | build_opener, | ||
3057 | 45 | install_opener, | ||
3058 | 46 | urlopen, | ||
3059 | 47 | ) | ||
3060 | 48 | from urllib.parse import urlsplit | ||
3061 | 49 | except ImportError: | ||
3062 | 50 | from urllib2 import ( | ||
3063 | 51 | ProxyHandler, | ||
3064 | 52 | Request, | ||
3065 | 53 | build_opener, | ||
3066 | 54 | install_opener, | ||
3067 | 55 | urlopen, | ||
3068 | 56 | ) | ||
3069 | 57 | from urlparse import urlsplit | ||
3070 | 58 | |||
3071 | 59 | from copy import copy | ||
3072 | 60 | |||
3073 | 61 | |||
3074 | 62 | class ExecutionTime(object): | ||
3075 | 63 | """ | ||
3076 | 64 | Helper that can be used in with statements to have a simple | ||
3077 | 65 | measure of the timing of a particular block of code, e.g. | ||
3078 | 66 | with ExecutionTime("db flush"): | ||
3079 | 67 | db.flush() | ||
3080 | 68 | """ | ||
3081 | 69 | def __init__(self, info=""): | ||
3082 | 70 | self.info = info | ||
3083 | 71 | def __enter__(self): | ||
3084 | 72 | self.now = time.time() | ||
3085 | 73 | def __exit__(self, type, value, stack): | ||
3086 | 74 | print("%s: %s" % (self.info, time.time() - self.now)) | ||
3087 | 75 | |||
3088 | 76 | def get_string_with_no_auth_from_source_entry(entry): | ||
3089 | 77 | tmp = copy(entry) | ||
3090 | 78 | url_parts = urlsplit(tmp.uri) | ||
3091 | 79 | if url_parts.username: | ||
3092 | 80 | tmp.uri = tmp.uri.replace(url_parts.username, "hidden-u") | ||
3093 | 81 | if url_parts.password: | ||
3094 | 82 | tmp.uri = tmp.uri.replace(url_parts.password, "hidden-p") | ||
3095 | 83 | return str(tmp) | ||
3096 | 84 | |||
3097 | 85 | def estimate_kernel_size_in_boot(): | ||
3098 | 86 | """ estimate the amount of space that the current kernel takes in /boot """ | ||
3099 | 87 | size = 0 | ||
3100 | 88 | kver = os.uname()[2] | ||
3101 | 89 | for f in glob.glob("/boot/*%s*" % kver): | ||
3102 | 90 | size += os.path.getsize(f) | ||
3103 | 91 | return size | ||
3104 | 92 | |||
3105 | 93 | def is_unity_running(): | ||
3106 | 94 | """ return True if Unity is currently running """ | ||
3107 | 95 | unity_running = False | ||
3108 | 96 | try: | ||
3109 | 97 | import dbus | ||
3110 | 98 | bus = dbus.SessionBus() | ||
3111 | 99 | unity_running = bus.name_has_owner("com.canonical.Unity") | ||
3112 | 100 | except: | ||
3113 | 101 | logging.exception("could not check for Unity dbus service") | ||
3114 | 102 | return unity_running | ||
3115 | 103 | |||
3116 | 104 | def is_child_of_process_name(processname, pid=None): | ||
3117 | 105 | if not pid: | ||
3118 | 106 | pid = os.getpid() | ||
3119 | 107 | while pid > 0: | ||
3120 | 108 | stat_file = "/proc/%s/stat" % pid | ||
3121 | 109 | with open(stat_file) as stat_f: | ||
3122 | 110 | stat = stat_f.read() | ||
3123 | 111 | # extract command (inside ()) | ||
3124 | 112 | command = stat.partition("(")[2].partition(")")[0] | ||
3125 | 113 | if command == processname: | ||
3126 | 114 | return True | ||
3127 | 115 | # get parent (second to the right of command) and check that next | ||
3128 | 116 | pid = int(stat.partition(")")[2].split()[1]) | ||
3129 | 117 | return False | ||
3130 | 118 | |||
3131 | 119 | def inside_chroot(): | ||
3132 | 120 | """ returns True if we are inside a chroot | ||
3133 | 121 | """ | ||
3134 | 122 | # if there is no proc or no pid 1 we are very likely inside a chroot | ||
3135 | 123 | if not os.path.exists("/proc") or not os.path.exists("/proc/1"): | ||
3136 | 124 | return True | ||
3137 | 125 | # if the inode is differnt for pid 1 "/" and our "/" | ||
3138 | 126 | return os.stat("/") != os.stat("/proc/1/root") | ||
3139 | 127 | |||
3140 | 128 | def wrap(t, width=70, subsequent_indent=""): | ||
3141 | 129 | """ helpers inspired after textwrap - unfortunately | ||
3142 | 130 | we can not use textwrap directly because it break | ||
3143 | 131 | packagenames with "-" in them into new lines | ||
3144 | 132 | """ | ||
3145 | 133 | out = "" | ||
3146 | 134 | for s in t.split(): | ||
3147 | 135 | if (len(out)-out.rfind("\n")) + len(s) > width: | ||
3148 | 136 | out += "\n" + subsequent_indent | ||
3149 | 137 | out += s + " " | ||
3150 | 138 | return out | ||
3151 | 139 | |||
3152 | 140 | def twrap(s, **kwargs): | ||
3153 | 141 | msg = "" | ||
3154 | 142 | paras = s.split("\n") | ||
3155 | 143 | for par in paras: | ||
3156 | 144 | s = wrap(par, **kwargs) | ||
3157 | 145 | msg += s+"\n" | ||
3158 | 146 | return msg | ||
3159 | 147 | |||
3160 | 148 | def lsmod(): | ||
3161 | 149 | " return list of loaded modules (or [] if lsmod is not found) " | ||
3162 | 150 | modules=[] | ||
3163 | 151 | # FIXME raise? | ||
3164 | 152 | if not os.path.exists("/sbin/lsmod"): | ||
3165 | 153 | return [] | ||
3166 | 154 | p=subprocess.Popen(["/sbin/lsmod"], stdout=subprocess.PIPE, | ||
3167 | 155 | universal_newlines=True) | ||
3168 | 156 | lines=p.communicate()[0].split("\n") | ||
3169 | 157 | # remove heading line: "Modules Size Used by" | ||
3170 | 158 | del lines[0] | ||
3171 | 159 | # add lines to list, skip empty lines | ||
3172 | 160 | for line in lines: | ||
3173 | 161 | if line: | ||
3174 | 162 | modules.append(line.split()[0]) | ||
3175 | 163 | return modules | ||
3176 | 164 | |||
3177 | 165 | def check_and_fix_xbit(path): | ||
3178 | 166 | " check if a given binary has the executable bit and if not, add it" | ||
3179 | 167 | if not os.path.exists(path): | ||
3180 | 168 | return | ||
3181 | 169 | mode = S_IMODE(os.stat(path)[ST_MODE]) | ||
3182 | 170 | if not ((mode & S_IXUSR) == S_IXUSR): | ||
3183 | 171 | os.chmod(path, mode | S_IXUSR) | ||
3184 | 172 | |||
3185 | 173 | def country_mirror(): | ||
3186 | 174 | " helper to get the country mirror from the current locale " | ||
3187 | 175 | # special cases go here | ||
3188 | 176 | lang_mirror = { 'c' : '', | ||
3189 | 177 | } | ||
3190 | 178 | # no lang, no mirror | ||
3191 | 179 | if not 'LANG' in os.environ: | ||
3192 | 180 | return '' | ||
3193 | 181 | lang = os.environ['LANG'].lower() | ||
3194 | 182 | # check if it is a special case | ||
3195 | 183 | if lang[:5] in lang_mirror: | ||
3196 | 184 | return lang_mirror[lang[:5]] | ||
3197 | 185 | # now check for the most comon form (en_US.UTF-8) | ||
3198 | 186 | if "_" in lang: | ||
3199 | 187 | country = lang.split(".")[0].split("_")[1] | ||
3200 | 188 | if "@" in country: | ||
3201 | 189 | country = country.split("@")[0] | ||
3202 | 190 | return country+"." | ||
3203 | 191 | else: | ||
3204 | 192 | return lang[:2]+"." | ||
3205 | 193 | return '' | ||
3206 | 194 | |||
3207 | 195 | def get_dist(): | ||
3208 | 196 | " return the codename of the current runing distro " | ||
3209 | 197 | # support debug overwrite | ||
3210 | 198 | dist = os.environ.get("META_RELEASE_FAKE_CODENAME") | ||
3211 | 199 | if dist: | ||
3212 | 200 | logging.warn("using fake release name '%s' (because of META_RELEASE_FAKE_CODENAME environment) " % dist) | ||
3213 | 201 | return dist | ||
3214 | 202 | # then check the real one | ||
3215 | 203 | from subprocess import Popen, PIPE | ||
3216 | 204 | p = Popen(["lsb_release","-c","-s"], stdout=PIPE, universal_newlines=True) | ||
3217 | 205 | res = p.wait() | ||
3218 | 206 | if res != 0: | ||
3219 | 207 | sys.stderr.write("lsb_release returned exitcode: %i\n" % res) | ||
3220 | 208 | return "unknown distribution" | ||
3221 | 209 | dist = p.stdout.readline().strip() | ||
3222 | 210 | p.stdout.close() | ||
3223 | 211 | return dist | ||
3224 | 212 | |||
3225 | 213 | def get_dist_version(): | ||
3226 | 214 | " return the version of the current running distro " | ||
3227 | 215 | # support debug overwrite | ||
3228 | 216 | desc = os.environ.get("META_RELEASE_FAKE_VERSION") | ||
3229 | 217 | if desc: | ||
3230 | 218 | logging.warn("using fake release version '%s' (because of META_RELEASE_FAKE_VERSION environment) " % desc) | ||
3231 | 219 | return desc | ||
3232 | 220 | # then check the real one | ||
3233 | 221 | from subprocess import Popen, PIPE | ||
3234 | 222 | p = Popen(["lsb_release","-r","-s"], stdout=PIPE, universal_newlines=True) | ||
3235 | 223 | res = p.wait() | ||
3236 | 224 | if res != 0: | ||
3237 | 225 | sys.stderr.write("lsb_release returned exitcode: %i\n" % res) | ||
3238 | 226 | return "unknown distribution" | ||
3239 | 227 | desc = p.stdout.readline().strip() | ||
3240 | 228 | p.stdout.close() | ||
3241 | 229 | return desc | ||
3242 | 230 | |||
3243 | 231 | class HeadRequest(Request): | ||
3244 | 232 | def get_method(self): | ||
3245 | 233 | return "HEAD" | ||
3246 | 234 | |||
3247 | 235 | def url_downloadable(uri, debug_func=None): | ||
3248 | 236 | """ | ||
3249 | 237 | helper that checks if the given uri exists and is downloadable | ||
3250 | 238 | (supports optional debug_func function handler to support | ||
3251 | 239 | e.g. logging) | ||
3252 | 240 | |||
3253 | 241 | Supports http (via HEAD) and ftp (via size request) | ||
3254 | 242 | """ | ||
3255 | 243 | if not debug_func: | ||
3256 | 244 | lambda x: True | ||
3257 | 245 | debug_func("url_downloadable: %s" % uri) | ||
3258 | 246 | (scheme, netloc, path, querry, fragment) = urlsplit(uri) | ||
3259 | 247 | debug_func("s='%s' n='%s' p='%s' q='%s' f='%s'" % (scheme, netloc, path, querry, fragment)) | ||
3260 | 248 | if scheme == "http": | ||
3261 | 249 | try: | ||
3262 | 250 | http_file = urlopen(HeadRequest(uri)) | ||
3263 | 251 | http_file.close() | ||
3264 | 252 | if http_file.code == 200: | ||
3265 | 253 | return True | ||
3266 | 254 | return False | ||
3267 | 255 | except Exception as e: | ||
3268 | 256 | debug_func("error from httplib: '%s'" % e) | ||
3269 | 257 | return False | ||
3270 | 258 | elif scheme == "ftp": | ||
3271 | 259 | import ftplib | ||
3272 | 260 | try: | ||
3273 | 261 | f = ftplib.FTP(netloc) | ||
3274 | 262 | f.login() | ||
3275 | 263 | f.cwd(os.path.dirname(path)) | ||
3276 | 264 | size = f.size(os.path.basename(path)) | ||
3277 | 265 | f.quit() | ||
3278 | 266 | if debug_func: | ||
3279 | 267 | debug_func("ftplib.size() returned: %s" % size) | ||
3280 | 268 | if size != 0: | ||
3281 | 269 | return True | ||
3282 | 270 | except Exception as e: | ||
3283 | 271 | if debug_func: | ||
3284 | 272 | debug_func("error from ftplib: '%s'" % e) | ||
3285 | 273 | return False | ||
3286 | 274 | return False | ||
3287 | 275 | |||
3288 | 276 | def init_proxy(gsettings=None): | ||
3289 | 277 | """ init proxy settings | ||
3290 | 278 | |||
3291 | 279 | * first check for http_proxy environment (always wins), | ||
3292 | 280 | * then check the apt.conf http proxy, | ||
3293 | 281 | * then look into synaptics conffile | ||
3294 | 282 | * then into gconf (if gconfclient was supplied) | ||
3295 | 283 | """ | ||
3296 | 284 | SYNAPTIC_CONF_FILE = "/root/.synaptic/synaptic.conf" | ||
3297 | 285 | proxy = None | ||
3298 | 286 | # generic apt config wins | ||
3299 | 287 | if apt_pkg.config.find("Acquire::http::Proxy") != '': | ||
3300 | 288 | proxy = apt_pkg.config.find("Acquire::http::Proxy") | ||
3301 | 289 | # then synaptic | ||
3302 | 290 | elif os.path.exists(SYNAPTIC_CONF_FILE): | ||
3303 | 291 | cnf = apt_pkg.Configuration() | ||
3304 | 292 | apt_pkg.read_config_file(cnf, SYNAPTIC_CONF_FILE) | ||
3305 | 293 | use_proxy = cnf.find_b("Synaptic::useProxy", False) | ||
3306 | 294 | if use_proxy: | ||
3307 | 295 | proxy_host = cnf.find("Synaptic::httpProxy") | ||
3308 | 296 | proxy_port = str(cnf.find_i("Synaptic::httpProxyPort")) | ||
3309 | 297 | if proxy_host and proxy_port: | ||
3310 | 298 | proxy = "http://%s:%s/" % (proxy_host, proxy_port) | ||
3311 | 299 | # gconf is no more | ||
3312 | 300 | # elif gconfclient: | ||
3313 | 301 | # try: # see LP: #281248 | ||
3314 | 302 | # if gconfclient.get_bool("/system/http_proxy/use_http_proxy"): | ||
3315 | 303 | # host = gconfclient.get_string("/system/http_proxy/host") | ||
3316 | 304 | # port = gconfclient.get_int("/system/http_proxy/port") | ||
3317 | 305 | # use_auth = gconfclient.get_bool("/system/http_proxy/use_authentication") | ||
3318 | 306 | # if host and port: | ||
3319 | 307 | # if use_auth: | ||
3320 | 308 | # auth_user = gconfclient.get_string("/system/http_proxy/authentication_user") | ||
3321 | 309 | # auth_pw = gconfclient.get_string("/system/http_proxy/authentication_password") | ||
3322 | 310 | # proxy = "http://%s:%s@%s:%s/" % (auth_user,auth_pw,host, port) | ||
3323 | 311 | # else: | ||
3324 | 312 | # proxy = "http://%s:%s/" % (host, port) | ||
3325 | 313 | # except Exception as e: | ||
3326 | 314 | # print("error from gconf: %s" % e) | ||
3327 | 315 | # if we have a proxy, set it | ||
3328 | 316 | if proxy: | ||
3329 | 317 | # basic verification | ||
3330 | 318 | if not re.match("http://\w+", proxy): | ||
3331 | 319 | print("proxy '%s' looks invalid" % proxy, file=sys.stderr) | ||
3332 | 320 | return | ||
3333 | 321 | proxy_support = ProxyHandler({"http":proxy}) | ||
3334 | 322 | opener = build_opener(proxy_support) | ||
3335 | 323 | install_opener(opener) | ||
3336 | 324 | os.putenv("http_proxy",proxy) | ||
3337 | 325 | return proxy | ||
3338 | 326 | |||
3339 | 327 | def on_battery(): | ||
3340 | 328 | """ | ||
3341 | 329 | Check via dbus if the system is running on battery. | ||
3342 | 330 | This function is using UPower per default, if UPower is not | ||
3343 | 331 | available it falls-back to DeviceKit.Power. | ||
3344 | 332 | """ | ||
3345 | 333 | try: | ||
3346 | 334 | import dbus | ||
3347 | 335 | bus = dbus.Bus(dbus.Bus.TYPE_SYSTEM) | ||
3348 | 336 | try: | ||
3349 | 337 | devobj = bus.get_object('org.freedesktop.UPower', | ||
3350 | 338 | '/org/freedesktop/UPower') | ||
3351 | 339 | dev = dbus.Interface(devobj, 'org.freedesktop.DBus.Properties') | ||
3352 | 340 | return dev.Get('org.freedesktop.UPower', 'OnBattery') | ||
3353 | 341 | except dbus.exceptions.DBusException as e: | ||
3354 | 342 | if e._dbus_error_name != 'org.freedesktop.DBus.Error.ServiceUnknown': | ||
3355 | 343 | raise | ||
3356 | 344 | devobj = bus.get_object('org.freedesktop.DeviceKit.Power', | ||
3357 | 345 | '/org/freedesktop/DeviceKit/Power') | ||
3358 | 346 | dev = dbus.Interface(devobj, "org.freedesktop.DBus.Properties") | ||
3359 | 347 | return dev.Get("org.freedesktop.DeviceKit.Power", "on_battery") | ||
3360 | 348 | except Exception as e: | ||
3361 | 349 | #import sys | ||
3362 | 350 | #print("on_battery returned error: ", e, file=sys.stderr) | ||
3363 | 351 | return False | ||
3364 | 352 | |||
3365 | 353 | def inhibit_sleep(): | ||
3366 | 354 | """ | ||
3367 | 355 | Send a dbus signal to power-manager to not suspend | ||
3368 | 356 | the system, using the freedesktop common interface | ||
3369 | 357 | """ | ||
3370 | 358 | try: | ||
3371 | 359 | import dbus | ||
3372 | 360 | bus = dbus.Bus(dbus.Bus.TYPE_SESSION) | ||
3373 | 361 | devobj = bus.get_object('org.freedesktop.PowerManagement', | ||
3374 | 362 | '/org/freedesktop/PowerManagement/Inhibit') | ||
3375 | 363 | dev = dbus.Interface(devobj, "org.freedesktop.PowerManagement.Inhibit") | ||
3376 | 364 | cookie = dev.Inhibit('UpdateManager', 'Updating system') | ||
3377 | 365 | return (dev, cookie) | ||
3378 | 366 | except Exception: | ||
3379 | 367 | #print("could not send the dbus Inhibit signal: %s" % e) | ||
3380 | 368 | return (False, False) | ||
3381 | 369 | |||
3382 | 370 | def allow_sleep(dev, cookie): | ||
3383 | 371 | """Send a dbus signal to gnome-power-manager to allow a suspending | ||
3384 | 372 | the system""" | ||
3385 | 373 | try: | ||
3386 | 374 | dev.UnInhibit(cookie) | ||
3387 | 375 | except Exception as e: | ||
3388 | 376 | print("could not send the dbus UnInhibit signal: %s" % e) | ||
3389 | 377 | |||
3390 | 378 | |||
3391 | 379 | def str_to_bool(str): | ||
3392 | 380 | if str == "0" or str.upper() == "FALSE": | ||
3393 | 381 | return False | ||
3394 | 382 | return True | ||
3395 | 383 | |||
3396 | 384 | def get_lang(): | ||
3397 | 385 | import logging | ||
3398 | 386 | try: | ||
3399 | 387 | (locale_s, encoding) = locale.getdefaultlocale() | ||
3400 | 388 | return locale_s | ||
3401 | 389 | except Exception: | ||
3402 | 390 | logging.exception("gedefaultlocale() failed") | ||
3403 | 391 | return None | ||
3404 | 392 | |||
3405 | 393 | def get_ubuntu_flavor(): | ||
3406 | 394 | """ try to guess the flavor based on the running desktop """ | ||
3407 | 395 | # this will (of course) not work in a server environment, | ||
3408 | 396 | # but the main use case for this is to show the right | ||
3409 | 397 | # release notes | ||
3410 | 398 | # TODO: actually examine which meta packages are installed, like | ||
3411 | 399 | # DistUpgrade/DistUpgradeCache.py does and use that to choose a flavor. | ||
3412 | 400 | denv = os.environ.get("DESKTOP_SESSION", "") | ||
3413 | 401 | if "gnome" in denv: | ||
3414 | 402 | return "ubuntu" | ||
3415 | 403 | elif "kde" in denv: | ||
3416 | 404 | return "kubuntu" | ||
3417 | 405 | elif "xfce" in denv or "xubuntu" in denv: | ||
3418 | 406 | return "xubuntu" | ||
3419 | 407 | elif "LXDE" in denv or "Lubuntu" in denv: | ||
3420 | 408 | return "lubuntu" | ||
3421 | 409 | # default to ubuntu if nothing more specific is found | ||
3422 | 410 | return "ubuntu" | ||
3423 | 411 | |||
3424 | 412 | def get_ubuntu_flavor_name(): | ||
3425 | 413 | flavor = get_ubuntu_flavor() | ||
3426 | 414 | if flavor == "kubuntu": | ||
3427 | 415 | return "Kubuntu" | ||
3428 | 416 | elif flavor == "xubuntu": | ||
3429 | 417 | return "Xubuntu" | ||
3430 | 418 | elif flavor == "lubuntu": | ||
3431 | 419 | return "Lubuntu" | ||
3432 | 420 | else: | ||
3433 | 421 | return "Ubuntu" | ||
3434 | 422 | |||
3435 | 423 | def error(parent, summary, message): | ||
3436 | 424 | from gi.repository import Gtk, Gdk | ||
3437 | 425 | d = Gtk.MessageDialog(parent=parent, | ||
3438 | 426 | flags=Gtk.DialogFlags.MODAL, | ||
3439 | 427 | type=Gtk.MessageType.ERROR, | ||
3440 | 428 | buttons=Gtk.ButtonsType.CLOSE) | ||
3441 | 429 | d.set_markup("<big><b>%s</b></big>\n\n%s" % (summary, message)) | ||
3442 | 430 | d.realize() | ||
3443 | 431 | d.window.set_functions(Gdk.FUNC_MOVE) | ||
3444 | 432 | d.set_title("") | ||
3445 | 433 | d.run() | ||
3446 | 434 | d.destroy() | ||
3447 | 435 | return False | ||
3448 | 436 | |||
3449 | 437 | def humanize_size(bytes): | ||
3450 | 438 | """ | ||
3451 | 439 | Convert a given size in bytes to a nicer better readable unit | ||
3452 | 440 | """ | ||
3453 | 441 | |||
3454 | 442 | if bytes < 1000 * 1000: | ||
3455 | 443 | # to have 0 for 0 bytes, 1 for 0-1000 bytes and for 1 and above round up | ||
3456 | 444 | size_in_kb = int(ceil(bytes/float(1000))); | ||
3457 | 445 | # TRANSLATORS: download size of small updates, e.g. "250 kB" | ||
3458 | 446 | return ngettext("%(size).0f kB", "%(size).0f kB", size_in_kb) % { "size" : size_in_kb } | ||
3459 | 447 | else: | ||
3460 | 448 | # TRANSLATORS: download size of updates, e.g. "2.3 MB" | ||
3461 | 449 | return locale.format_string(_("%.1f MB"), bytes / 1000.0 / 1000.0) | ||
3462 | 450 | |||
3463 | 451 | def get_arch(): | ||
3464 | 452 | return apt_pkg.config.find("APT::Architecture") | ||
3465 | 453 | |||
3466 | 454 | |||
3467 | 455 | def is_port_already_listening(port): | ||
3468 | 456 | """ check if the current system is listening on the given tcp port """ | ||
3469 | 457 | # index in the line | ||
3470 | 458 | INDEX_LOCAL_ADDR = 1 | ||
3471 | 459 | #INDEX_REMOTE_ADDR = 2 | ||
3472 | 460 | INDEX_STATE = 3 | ||
3473 | 461 | # state (st) that we care about | ||
3474 | 462 | STATE_LISTENING = '0A' | ||
3475 | 463 | # read the data | ||
3476 | 464 | with open("/proc/net/tcp") as net_tcp: | ||
3477 | 465 | for line in net_tcp: | ||
3478 | 466 | line = line.strip() | ||
3479 | 467 | if not line: | ||
3480 | 468 | continue | ||
3481 | 469 | # split, values are: | ||
3482 | 470 | # sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode | ||
3483 | 471 | values = line.split() | ||
3484 | 472 | state = values[INDEX_STATE] | ||
3485 | 473 | if state != STATE_LISTENING: | ||
3486 | 474 | continue | ||
3487 | 475 | local_port_str = values[INDEX_LOCAL_ADDR].split(":")[1] | ||
3488 | 476 | local_port = int(local_port_str, 16) | ||
3489 | 477 | if local_port == port: | ||
3490 | 478 | return True | ||
3491 | 479 | return False | ||
3492 | 480 | |||
3493 | 481 | |||
3494 | 482 | def iptables_active(): | ||
3495 | 483 | """ Return True if iptables is active """ | ||
3496 | 484 | # FIXME: is there a better way? | ||
3497 | 485 | iptables_empty="""Chain INPUT (policy ACCEPT) | ||
3498 | 486 | target prot opt source destination | ||
3499 | 487 | |||
3500 | 488 | Chain FORWARD (policy ACCEPT) | ||
3501 | 489 | target prot opt source destination | ||
3502 | 490 | |||
3503 | 491 | Chain OUTPUT (policy ACCEPT) | ||
3504 | 492 | target prot opt source destination | ||
3505 | 493 | """ | ||
3506 | 494 | if os.getuid() != 0: | ||
3507 | 495 | raise OSError("Need root to check the iptables state") | ||
3508 | 496 | if not os.path.exists("/sbin/iptables"): | ||
3509 | 497 | return False | ||
3510 | 498 | out = subprocess.Popen(["iptables", "-L"], | ||
3511 | 499 | stdout=subprocess.PIPE, | ||
3512 | 500 | universal_newlines=True).communicate()[0] | ||
3513 | 501 | if out == iptables_empty: | ||
3514 | 502 | return False | ||
3515 | 503 | return True | ||
3516 | 504 | |||
3517 | 505 | |||
3518 | 506 | if __name__ == "__main__": | ||
3519 | 507 | #print(mirror_from_sources_list()) | ||
3520 | 508 | #print(on_battery()) | ||
3521 | 509 | #print(inside_chroot()) | ||
3522 | 510 | print(iptables_active()) | ||
3523 | 511 | 0 | ||
3524 | === removed file 'UpdateManager/Dialogs.py' | |||
3525 | --- UpdateManager/Dialogs.py 2012-06-27 13:39:33 +0000 | |||
3526 | +++ UpdateManager/Dialogs.py 1970-01-01 00:00:00 +0000 | |||
3527 | @@ -1,235 +0,0 @@ | |||
3528 | 1 | # Dialogs.py | ||
3529 | 2 | # -*- coding: utf-8 -*- | ||
3530 | 3 | # | ||
3531 | 4 | # Copyright (c) 2012 Canonical | ||
3532 | 5 | # | ||
3533 | 6 | # Author: Michael Terry <michael.terry@canonical.com> | ||
3534 | 7 | # | ||
3535 | 8 | # This program is free software; you can redistribute it and/or | ||
3536 | 9 | # modify it under the terms of the GNU General Public License as | ||
3537 | 10 | # published by the Free Software Foundation; either version 2 of the | ||
3538 | 11 | # License, or (at your option) any later version. | ||
3539 | 12 | # | ||
3540 | 13 | # This program is distributed in the hope that it will be useful, | ||
3541 | 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
3542 | 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
3543 | 16 | # GNU General Public License for more details. | ||
3544 | 17 | # | ||
3545 | 18 | # You should have received a copy of the GNU General Public License | ||
3546 | 19 | # along with this program; if not, write to the Free Software | ||
3547 | 20 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 | ||
3548 | 21 | # USA | ||
3549 | 22 | |||
3550 | 23 | from __future__ import absolute_import, print_function | ||
3551 | 24 | |||
3552 | 25 | from gi.repository import Gtk | ||
3553 | 26 | from gi.repository import GObject | ||
3554 | 27 | GObject.threads_init() | ||
3555 | 28 | |||
3556 | 29 | import warnings | ||
3557 | 30 | warnings.filterwarnings("ignore", "Accessed deprecated property", DeprecationWarning) | ||
3558 | 31 | |||
3559 | 32 | import dbus | ||
3560 | 33 | import os | ||
3561 | 34 | import subprocess | ||
3562 | 35 | import sys | ||
3563 | 36 | import time | ||
3564 | 37 | from .SimpleGtk3builderApp import SimpleGtkbuilderApp | ||
3565 | 38 | from .DistUpgradeFetcher import DistUpgradeFetcherGtk | ||
3566 | 39 | from .GtkProgress import GtkAcquireProgress | ||
3567 | 40 | |||
3568 | 41 | from gettext import gettext as _ | ||
3569 | 42 | |||
3570 | 43 | class Dialog(SimpleGtkbuilderApp): | ||
3571 | 44 | def __init__(self, window_main): | ||
3572 | 45 | self.window_main = window_main | ||
3573 | 46 | self.focus_button = None | ||
3574 | 47 | SimpleGtkbuilderApp.__init__(self, self.window_main.datadir+"/gtkbuilder/Dialog.ui", | ||
3575 | 48 | "update-manager") | ||
3576 | 49 | |||
3577 | 50 | def main(self): | ||
3578 | 51 | self.window_main.push(self.pane_dialog, self) | ||
3579 | 52 | if self.focus_button: | ||
3580 | 53 | self.focus_button.grab_focus() | ||
3581 | 54 | |||
3582 | 55 | def run(self, parent=None): | ||
3583 | 56 | if self.focus_button: | ||
3584 | 57 | self.focus_button.grab_focus() | ||
3585 | 58 | if parent: | ||
3586 | 59 | self.window_dialog.set_transient_for(parent) | ||
3587 | 60 | self.window_dialog.set_modal(True) | ||
3588 | 61 | self.window_dialog.run() | ||
3589 | 62 | |||
3590 | 63 | def close(self): | ||
3591 | 64 | sys.exit(0) # By default, exit the app | ||
3592 | 65 | |||
3593 | 66 | def add_button(self, label, callback, secondary=False): | ||
3594 | 67 | # from_stock tries stock first and falls back to mnemonic | ||
3595 | 68 | button = Gtk.Button.new_from_stock(label) | ||
3596 | 69 | button.connect("clicked", lambda x: callback()) | ||
3597 | 70 | button.show() | ||
3598 | 71 | self.buttonbox.add(button) | ||
3599 | 72 | self.buttonbox.set_child_secondary(button, secondary) | ||
3600 | 73 | return button | ||
3601 | 74 | |||
3602 | 75 | def add_settings_button(self): | ||
3603 | 76 | if os.path.exists("/usr/bin/software-properties-gtk"): | ||
3604 | 77 | return self.add_button(_("Settings…"), self.on_settings_button_clicked, secondary=True) | ||
3605 | 78 | else: | ||
3606 | 79 | return None | ||
3607 | 80 | |||
3608 | 81 | def on_settings_button_clicked(self): | ||
3609 | 82 | cmd = ["/usr/bin/software-properties-gtk", | ||
3610 | 83 | "--open-tab","2", | ||
3611 | 84 | # FIXME: once get_xid() is available via introspections, add | ||
3612 | 85 | # this back | ||
3613 | 86 | #"--toplevel", "%s" % self.window_main.get_window().get_xid() | ||
3614 | 87 | ] | ||
3615 | 88 | self.window_main.set_sensitive(False) | ||
3616 | 89 | p = subprocess.Popen(cmd) | ||
3617 | 90 | while p.poll() is None: | ||
3618 | 91 | while Gtk.events_pending(): | ||
3619 | 92 | Gtk.main_iteration() | ||
3620 | 93 | time.sleep(0.05) | ||
3621 | 94 | self.window_main.set_sensitive(True) | ||
3622 | 95 | |||
3623 | 96 | def set_header(self, label): | ||
3624 | 97 | self.label_header.set_label(label) | ||
3625 | 98 | |||
3626 | 99 | def set_desc(self, label): | ||
3627 | 100 | self.label_desc.set_label(label) | ||
3628 | 101 | self.label_desc.set_visible(bool(label)) | ||
3629 | 102 | |||
3630 | 103 | |||
3631 | 104 | class NoUpdatesDialog(Dialog): | ||
3632 | 105 | def __init__(self, window_main): | ||
3633 | 106 | Dialog.__init__(self, window_main) | ||
3634 | 107 | self.set_header(_("The software on this computer is up to date.")) | ||
3635 | 108 | self.add_settings_button() | ||
3636 | 109 | self.focus_button = self.add_button(Gtk.STOCK_OK, self.close) | ||
3637 | 110 | |||
3638 | 111 | |||
3639 | 112 | class DistUpgradeDialog(Dialog): | ||
3640 | 113 | def __init__(self, window_main, meta_release): | ||
3641 | 114 | Dialog.__init__(self, window_main) | ||
3642 | 115 | self.meta_release = meta_release | ||
3643 | 116 | self.set_header(_("The software on this computer is up to date.")) | ||
3644 | 117 | # Translators: these are Ubuntu version names like "Ubuntu 12.04" | ||
3645 | 118 | self.set_desc(_("However, %s %s is now available (you have %s).") % ( | ||
3646 | 119 | meta_release.flavor_name, | ||
3647 | 120 | meta_release.upgradable_to.version, | ||
3648 | 121 | meta_release.current_dist_version)) | ||
3649 | 122 | self.add_settings_button() | ||
3650 | 123 | self.add_button(_("Upgrade…"), self.upgrade) | ||
3651 | 124 | self.focus_button = self.add_button(Gtk.STOCK_OK, self.close) | ||
3652 | 125 | |||
3653 | 126 | def upgrade(self): | ||
3654 | 127 | progress = GtkAcquireProgress(self.window_main, self.window_main.datadir, | ||
3655 | 128 | _("Downloading the release upgrade tool")) | ||
3656 | 129 | fetcher = DistUpgradeFetcherGtk(new_dist=self.meta_release.upgradable_to, | ||
3657 | 130 | parent=self.window_main, | ||
3658 | 131 | progress=progress, | ||
3659 | 132 | datadir=self.window_main.datadir) | ||
3660 | 133 | if self.window_main.options.sandbox: | ||
3661 | 134 | fetcher.run_options.append("--sandbox") | ||
3662 | 135 | fetcher.run() | ||
3663 | 136 | |||
3664 | 137 | |||
3665 | 138 | class UnsupportedDialog(DistUpgradeDialog): | ||
3666 | 139 | def __init__(self, window_main, meta_release): | ||
3667 | 140 | DistUpgradeDialog.__init__(self, window_main, meta_release) | ||
3668 | 141 | # Translators: this is an Ubuntu version name like "Ubuntu 12.04" | ||
3669 | 142 | self.set_header(_("Software updates are no longer provided for %s %s.") % ( | ||
3670 | 143 | meta_release.flavor_name, | ||
3671 | 144 | meta_release.current_dist_version)) | ||
3672 | 145 | # Translators: this is an Ubuntu version name like "Ubuntu 12.04" | ||
3673 | 146 | self.set_desc(_("To stay secure, you should upgrade to %s %s.") % ( | ||
3674 | 147 | meta_release.flavor_name, | ||
3675 | 148 | meta_release.upgradable_to.version)) | ||
3676 | 149 | |||
3677 | 150 | def run(self, parent): | ||
3678 | 151 | # This field is used in tests/test_end_of_life.py | ||
3679 | 152 | self.window_main.no_longer_supported_nag = self.window_dialog | ||
3680 | 153 | DistUpgradeDialog.run(self, parent) | ||
3681 | 154 | |||
3682 | 155 | |||
3683 | 156 | class PartialUpgradeDialog(Dialog): | ||
3684 | 157 | def __init__(self, window_main): | ||
3685 | 158 | Dialog.__init__(self, window_main) | ||
3686 | 159 | self.set_header(_("Not all updates can be installed")) | ||
3687 | 160 | self.set_desc(_("""Run a partial upgrade, to install as many updates as possible. | ||
3688 | 161 | |||
3689 | 162 | This can be caused by: | ||
3690 | 163 | * A previous upgrade which didn't complete | ||
3691 | 164 | * Problems with some of the installed software | ||
3692 | 165 | * Unofficial software packages not provided by Ubuntu | ||
3693 | 166 | * Normal changes of a pre-release version of Ubuntu""")) | ||
3694 | 167 | self.add_settings_button() | ||
3695 | 168 | self.add_button(_("_Partial Upgrade"), self.upgrade) | ||
3696 | 169 | self.focus_button = self.add_button(_("_Continue"), Gtk.main_quit) | ||
3697 | 170 | |||
3698 | 171 | def upgrade(self): | ||
3699 | 172 | os.execl("/usr/bin/gksu", | ||
3700 | 173 | "/usr/bin/gksu", "--desktop", | ||
3701 | 174 | "/usr/share/applications/update-manager.desktop", | ||
3702 | 175 | "--", "/usr/bin/update-manager", "--dist-upgrade") | ||
3703 | 176 | |||
3704 | 177 | def main(self): | ||
3705 | 178 | Dialog.main(self) | ||
3706 | 179 | # Block progress until user has answered this question | ||
3707 | 180 | Gtk.main() | ||
3708 | 181 | |||
3709 | 182 | |||
3710 | 183 | class ErrorDialog(Dialog): | ||
3711 | 184 | def __init__(self, window_main, header, desc=None): | ||
3712 | 185 | Dialog.__init__(self, window_main) | ||
3713 | 186 | self.set_header(header) | ||
3714 | 187 | if desc: | ||
3715 | 188 | self.set_desc(desc) | ||
3716 | 189 | self.label_desc.set_selectable(True) | ||
3717 | 190 | self.add_settings_button() | ||
3718 | 191 | self.focus_button = self.add_button(Gtk.STOCK_OK, self.close) | ||
3719 | 192 | |||
3720 | 193 | def main(self): | ||
3721 | 194 | Dialog.main(self) | ||
3722 | 195 | # The label likes to start selecting everything (b/c it got focus before | ||
3723 | 196 | # we switched to our default button). | ||
3724 | 197 | self.label_desc.select_region(0, 0) | ||
3725 | 198 | # Since errors usually are outside the normal flow, we'll guarantee that | ||
3726 | 199 | # we don't continue with normal code flow by running our own loop here. | ||
3727 | 200 | # We won't screw anything up because the only thing this dialog will do | ||
3728 | 201 | # is exit. | ||
3729 | 202 | Gtk.main() | ||
3730 | 203 | |||
3731 | 204 | |||
3732 | 205 | class NeedRestartDialog(Dialog): | ||
3733 | 206 | def __init__(self, window_main): | ||
3734 | 207 | Dialog.__init__(self, window_main) | ||
3735 | 208 | self.set_header(_("The computer needs to restart to finish installing updates.")) | ||
3736 | 209 | self.focus_button = self.add_button(_("_Restart"), self.restart) | ||
3737 | 210 | |||
3738 | 211 | def restart(self, *args, **kwargs): | ||
3739 | 212 | self._request_reboot_via_session_manager() | ||
3740 | 213 | |||
3741 | 214 | def _request_reboot_via_session_manager(self): | ||
3742 | 215 | try: | ||
3743 | 216 | bus = dbus.SessionBus() | ||
3744 | 217 | proxy_obj = bus.get_object("org.gnome.SessionManager", | ||
3745 | 218 | "/org/gnome/SessionManager") | ||
3746 | 219 | iface = dbus.Interface(proxy_obj, "org.gnome.SessionManager") | ||
3747 | 220 | iface.RequestReboot() | ||
3748 | 221 | except dbus.DBusException: | ||
3749 | 222 | self._request_reboot_via_consolekit() | ||
3750 | 223 | except: | ||
3751 | 224 | pass | ||
3752 | 225 | |||
3753 | 226 | def _request_reboot_via_consolekit(self): | ||
3754 | 227 | try: | ||
3755 | 228 | bus = dbus.SystemBus() | ||
3756 | 229 | proxy_obj = bus.get_object("org.freedesktop.ConsoleKit", | ||
3757 | 230 | "/org/freedesktop/ConsoleKit/Manager") | ||
3758 | 231 | iface = dbus.Interface(proxy_obj, "org.freedesktop.ConsoleKit.Manager") | ||
3759 | 232 | iface.Restart() | ||
3760 | 233 | except dbus.DBusException: | ||
3761 | 234 | pass | ||
3762 | 235 | |||
3763 | 236 | 0 | ||
3764 | === removed file 'UpdateManager/DistUpgradeFetcher.py' | |||
3765 | --- UpdateManager/DistUpgradeFetcher.py 2012-06-15 20:02:33 +0000 | |||
3766 | +++ UpdateManager/DistUpgradeFetcher.py 1970-01-01 00:00:00 +0000 | |||
3767 | @@ -1,143 +0,0 @@ | |||
3768 | 1 | # DistUpgradeFetcher.py | ||
3769 | 2 | # | ||
3770 | 3 | # Copyright (c) 2006 Canonical | ||
3771 | 4 | # | ||
3772 | 5 | # Author: Michael Vogt <michael.vogt@ubuntu.com> | ||
3773 | 6 | # | ||
3774 | 7 | # This program is free software; you can redistribute it and/or | ||
3775 | 8 | # modify it under the terms of the GNU General Public License as | ||
3776 | 9 | # published by the Free Software Foundation; either version 2 of the | ||
3777 | 10 | # License, or (at your option) any later version. | ||
3778 | 11 | # | ||
3779 | 12 | # This program is distributed in the hope that it will be useful, | ||
3780 | 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
3781 | 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
3782 | 15 | # GNU General Public License for more details. | ||
3783 | 16 | # | ||
3784 | 17 | # You should have received a copy of the GNU General Public License | ||
3785 | 18 | # along with this program; if not, write to the Free Software | ||
3786 | 19 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 | ||
3787 | 20 | # USA | ||
3788 | 21 | |||
3789 | 22 | from __future__ import absolute_import, print_function | ||
3790 | 23 | |||
3791 | 24 | from gi.repository import Gtk, Gdk | ||
3792 | 25 | |||
3793 | 26 | from .ReleaseNotesViewer import ReleaseNotesViewer | ||
3794 | 27 | from .Core.utils import error, inhibit_sleep, allow_sleep | ||
3795 | 28 | from .Core.DistUpgradeFetcherCore import DistUpgradeFetcherCore | ||
3796 | 29 | from .SimpleGtk3builderApp import SimpleGtkbuilderApp | ||
3797 | 30 | from gettext import gettext as _ | ||
3798 | 31 | try: | ||
3799 | 32 | from urllib.request import urlopen | ||
3800 | 33 | from urllib.error import HTTPError | ||
3801 | 34 | except ImportError: | ||
3802 | 35 | from urllib2 import urlopen, HTTPError | ||
3803 | 36 | import os | ||
3804 | 37 | import socket | ||
3805 | 38 | |||
3806 | 39 | |||
3807 | 40 | class DistUpgradeFetcherGtk(DistUpgradeFetcherCore): | ||
3808 | 41 | |||
3809 | 42 | def __init__(self, new_dist, progress, parent, datadir): | ||
3810 | 43 | DistUpgradeFetcherCore.__init__(self,new_dist,progress) | ||
3811 | 44 | uifile = datadir + "gtkbuilder/ReleaseNotes.ui" | ||
3812 | 45 | self.widgets = SimpleGtkbuilderApp(uifile, "update-manager") | ||
3813 | 46 | self.window_main = parent | ||
3814 | 47 | |||
3815 | 48 | def error(self, summary, message): | ||
3816 | 49 | return error(self.window_main, summary, message) | ||
3817 | 50 | |||
3818 | 51 | def runDistUpgrader(self): | ||
3819 | 52 | inhibit_sleep() | ||
3820 | 53 | # now run it with sudo | ||
3821 | 54 | if os.getuid() != 0: | ||
3822 | 55 | os.execv("/usr/bin/gksu",["gksu", | ||
3823 | 56 | "--desktop","/usr/share/applications/update-manager.desktop", | ||
3824 | 57 | "--", | ||
3825 | 58 | self.script]+self.run_options) | ||
3826 | 59 | else: | ||
3827 | 60 | os.execv(self.script,[self.script]+self.run_options) | ||
3828 | 61 | # we shouldn't come to this point, but if we do, undo our | ||
3829 | 62 | # inhibit sleep | ||
3830 | 63 | allow_sleep() | ||
3831 | 64 | |||
3832 | 65 | def showReleaseNotes(self): | ||
3833 | 66 | # first try showing the webkit version, this may fail (return None | ||
3834 | 67 | # because e.g. there is no webkit installed) | ||
3835 | 68 | res = self._try_show_release_notes_webkit() | ||
3836 | 69 | if res is not None: | ||
3837 | 70 | return res | ||
3838 | 71 | else: | ||
3839 | 72 | # fallback to text | ||
3840 | 73 | return self._try_show_release_notes_textview() | ||
3841 | 74 | |||
3842 | 75 | def _try_show_release_notes_webkit(self): | ||
3843 | 76 | if self.new_dist.releaseNotesHtmlUri is not None: | ||
3844 | 77 | try: | ||
3845 | 78 | from .ReleaseNotesViewerWebkit import ReleaseNotesViewerWebkit | ||
3846 | 79 | webkit_release_notes = ReleaseNotesViewerWebkit(self.new_dist.releaseNotesHtmlUri) | ||
3847 | 80 | webkit_release_notes.show() | ||
3848 | 81 | self.widgets.scrolled_notes.add(webkit_release_notes) | ||
3849 | 82 | res = self.widgets.dialog_release_notes.run() | ||
3850 | 83 | self.widgets.dialog_release_notes.hide() | ||
3851 | 84 | if res == Gtk.ResponseType.OK: | ||
3852 | 85 | return True | ||
3853 | 86 | return False | ||
3854 | 87 | except ImportError: | ||
3855 | 88 | pass | ||
3856 | 89 | return None | ||
3857 | 90 | |||
3858 | 91 | def _try_show_release_notes_textview(self): | ||
3859 | 92 | # FIXME: care about i18n! (append -$lang or something) | ||
3860 | 93 | if self.new_dist.releaseNotesURI != None: | ||
3861 | 94 | uri = self._expandUri(self.new_dist.releaseNotesURI) | ||
3862 | 95 | self.window_main.set_sensitive(False) | ||
3863 | 96 | self.window_main.get_window().set_cursor(Gdk.Cursor.new(Gdk.CursorType.WATCH)) | ||
3864 | 97 | while Gtk.events_pending(): | ||
3865 | 98 | Gtk.main_iteration() | ||
3866 | 99 | |||
3867 | 100 | # download/display the release notes | ||
3868 | 101 | # FIXME: add some progress reporting here | ||
3869 | 102 | res = Gtk.ResponseType.CANCEL | ||
3870 | 103 | timeout = socket.getdefaulttimeout() | ||
3871 | 104 | try: | ||
3872 | 105 | socket.setdefaulttimeout(5) | ||
3873 | 106 | release_notes = urlopen(uri) | ||
3874 | 107 | notes = release_notes.read().decode("UTF-8", "replace") | ||
3875 | 108 | textview_release_notes = ReleaseNotesViewer(notes) | ||
3876 | 109 | textview_release_notes.show() | ||
3877 | 110 | self.widgets.scrolled_notes.add(textview_release_notes) | ||
3878 | 111 | self.widgets.dialog_release_notes.set_transient_for(self.window_main) | ||
3879 | 112 | res = self.widgets.dialog_release_notes.run() | ||
3880 | 113 | self.widgets.dialog_release_notes.hide() | ||
3881 | 114 | except HTTPError: | ||
3882 | 115 | primary = "<span weight=\"bold\" size=\"larger\">%s</span>" % \ | ||
3883 | 116 | _("Could not find the release notes") | ||
3884 | 117 | secondary = _("The server may be overloaded. ") | ||
3885 | 118 | dialog = Gtk.MessageDialog(self.window_main,Gtk.DialogFlags.MODAL, | ||
3886 | 119 | Gtk.MessageType.ERROR,Gtk.ButtonsType.CLOSE,"") | ||
3887 | 120 | dialog.set_title("") | ||
3888 | 121 | dialog.set_markup(primary); | ||
3889 | 122 | dialog.format_secondary_text(secondary); | ||
3890 | 123 | dialog.run() | ||
3891 | 124 | dialog.destroy() | ||
3892 | 125 | except IOError: | ||
3893 | 126 | primary = "<span weight=\"bold\" size=\"larger\">%s</span>" % \ | ||
3894 | 127 | _("Could not download the release notes") | ||
3895 | 128 | secondary = _("Please check your internet connection.") | ||
3896 | 129 | dialog = Gtk.MessageDialog(self.window_main,Gtk.DialogFlags.MODAL, | ||
3897 | 130 | Gtk.MessageType.ERROR,Gtk.ButtonsType.CLOSE,"") | ||
3898 | 131 | dialog.set_title("") | ||
3899 | 132 | dialog.set_markup(primary); | ||
3900 | 133 | dialog.format_secondary_text(secondary); | ||
3901 | 134 | dialog.run() | ||
3902 | 135 | dialog.destroy() | ||
3903 | 136 | socket.setdefaulttimeout(timeout) | ||
3904 | 137 | self.window_main.set_sensitive(True) | ||
3905 | 138 | self.window_main.get_window().set_cursor(None) | ||
3906 | 139 | # user clicked cancel | ||
3907 | 140 | if res == Gtk.ResponseType.OK: | ||
3908 | 141 | return True | ||
3909 | 142 | return False | ||
3910 | 143 | |||
3911 | 144 | 0 | ||
3912 | === removed file 'UpdateManager/DistUpgradeFetcherKDE.py' | |||
3913 | --- UpdateManager/DistUpgradeFetcherKDE.py 2012-06-12 01:40:26 +0000 | |||
3914 | +++ UpdateManager/DistUpgradeFetcherKDE.py 1970-01-01 00:00:00 +0000 | |||
3915 | @@ -1,188 +0,0 @@ | |||
3916 | 1 | # DistUpgradeFetcherKDE.py | ||
3917 | 2 | # | ||
3918 | 3 | # Copyright (c) 2008 Canonical Ltd | ||
3919 | 4 | # | ||
3920 | 5 | # Author: Jonathan Riddell <jriddell@ubuntu.com> | ||
3921 | 6 | # | ||
3922 | 7 | # This program is free software; you can redistribute it and/or | ||
3923 | 8 | # modify it under the terms of the GNU General Public License as | ||
3924 | 9 | # published by the Free Software Foundation; either version 2 of the | ||
3925 | 10 | # License, or (at your option) any later version. | ||
3926 | 11 | # | ||
3927 | 12 | # This program is distributed in the hope that it will be useful, | ||
3928 | 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
3929 | 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
3930 | 15 | # GNU General Public License for more details. | ||
3931 | 16 | # | ||
3932 | 17 | # You should have received a copy of the GNU General Public License | ||
3933 | 18 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
3934 | 19 | |||
3935 | 20 | from __future__ import absolute_import | ||
3936 | 21 | |||
3937 | 22 | from PyKDE4.kdecore import ki18n, KAboutData, KCmdLineOptions, KCmdLineArgs | ||
3938 | 23 | from PyKDE4.kdeui import KIcon, KMessageBox, KApplication, KStandardGuiItem | ||
3939 | 24 | from PyQt4.QtCore import QDir, QTimer | ||
3940 | 25 | from PyQt4.QtGui import QDialog, QDialogButtonBox | ||
3941 | 26 | from PyQt4 import uic | ||
3942 | 27 | |||
3943 | 28 | import apt_pkg | ||
3944 | 29 | import sys | ||
3945 | 30 | |||
3946 | 31 | from .Core.utils import inhibit_sleep, allow_sleep | ||
3947 | 32 | from .Core.DistUpgradeFetcherCore import DistUpgradeFetcherCore | ||
3948 | 33 | from gettext import gettext as _ | ||
3949 | 34 | try: | ||
3950 | 35 | from urllib.request import urlopen | ||
3951 | 36 | from urllib.error import HTTPError | ||
3952 | 37 | except ImportError: | ||
3953 | 38 | from urllib2 import urlopen, HTTPError | ||
3954 | 39 | import os | ||
3955 | 40 | |||
3956 | 41 | from .Core.MetaRelease import MetaReleaseCore | ||
3957 | 42 | import time | ||
3958 | 43 | import apt | ||
3959 | 44 | |||
3960 | 45 | class DistUpgradeFetcherKDE(DistUpgradeFetcherCore): | ||
3961 | 46 | """A small application run by Adept to download, verify | ||
3962 | 47 | and run the dist-upgrade tool""" | ||
3963 | 48 | |||
3964 | 49 | def __init__(self, useDevelopmentRelease=False, useProposed=False): | ||
3965 | 50 | self.useDevelopmentRelease = useDevelopmentRelease | ||
3966 | 51 | self.useProposed = useProposed | ||
3967 | 52 | metaRelease = MetaReleaseCore(useDevelopmentRelease, useProposed) | ||
3968 | 53 | while metaRelease.downloading: | ||
3969 | 54 | time.sleep(0.2) | ||
3970 | 55 | if metaRelease.new_dist is None and __name__ == "__main__": | ||
3971 | 56 | sys.exit() | ||
3972 | 57 | elif metaRelease.new_dist is None: | ||
3973 | 58 | return | ||
3974 | 59 | |||
3975 | 60 | self.progressDialogue = QDialog() | ||
3976 | 61 | if os.path.exists("fetch-progress.ui"): | ||
3977 | 62 | self.APPDIR = QDir.currentPath() | ||
3978 | 63 | else: | ||
3979 | 64 | self.APPDIR = "/usr/share/update-manager" | ||
3980 | 65 | |||
3981 | 66 | uic.loadUi(self.APPDIR + "/fetch-progress.ui", self.progressDialogue) | ||
3982 | 67 | self.progressDialogue.setWindowIcon(KIcon("system-software-update")) | ||
3983 | 68 | self.progressDialogue.setWindowTitle(_("Upgrade")) | ||
3984 | 69 | self.progress = KDEAcquireProgressAdapter(self.progressDialogue.installationProgress, self.progressDialogue.installingLabel, None) | ||
3985 | 70 | DistUpgradeFetcherCore.__init__(self,metaRelease.new_dist,self.progress) | ||
3986 | 71 | |||
3987 | 72 | def error(self, summary, message): | ||
3988 | 73 | KMessageBox.sorry(None, message, summary) | ||
3989 | 74 | |||
3990 | 75 | def runDistUpgrader(self): | ||
3991 | 76 | inhibit_sleep() | ||
3992 | 77 | # now run it with sudo | ||
3993 | 78 | if os.getuid() != 0: | ||
3994 | 79 | os.execv("/usr/bin/kdesudo",["kdesudo", self.script + " --frontend=DistUpgradeViewKDE"]) | ||
3995 | 80 | else: | ||
3996 | 81 | os.execv(self.script,[self.script]+ ["--frontend=DistUpgradeViewKDE"] + self.run_options) | ||
3997 | 82 | # we shouldn't come to this point, but if we do, undo our | ||
3998 | 83 | # inhibit sleep | ||
3999 | 84 | allow_sleep() | ||
4000 | 85 | |||
4001 | 86 | def showReleaseNotes(self): | ||
4002 | 87 | # FIXME: care about i18n! (append -$lang or something) | ||
4003 | 88 | self.dialogue = QDialog() | ||
4004 | 89 | uic.loadUi(self.APPDIR + "/dialog_release_notes.ui", self.dialogue) | ||
4005 | 90 | upgradeButton = self.dialogue.buttonBox.button(QDialogButtonBox.Ok) | ||
4006 | 91 | upgradeButton.setText(_("Upgrade")) | ||
4007 | 92 | upgradeButton.setIcon(KIcon("dialog-ok")) | ||
4008 | 93 | cancelButton = self.dialogue.buttonBox.button(QDialogButtonBox.Cancel) | ||
4009 | 94 | cancelButton.setIcon(KIcon("dialog-cancel")) | ||
4010 | 95 | self.dialogue.setWindowTitle(_("Release Notes")) | ||
4011 | 96 | self.dialogue.show() | ||
4012 | 97 | if self.new_dist.releaseNotesURI != None: | ||
4013 | 98 | uri = self._expandUri(self.new_dist.releaseNotesURI) | ||
4014 | 99 | # download/display the release notes | ||
4015 | 100 | # FIXME: add some progress reporting here | ||
4016 | 101 | result = None | ||
4017 | 102 | try: | ||
4018 | 103 | release_notes = urlopen(uri) | ||
4019 | 104 | notes = release_notes.read().decode("UTF-8", "replace") | ||
4020 | 105 | self.dialogue.scrolled_notes.setText(notes) | ||
4021 | 106 | result = self.dialogue.exec_() | ||
4022 | 107 | except HTTPError: | ||
4023 | 108 | primary = "<span weight=\"bold\" size=\"larger\">%s</span>" % \ | ||
4024 | 109 | _("Could not find the release notes") | ||
4025 | 110 | secondary = _("The server may be overloaded. ") | ||
4026 | 111 | KMessageBox.sorry(None, primary + "<br />" + secondary, "") | ||
4027 | 112 | except IOError: | ||
4028 | 113 | primary = "<span weight=\"bold\" size=\"larger\">%s</span>" % \ | ||
4029 | 114 | _("Could not download the release notes") | ||
4030 | 115 | secondary = _("Please check your internet connection.") | ||
4031 | 116 | KMessageBox.sorry(None, primary + "<br />" + secondary, "") | ||
4032 | 117 | # user clicked cancel | ||
4033 | 118 | if result == QDialog.Accepted: | ||
4034 | 119 | self.progressDialogue.show() | ||
4035 | 120 | return True | ||
4036 | 121 | if __name__ == "__main__": | ||
4037 | 122 | KApplication.kApplication().exit(1) | ||
4038 | 123 | if self.useDevelopmentRelease or self.useProposed: | ||
4039 | 124 | sys.exit() #FIXME why does KApplication.kApplication().exit() crash but this doesn't? | ||
4040 | 125 | return False | ||
4041 | 126 | |||
4042 | 127 | class KDEAcquireProgressAdapter(apt.progress.base.AcquireProgress): | ||
4043 | 128 | def __init__(self,progress,label,parent): | ||
4044 | 129 | self.progress = progress | ||
4045 | 130 | self.label = label | ||
4046 | 131 | self.parent = parent | ||
4047 | 132 | |||
4048 | 133 | def start(self): | ||
4049 | 134 | self.label.setText(_("Downloading additional package files...")) | ||
4050 | 135 | self.progress.setValue(0) | ||
4051 | 136 | |||
4052 | 137 | def stop(self): | ||
4053 | 138 | pass | ||
4054 | 139 | |||
4055 | 140 | def pulse(self, owner): | ||
4056 | 141 | apt.progress.base.AcquireProgress.pulse(self, owner) | ||
4057 | 142 | self.progress.setValue((self.current_bytes + self.current_items) / | ||
4058 | 143 | float(self.total_bytes + self.total_items)) | ||
4059 | 144 | current_item = self.current_items + 1 | ||
4060 | 145 | if current_item > self.total_items: | ||
4061 | 146 | current_item = self.total_items | ||
4062 | 147 | if self.current_cps > 0: | ||
4063 | 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))) | ||
4064 | 149 | else: | ||
4065 | 150 | self.label.setText(_("Downloading additional package files...") + _("File %s of %s") % (self.current_items,self.total_items)) | ||
4066 | 151 | KApplication.kApplication().processEvents() | ||
4067 | 152 | return True | ||
4068 | 153 | |||
4069 | 154 | def mediaChange(self, medium, drive): | ||
4070 | 155 | msg = _("Please insert '%s' into the drive '%s'") % (medium,drive) | ||
4071 | 156 | #change = QMessageBox.question(None, _("Media Change"), msg, QMessageBox.Ok, QMessageBox.Cancel) | ||
4072 | 157 | change = KMessageBox.questionYesNo(None, _("Media Change"), _("Media Change") + "<br>" + msg, KStandardGuiItem.ok(), KStandardGuiItem.cancel()) | ||
4073 | 158 | if change == KMessageBox.Yes: | ||
4074 | 159 | return True | ||
4075 | 160 | return False | ||
4076 | 161 | |||
4077 | 162 | if __name__ == "__main__": | ||
4078 | 163 | |||
4079 | 164 | appName = "dist-upgrade-fetcher" | ||
4080 | 165 | catalog = "" | ||
4081 | 166 | programName = ki18n ("Dist Upgrade Fetcher") | ||
4082 | 167 | version = "0.3.4" | ||
4083 | 168 | description = ki18n ("Dist Upgrade Fetcher") | ||
4084 | 169 | license = KAboutData.License_GPL | ||
4085 | 170 | copyright = ki18n ("(c) 2008 Canonical Ltd") | ||
4086 | 171 | text = ki18n ("none") | ||
4087 | 172 | homePage = "https://launchpad.net/update-manager" | ||
4088 | 173 | bugEmail = "" | ||
4089 | 174 | |||
4090 | 175 | aboutData = KAboutData (appName, catalog, programName, version, description, license, copyright, text, homePage, bugEmail) | ||
4091 | 176 | |||
4092 | 177 | aboutData.addAuthor(ki18n("Jonathan Riddell"), ki18n("Author")) | ||
4093 | 178 | |||
4094 | 179 | options = KCmdLineOptions() | ||
4095 | 180 | |||
4096 | 181 | KCmdLineArgs.init (sys.argv, aboutData) | ||
4097 | 182 | KCmdLineArgs.addCmdLineOptions(options) | ||
4098 | 183 | |||
4099 | 184 | app = KApplication() | ||
4100 | 185 | fetcher = DistUpgradeFetcherKDE() | ||
4101 | 186 | QTimer.singleShot(10, fetcher.run) | ||
4102 | 187 | |||
4103 | 188 | app.exec_() | ||
4104 | 189 | 0 | ||
4105 | === removed file 'UpdateManager/GtkProgress.py' | |||
4106 | --- UpdateManager/GtkProgress.py 2012-06-15 20:24:05 +0000 | |||
4107 | +++ UpdateManager/GtkProgress.py 1970-01-01 00:00:00 +0000 | |||
4108 | @@ -1,89 +0,0 @@ | |||
4109 | 1 | # GtkProgress.py | ||
4110 | 2 | # | ||
4111 | 3 | # Copyright (c) 2004,2005 Canonical | ||
4112 | 4 | # | ||
4113 | 5 | # Author: Michael Vogt <michael.vogt@ubuntu.com> | ||
4114 | 6 | # | ||
4115 | 7 | # This program is free software; you can redistribute it and/or | ||
4116 | 8 | # modify it under the terms of the GNU General Public License as | ||
4117 | 9 | # published by the Free Software Foundation; either version 2 of the | ||
4118 | 10 | # License, or (at your option) any later version. | ||
4119 | 11 | # | ||
4120 | 12 | # This program is distributed in the hope that it will be useful, | ||
4121 | 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
4122 | 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
4123 | 15 | # GNU General Public License for more details. | ||
4124 | 16 | # | ||
4125 | 17 | # You should have received a copy of the GNU General Public License | ||
4126 | 18 | # along with this program; if not, write to the Free Software | ||
4127 | 19 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 | ||
4128 | 20 | # USA | ||
4129 | 21 | |||
4130 | 22 | from __future__ import absolute_import, print_function | ||
4131 | 23 | |||
4132 | 24 | from gi.repository import Gtk, Gdk | ||
4133 | 25 | import apt | ||
4134 | 26 | from gettext import gettext as _ | ||
4135 | 27 | from .Core.utils import humanize_size | ||
4136 | 28 | from .SimpleGtk3builderApp import SimpleGtkbuilderApp | ||
4137 | 29 | |||
4138 | 30 | class GtkAcquireProgress(apt.progress.base.AcquireProgress): | ||
4139 | 31 | def __init__(self, parent, datadir, summary="", descr=""): | ||
4140 | 32 | uifile = datadir + "gtkbuilder/AcquireProgress.ui" | ||
4141 | 33 | self.widgets = SimpleGtkbuilderApp(uifile, "update-manager") | ||
4142 | 34 | # if this is set to false the download will cancel | ||
4143 | 35 | self._continue = True | ||
4144 | 36 | # init vars here | ||
4145 | 37 | # FIXME: find a more elegant way, this sucks | ||
4146 | 38 | self.summary = self.widgets.label_fetch_summary | ||
4147 | 39 | self.status = self.widgets.label_fetch_status | ||
4148 | 40 | # we need to connect the signal manual here, it won't work | ||
4149 | 41 | # from the main window auto-connect | ||
4150 | 42 | self.widgets.button_fetch_cancel.connect( | ||
4151 | 43 | "clicked", self.on_button_fetch_cancel_clicked) | ||
4152 | 44 | self.progress = self.widgets.progressbar_fetch | ||
4153 | 45 | self.window_fetch = self.widgets.window_fetch | ||
4154 | 46 | self.window_fetch.set_transient_for(parent) | ||
4155 | 47 | self.window_fetch.realize() | ||
4156 | 48 | self.window_fetch.get_window().set_functions(Gdk.WMFunction.MOVE) | ||
4157 | 49 | # set summary | ||
4158 | 50 | if summary != "": | ||
4159 | 51 | self.summary.set_markup("<big><b>%s</b></big> \n\n%s" % | ||
4160 | 52 | (summary, descr)) | ||
4161 | 53 | def start(self): | ||
4162 | 54 | self.progress.set_fraction(0) | ||
4163 | 55 | self.window_fetch.show() | ||
4164 | 56 | def stop(self): | ||
4165 | 57 | self.window_fetch.hide() | ||
4166 | 58 | def on_button_fetch_cancel_clicked(self, widget): | ||
4167 | 59 | self._continue = False | ||
4168 | 60 | def pulse(self, owner): | ||
4169 | 61 | apt.progress.base.AcquireProgress.pulse(self, owner) | ||
4170 | 62 | current_item = self.current_items + 1 | ||
4171 | 63 | if current_item > self.total_items: | ||
4172 | 64 | current_item = self.total_items | ||
4173 | 65 | if self.current_cps > 0: | ||
4174 | 66 | status_text = (_("Downloading file %(current)li of %(total)li with " | ||
4175 | 67 | "%(speed)s/s") % {"current" : current_item, | ||
4176 | 68 | "total" : self.total_items, | ||
4177 | 69 | "speed" : humanize_size(self.current_cps)}) | ||
4178 | 70 | else: | ||
4179 | 71 | status_text = (_("Downloading file %(current)li of %(total)li") % \ | ||
4180 | 72 | {"current" : current_item, | ||
4181 | 73 | "total" : self.total_items }) | ||
4182 | 74 | self.progress.set_fraction((self.current_bytes + self.current_items) / | ||
4183 | 75 | float(self.total_bytes + self.total_items)) | ||
4184 | 76 | self.status.set_markup("<i>%s</i>" % status_text) | ||
4185 | 77 | # TRANSLATORS: show the remaining time in a progress bar: | ||
4186 | 78 | #if self.current_cps > 0: | ||
4187 | 79 | # eta = ((self.total_bytes + self.current_bytes) / float(self.current_cps)) | ||
4188 | 80 | #else: | ||
4189 | 81 | # eta = 0.0 | ||
4190 | 82 | #self.progress.set_text(_("About %s left" % (apt_pkg.TimeToStr(eta)))) | ||
4191 | 83 | # FIXME: show remaining time | ||
4192 | 84 | self.progress.set_text("") | ||
4193 | 85 | |||
4194 | 86 | while Gtk.events_pending(): | ||
4195 | 87 | Gtk.main_iteration() | ||
4196 | 88 | return self._continue | ||
4197 | 89 | |||
4198 | 90 | 0 | ||
4199 | === removed file 'UpdateManager/HelpViewer.py' | |||
4200 | --- UpdateManager/HelpViewer.py 2012-05-28 11:11:59 +0000 | |||
4201 | +++ UpdateManager/HelpViewer.py 1970-01-01 00:00:00 +0000 | |||
4202 | @@ -1,33 +0,0 @@ | |||
4203 | 1 | # helpviewer.py | ||
4204 | 2 | |||
4205 | 3 | import os | ||
4206 | 4 | import subprocess | ||
4207 | 5 | |||
4208 | 6 | # Hardcoded list of available help viewers | ||
4209 | 7 | # FIXME: khelpcenter support would be nice | ||
4210 | 8 | #KNOWN_VIEWERS = ["/usr/bin/yelp", "/usr/bin/khelpcenter"] | ||
4211 | 9 | KNOWN_VIEWERS = ["/usr/bin/yelp"] | ||
4212 | 10 | |||
4213 | 11 | class HelpViewer: | ||
4214 | 12 | def __init__(self, docu): | ||
4215 | 13 | self.command = [] | ||
4216 | 14 | self.docu = docu | ||
4217 | 15 | for viewer in KNOWN_VIEWERS: | ||
4218 | 16 | if os.path.exists(viewer): | ||
4219 | 17 | self.command = [viewer, "ghelp:%s" % docu] | ||
4220 | 18 | break | ||
4221 | 19 | |||
4222 | 20 | def check(self): | ||
4223 | 21 | """check if a viewer is available""" | ||
4224 | 22 | if self.command == []: | ||
4225 | 23 | return False | ||
4226 | 24 | else: | ||
4227 | 25 | return True | ||
4228 | 26 | |||
4229 | 27 | def run(self): | ||
4230 | 28 | """open the documentation in the viewer""" | ||
4231 | 29 | # avoid running the help viewer as root | ||
4232 | 30 | if os.getuid() == 0 and 'SUDO_USER' in os.environ: | ||
4233 | 31 | self.command = ['sudo', '-u', os.environ['SUDO_USER']] +\ | ||
4234 | 32 | self.command | ||
4235 | 33 | subprocess.Popen(self.command) | ||
4236 | 34 | 0 | ||
4237 | === removed file 'UpdateManager/InstallProgress.py' | |||
4238 | --- UpdateManager/InstallProgress.py 2012-06-15 20:24:05 +0000 | |||
4239 | +++ UpdateManager/InstallProgress.py 1970-01-01 00:00:00 +0000 | |||
4240 | @@ -1,93 +0,0 @@ | |||
4241 | 1 | # InstallProgress.py | ||
4242 | 2 | # | ||
4243 | 3 | # Copyright (c) 2004-2012 Canonical | ||
4244 | 4 | # 2004 Michiel Sikkes | ||
4245 | 5 | # 2005 Martin Willemoes Hansen | ||
4246 | 6 | # 2010 Mohamed Amine IL Idrissi | ||
4247 | 7 | # | ||
4248 | 8 | # Author: Michiel Sikkes <michiel@eyesopened.nl> | ||
4249 | 9 | # Michael Vogt <mvo@debian.org> | ||
4250 | 10 | # Martin Willemoes Hansen <mwh@sysrq.dk> | ||
4251 | 11 | # Mohamed Amine IL Idrissi <ilidrissiamine@gmail.com> | ||
4252 | 12 | # Alex Launi <alex.launi@canonical.com> | ||
4253 | 13 | # Michael Terry <michael.terry@canonical.com> | ||
4254 | 14 | # | ||
4255 | 15 | # This program is free software; you can redistribute it and/or | ||
4256 | 16 | # modify it under the terms of the GNU General Public License as | ||
4257 | 17 | # published by the Free Software Foundation; either version 2 of the | ||
4258 | 18 | # License, or (at your option) any later version. | ||
4259 | 19 | # | ||
4260 | 20 | # This program is distributed in the hope that it will be useful, | ||
4261 | 21 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
4262 | 22 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
4263 | 23 | # GNU General Public License for more details. | ||
4264 | 24 | # | ||
4265 | 25 | # You should have received a copy of the GNU General Public License | ||
4266 | 26 | # along with this program; if not, write to the Free Software | ||
4267 | 27 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 | ||
4268 | 28 | # USA | ||
4269 | 29 | |||
4270 | 30 | from __future__ import absolute_import, print_function | ||
4271 | 31 | |||
4272 | 32 | import warnings | ||
4273 | 33 | warnings.filterwarnings("ignore", "Accessed deprecated property", DeprecationWarning) | ||
4274 | 34 | |||
4275 | 35 | import os | ||
4276 | 36 | import sys | ||
4277 | 37 | |||
4278 | 38 | from .backend import get_backend | ||
4279 | 39 | |||
4280 | 40 | from .Core.utils import (inhibit_sleep, | ||
4281 | 41 | allow_sleep) | ||
4282 | 42 | |||
4283 | 43 | class InstallProgress(object): | ||
4284 | 44 | |||
4285 | 45 | def __init__(self, app): | ||
4286 | 46 | self.window_main = app | ||
4287 | 47 | self.datadir = app.datadir | ||
4288 | 48 | self.options = app.options | ||
4289 | 49 | |||
4290 | 50 | # Used for inhibiting power management | ||
4291 | 51 | self.sleep_cookie = None | ||
4292 | 52 | self.sleep_dev = None | ||
4293 | 53 | |||
4294 | 54 | # get the install backend | ||
4295 | 55 | self.install_backend = get_backend(self.datadir, self.window_main) | ||
4296 | 56 | self.install_backend.connect("action-done", self._on_backend_done) | ||
4297 | 57 | |||
4298 | 58 | def invoke_manager(self): | ||
4299 | 59 | # don't display apt-listchanges, we already showed the changelog | ||
4300 | 60 | os.environ["APT_LISTCHANGES_FRONTEND"]="none" | ||
4301 | 61 | |||
4302 | 62 | # Do not suspend during the update process | ||
4303 | 63 | (self.sleep_dev, self.sleep_cookie) = inhibit_sleep() | ||
4304 | 64 | |||
4305 | 65 | # If the progress dialog should be closed automatically afterwards | ||
4306 | 66 | #settings = Gio.Settings("com.ubuntu.update-manager") | ||
4307 | 67 | #close_on_done = settings.get_boolean("autoclose-install-window") | ||
4308 | 68 | close_on_done = False # FIXME: confirm with mpt whether this should still be a setting | ||
4309 | 69 | |||
4310 | 70 | # Get the packages which should be installed and update | ||
4311 | 71 | pkgs_install = [] | ||
4312 | 72 | pkgs_upgrade = [] | ||
4313 | 73 | for pkg in self.window_main.cache: | ||
4314 | 74 | if pkg.marked_install: | ||
4315 | 75 | pkgs_install.append(pkg.name) | ||
4316 | 76 | elif pkg.marked_upgrade: | ||
4317 | 77 | pkgs_upgrade.append(pkg.name) | ||
4318 | 78 | self.install_backend.commit(pkgs_install, pkgs_upgrade, close_on_done) | ||
4319 | 79 | |||
4320 | 80 | def _on_backend_done(self, backend, action, authorized, success): | ||
4321 | 81 | # Allow suspend after synaptic is finished | ||
4322 | 82 | if self.sleep_cookie: | ||
4323 | 83 | allow_sleep(self.sleep_dev, self.sleep_cookie) | ||
4324 | 84 | self.sleep_cookie = self.sleep_dev = None | ||
4325 | 85 | |||
4326 | 86 | # Either launch main dialog and continue or quit altogether | ||
4327 | 87 | if success: | ||
4328 | 88 | self.window_main.start_available(allow_restart=True) | ||
4329 | 89 | else: | ||
4330 | 90 | sys.exit(0) | ||
4331 | 91 | |||
4332 | 92 | def main(self): | ||
4333 | 93 | self.invoke_manager() | ||
4334 | 94 | 0 | ||
4335 | === removed file 'UpdateManager/MetaReleaseGObject.py' | |||
4336 | --- UpdateManager/MetaReleaseGObject.py 2012-06-15 17:36:46 +0000 | |||
4337 | +++ UpdateManager/MetaReleaseGObject.py 1970-01-01 00:00:00 +0000 | |||
4338 | @@ -1,57 +0,0 @@ | |||
4339 | 1 | # Copyright (c) 2004-2007 Canonical | ||
4340 | 2 | # | ||
4341 | 3 | # Author: Michael Vogt <michael.vogt@ubuntu.com> | ||
4342 | 4 | # | ||
4343 | 5 | # This program is free software; you can redistribute it and/or | ||
4344 | 6 | # modify it under the terms of the GNU General Public License as | ||
4345 | 7 | # published by the Free Software Foundation; either version 2 of the | ||
4346 | 8 | # License, or (at your option) any later version. | ||
4347 | 9 | # | ||
4348 | 10 | # This program is distributed in the hope that it will be useful, | ||
4349 | 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
4350 | 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
4351 | 13 | # GNU General Public License for more details. | ||
4352 | 14 | # | ||
4353 | 15 | # You should have received a copy of the GNU General Public License | ||
4354 | 16 | # along with this program; if not, write to the Free Software | ||
4355 | 17 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 | ||
4356 | 18 | # USA | ||
4357 | 19 | |||
4358 | 20 | from __future__ import absolute_import | ||
4359 | 21 | |||
4360 | 22 | from gi.repository import GObject | ||
4361 | 23 | from .Core.MetaRelease import MetaReleaseCore | ||
4362 | 24 | |||
4363 | 25 | class MetaRelease(MetaReleaseCore,GObject.GObject): | ||
4364 | 26 | |||
4365 | 27 | __gsignals__ = { | ||
4366 | 28 | 'new_dist_available' : (GObject.SignalFlags.RUN_LAST, | ||
4367 | 29 | None, | ||
4368 | 30 | (GObject.TYPE_PYOBJECT,)), | ||
4369 | 31 | 'dist_no_longer_supported' : (GObject.SignalFlags.RUN_LAST, | ||
4370 | 32 | None, | ||
4371 | 33 | ()), | ||
4372 | 34 | 'done_downloading' : (GObject.SignalFlags.RUN_LAST, | ||
4373 | 35 | None, | ||
4374 | 36 | ()) | ||
4375 | 37 | } | ||
4376 | 38 | |||
4377 | 39 | def __init__(self, useDevelopmentRelease=False, useProposed=False): | ||
4378 | 40 | GObject.GObject.__init__(self) | ||
4379 | 41 | MetaReleaseCore.__init__(self, useDevelopmentRelease, useProposed) | ||
4380 | 42 | # in the gtk space to test if the download already finished | ||
4381 | 43 | # this is needed because gtk is not thread-safe | ||
4382 | 44 | GObject.timeout_add(1000, self.check) | ||
4383 | 45 | |||
4384 | 46 | def check(self): | ||
4385 | 47 | # check if we have a metarelease_information file | ||
4386 | 48 | if self.no_longer_supported is not None: | ||
4387 | 49 | self.emit("dist_no_longer_supported") | ||
4388 | 50 | if self.new_dist is not None: | ||
4389 | 51 | self.emit("new_dist_available", self.new_dist) | ||
4390 | 52 | if self.downloading: | ||
4391 | 53 | return True | ||
4392 | 54 | else: | ||
4393 | 55 | self.emit("done_downloading") | ||
4394 | 56 | return False | ||
4395 | 57 | |||
4396 | 58 | 0 | ||
4397 | === removed file 'UpdateManager/ReleaseNotesViewer.py' | |||
4398 | --- UpdateManager/ReleaseNotesViewer.py 2012-06-11 16:17:31 +0000 | |||
4399 | +++ UpdateManager/ReleaseNotesViewer.py 1970-01-01 00:00:00 +0000 | |||
4400 | @@ -1,186 +0,0 @@ | |||
4401 | 1 | # ReleaseNotesViewer.py | ||
4402 | 2 | # | ||
4403 | 3 | # Copyright (c) 2006 Sebastian Heinlein | ||
4404 | 4 | # | ||
4405 | 5 | # Author: Sebastian Heinlein <sebastian.heinlein@web.de> | ||
4406 | 6 | # | ||
4407 | 7 | # This modul provides an inheritance of the Gtk.TextView that is | ||
4408 | 8 | # aware of http URLs and allows to open them in a browser. | ||
4409 | 9 | # It is based on the pygtk-demo "hypertext". | ||
4410 | 10 | # | ||
4411 | 11 | # This program is free software; you can redistribute it and/or | ||
4412 | 12 | # modify it under the terms of the GNU General Public License as | ||
4413 | 13 | # published by the Free Software Foundation; either version 2 of the | ||
4414 | 14 | # License, or (at your option) any later version. | ||
4415 | 15 | # | ||
4416 | 16 | # This program is distributed in the hope that it will be useful, | ||
4417 | 17 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
4418 | 18 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
4419 | 19 | # GNU General Public License for more details. | ||
4420 | 20 | # | ||
4421 | 21 | # You should have received a copy of the GNU General Public License | ||
4422 | 22 | # along with this program; if not, write to the Free Software | ||
4423 | 23 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 | ||
4424 | 24 | # USA | ||
4425 | 25 | |||
4426 | 26 | from gi.repository import Pango | ||
4427 | 27 | from gi.repository import Gtk, GObject, Gdk | ||
4428 | 28 | import os | ||
4429 | 29 | import subprocess | ||
4430 | 30 | |||
4431 | 31 | def open_url(url): | ||
4432 | 32 | """Open the specified URL in a browser""" | ||
4433 | 33 | # Find an appropiate browser | ||
4434 | 34 | if os.path.exists("/usr/bin/xdg-open"): | ||
4435 | 35 | command = ["xdg-open", url] | ||
4436 | 36 | elif os.path.exists("/usr/bin/exo-open"): | ||
4437 | 37 | command = ["exo-open", url] | ||
4438 | 38 | elif os.path.exists('/usr/bin/gnome-open'): | ||
4439 | 39 | command = ['gnome-open', url] | ||
4440 | 40 | else: | ||
4441 | 41 | command = ['x-www-browser', url] | ||
4442 | 42 | # Avoid to run the browser as user root | ||
4443 | 43 | if os.getuid() == 0 and 'SUDO_USER' in os.environ: | ||
4444 | 44 | command = ['sudo', '-u', os.environ['SUDO_USER']] + command | ||
4445 | 45 | subprocess.Popen(command) | ||
4446 | 46 | |||
4447 | 47 | |||
4448 | 48 | class ReleaseNotesViewer(Gtk.TextView): | ||
4449 | 49 | def __init__(self, notes): | ||
4450 | 50 | """Init the ReleaseNotesViewer as an Inheritance of the Gtk.TextView. | ||
4451 | 51 | Load the notes into the buffer and make links clickable""" | ||
4452 | 52 | # init the parent | ||
4453 | 53 | GObject.GObject.__init__(self) | ||
4454 | 54 | # global hovering over link state | ||
4455 | 55 | self.hovering = False | ||
4456 | 56 | self.first = True | ||
4457 | 57 | # setup the buffer and signals | ||
4458 | 58 | self.set_property("editable", False) | ||
4459 | 59 | self.set_cursor_visible(False) | ||
4460 | 60 | self.modify_font(Pango.FontDescription("monospace")) | ||
4461 | 61 | self.buffer = Gtk.TextBuffer() | ||
4462 | 62 | self.set_buffer(self.buffer) | ||
4463 | 63 | self.buffer.set_text(notes) | ||
4464 | 64 | self.connect("button-press-event", self.button_press_event) | ||
4465 | 65 | self.connect("motion-notify-event", self.motion_notify_event) | ||
4466 | 66 | self.connect("visibility-notify-event", self.visibility_notify_event) | ||
4467 | 67 | # search for links in the notes and make them clickable | ||
4468 | 68 | self.search_links() | ||
4469 | 69 | |||
4470 | 70 | def tag_link(self, start, end, url): | ||
4471 | 71 | """Apply the tag that marks links to the specified buffer selection""" | ||
4472 | 72 | tag = self.buffer.create_tag(None, foreground="blue", | ||
4473 | 73 | underline=Pango.Underline.SINGLE) | ||
4474 | 74 | tag.url = url | ||
4475 | 75 | self.buffer.apply_tag(tag , start, end) | ||
4476 | 76 | |||
4477 | 77 | def search_links(self): | ||
4478 | 78 | """Search for http URLs in the buffer and call the tag_link method | ||
4479 | 79 | for each one to tag them as links""" | ||
4480 | 80 | # start at the beginning of the buffer | ||
4481 | 81 | iter = self.buffer.get_iter_at_offset(0) | ||
4482 | 82 | while 1: | ||
4483 | 83 | # search for the next URL in the buffer | ||
4484 | 84 | ret = iter.forward_search("http://", Gtk.TextSearchFlags.VISIBLE_ONLY, | ||
4485 | 85 | None) | ||
4486 | 86 | # if we reach the end break the loop | ||
4487 | 87 | if not ret: | ||
4488 | 88 | break | ||
4489 | 89 | # get the position of the protocol prefix | ||
4490 | 90 | (match_start, match_end) = ret | ||
4491 | 91 | match_tmp = match_end.copy() | ||
4492 | 92 | while 1: | ||
4493 | 93 | # extend the selection to the complete URL | ||
4494 | 94 | if match_tmp.forward_char(): | ||
4495 | 95 | text = match_end.get_text(match_tmp) | ||
4496 | 96 | if text in (" ", ")", "]", "\n", "\t"): | ||
4497 | 97 | break | ||
4498 | 98 | else: | ||
4499 | 99 | break | ||
4500 | 100 | match_end = match_tmp.copy() | ||
4501 | 101 | # call the tagging method for the complete URL | ||
4502 | 102 | url = match_start.get_text(match_end) | ||
4503 | 103 | self.tag_link(match_start, match_end, url) | ||
4504 | 104 | # set the starting point for the next search | ||
4505 | 105 | iter = match_end | ||
4506 | 106 | |||
4507 | 107 | def button_press_event(self, text_view, event): | ||
4508 | 108 | """callback for mouse click events""" | ||
4509 | 109 | if event.button != 1: | ||
4510 | 110 | return False | ||
4511 | 111 | |||
4512 | 112 | # try to get a selection | ||
4513 | 113 | try: | ||
4514 | 114 | (start, end) = self.buffer.get_selection_bounds() | ||
4515 | 115 | except ValueError: | ||
4516 | 116 | pass | ||
4517 | 117 | else: | ||
4518 | 118 | if start.get_offset() != end.get_offset(): | ||
4519 | 119 | return False | ||
4520 | 120 | |||
4521 | 121 | # get the iter at the mouse position | ||
4522 | 122 | (x, y) = self.window_to_buffer_coords(Gtk.TextWindowType.WIDGET, | ||
4523 | 123 | int(event.x), int(event.y)) | ||
4524 | 124 | iter = self.get_iter_at_location(x, y) | ||
4525 | 125 | |||
4526 | 126 | # call open_url if an URL is assigned to the iter | ||
4527 | 127 | tags = iter.get_tags() | ||
4528 | 128 | for tag in tags: | ||
4529 | 129 | url = getattr(tag, "url", None) | ||
4530 | 130 | if url != "": | ||
4531 | 131 | open_url(url) | ||
4532 | 132 | break | ||
4533 | 133 | |||
4534 | 134 | def motion_notify_event(self, text_view, event): | ||
4535 | 135 | """callback for the mouse movement event, that calls the | ||
4536 | 136 | check_hovering method with the mouse postition coordiantes""" | ||
4537 | 137 | x, y = text_view.window_to_buffer_coords(Gtk.TextWindowType.WIDGET, | ||
4538 | 138 | int(event.x), int(event.y)) | ||
4539 | 139 | self.check_hovering(x, y) | ||
4540 | 140 | self.get_window(Gtk.TextWindowType.TEXT).get_pointer() | ||
4541 | 141 | return False | ||
4542 | 142 | |||
4543 | 143 | def visibility_notify_event(self, text_view, event): | ||
4544 | 144 | """callback if the widgets gets visible (e.g. moves to the foreground) | ||
4545 | 145 | that calls the check_hovering method with the mouse position | ||
4546 | 146 | coordinates""" | ||
4547 | 147 | (screen, wx, wy, mod) = text_view.get_window(Gtk.TextWindowType.TEXT).get_pointer() | ||
4548 | 148 | (bx, by) = text_view.window_to_buffer_coords( | ||
4549 | 149 | Gtk.TextWindowType.WIDGET, wx, wy) | ||
4550 | 150 | self.check_hovering(bx, by) | ||
4551 | 151 | return False | ||
4552 | 152 | |||
4553 | 153 | def check_hovering(self, x, y): | ||
4554 | 154 | """Check if the mouse is above a tagged link and if yes show | ||
4555 | 155 | a hand cursor""" | ||
4556 | 156 | _hovering = False | ||
4557 | 157 | # get the iter at the mouse position | ||
4558 | 158 | iter = self.get_iter_at_location(x, y) | ||
4559 | 159 | |||
4560 | 160 | # set _hovering if the iter has the tag "url" | ||
4561 | 161 | tags = iter.get_tags() | ||
4562 | 162 | for tag in tags: | ||
4563 | 163 | url = getattr(tag, "url", None) | ||
4564 | 164 | if url != "": | ||
4565 | 165 | _hovering = True | ||
4566 | 166 | break | ||
4567 | 167 | |||
4568 | 168 | # change the global hovering state | ||
4569 | 169 | if _hovering != self.hovering or self.first == True: | ||
4570 | 170 | self.first = False | ||
4571 | 171 | self.hovering = _hovering | ||
4572 | 172 | # Set the appropriate cursur icon | ||
4573 | 173 | if self.hovering: | ||
4574 | 174 | self.get_window(Gtk.TextWindowType.TEXT).\ | ||
4575 | 175 | set_cursor(Gdk.Cursor.new(Gdk.CursorType.HAND2)) | ||
4576 | 176 | else: | ||
4577 | 177 | self.get_window(Gtk.TextWindowType.TEXT).\ | ||
4578 | 178 | set_cursor(Gdk.Cursor.new(Gdk.CursorType.LEFT_PTR)) | ||
4579 | 179 | |||
4580 | 180 | if __name__ == "__main__": | ||
4581 | 181 | # some simple test code | ||
4582 | 182 | win = Gtk.Window() | ||
4583 | 183 | rv = ReleaseNotesViewer(open("../DistUpgrade/ReleaseAnnouncement").read()) | ||
4584 | 184 | win.add(rv) | ||
4585 | 185 | win.show_all() | ||
4586 | 186 | Gtk.main() | ||
4587 | 187 | 0 | ||
4588 | === removed file 'UpdateManager/ReleaseNotesViewerWebkit.py' | |||
4589 | --- UpdateManager/ReleaseNotesViewerWebkit.py 2012-05-01 14:01:29 +0000 | |||
4590 | +++ UpdateManager/ReleaseNotesViewerWebkit.py 1970-01-01 00:00:00 +0000 | |||
4591 | @@ -1,54 +0,0 @@ | |||
4592 | 1 | # ReleaseNotesViewer.py | ||
4593 | 2 | # | ||
4594 | 3 | # Copyright (c) 2011 Canonical | ||
4595 | 4 | # | ||
4596 | 5 | # Author: Michael Vogt <mvo@ubutnu.com> | ||
4597 | 6 | # | ||
4598 | 7 | # This modul provides an inheritance of the Gtk.TextView that is | ||
4599 | 8 | # aware of http URLs and allows to open them in a browser. | ||
4600 | 9 | # It is based on the pygtk-demo "hypertext". | ||
4601 | 10 | # | ||
4602 | 11 | # This program is free software; you can redistribute it and/or | ||
4603 | 12 | # modify it under the terms of the GNU General Public License as | ||
4604 | 13 | # published by the Free Software Foundation; either version 2 of the | ||
4605 | 14 | # License, or (at your option) any later version. | ||
4606 | 15 | # | ||
4607 | 16 | # This program is distributed in the hope that it will be useful, | ||
4608 | 17 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
4609 | 18 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
4610 | 19 | # GNU General Public License for more details. | ||
4611 | 20 | # | ||
4612 | 21 | # You should have received a copy of the GNU General Public License | ||
4613 | 22 | # along with this program; if not, write to the Free Software | ||
4614 | 23 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 | ||
4615 | 24 | # USA | ||
4616 | 25 | |||
4617 | 26 | from __future__ import absolute_import | ||
4618 | 27 | |||
4619 | 28 | from gi.repository import Gtk | ||
4620 | 29 | from gi.repository import WebKit | ||
4621 | 30 | |||
4622 | 31 | from .ReleaseNotesViewer import open_url | ||
4623 | 32 | |||
4624 | 33 | class ReleaseNotesViewerWebkit(WebKit.WebView): | ||
4625 | 34 | def __init__(self, notes_url): | ||
4626 | 35 | super(ReleaseNotesViewerWebkit, self).__init__() | ||
4627 | 36 | self.load_uri(notes_url) | ||
4628 | 37 | self.connect("navigation-policy-decision-requested", self._on_navigation_policy_decision_requested) | ||
4629 | 38 | def _on_navigation_policy_decision_requested(self, view, frame, request, action, policy): | ||
4630 | 39 | open_url(request.get_uri()) | ||
4631 | 40 | policy.ignore() | ||
4632 | 41 | return True | ||
4633 | 42 | |||
4634 | 43 | |||
4635 | 44 | if __name__ == "__main__": | ||
4636 | 45 | win = Gtk.Window() | ||
4637 | 46 | win.set_size_request(600, 400) | ||
4638 | 47 | scroll = Gtk.ScrolledWindow() | ||
4639 | 48 | rv = ReleaseNotesViewerWebkit("http://archive.ubuntu.com/ubuntu/dists/natty/main/dist-upgrader-all/0.150/ReleaseAnnouncement.html") | ||
4640 | 49 | scroll.add(rv) | ||
4641 | 50 | win.add(scroll) | ||
4642 | 51 | win.show_all() | ||
4643 | 52 | Gtk.main() | ||
4644 | 53 | |||
4645 | 54 | |||
4646 | 55 | 0 | ||
4647 | === removed file 'UpdateManager/SimpleGtk3builderApp.py' | |||
4648 | --- UpdateManager/SimpleGtk3builderApp.py 2011-07-15 15:32:30 +0000 | |||
4649 | +++ UpdateManager/SimpleGtk3builderApp.py 1970-01-01 00:00:00 +0000 | |||
4650 | @@ -1,61 +0,0 @@ | |||
4651 | 1 | """ | ||
4652 | 2 | SimpleGladeApp.py | ||
4653 | 3 | Module that provides an object oriented abstraction to pygtk and libglade. | ||
4654 | 4 | Copyright (C) 2004 Sandino Flores Moreno | ||
4655 | 5 | """ | ||
4656 | 6 | |||
4657 | 7 | # This library is free software; you can redistribute it and/or | ||
4658 | 8 | # modify it under the terms of the GNU Lesser General Public | ||
4659 | 9 | # License as published by the Free Software Foundation; either | ||
4660 | 10 | # version 2.1 of the License, or (at your option) any later version. | ||
4661 | 11 | # | ||
4662 | 12 | # This library is distributed in the hope that it will be useful, | ||
4663 | 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
4664 | 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
4665 | 15 | # Lesser General Public License for more details. | ||
4666 | 16 | # | ||
4667 | 17 | # You should have received a copy of the GNU Lesser General Public | ||
4668 | 18 | # License along with this library; if not, write to the Free Software | ||
4669 | 19 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 | ||
4670 | 20 | # USA | ||
4671 | 21 | |||
4672 | 22 | import logging | ||
4673 | 23 | |||
4674 | 24 | from gi.repository import Gtk | ||
4675 | 25 | |||
4676 | 26 | # based on SimpleGladeApp | ||
4677 | 27 | class SimpleGtkbuilderApp: | ||
4678 | 28 | |||
4679 | 29 | def __init__(self, path, domain): | ||
4680 | 30 | self.builder = Gtk.Builder() | ||
4681 | 31 | self.builder.set_translation_domain(domain) | ||
4682 | 32 | self.builder.add_from_file(path) | ||
4683 | 33 | self.builder.connect_signals(self) | ||
4684 | 34 | for o in self.builder.get_objects(): | ||
4685 | 35 | if issubclass(type(o), Gtk.Buildable): | ||
4686 | 36 | name = Gtk.Buildable.get_name(o) | ||
4687 | 37 | setattr(self, name, o) | ||
4688 | 38 | else: | ||
4689 | 39 | logging.debug("WARNING: can not get name for '%s'" % o) | ||
4690 | 40 | |||
4691 | 41 | def run(self): | ||
4692 | 42 | """ | ||
4693 | 43 | Starts the main loop of processing events checking for Control-C. | ||
4694 | 44 | |||
4695 | 45 | The default implementation checks wheter a Control-C is pressed, | ||
4696 | 46 | then calls on_keyboard_interrupt(). | ||
4697 | 47 | |||
4698 | 48 | Use this method for starting programs. | ||
4699 | 49 | """ | ||
4700 | 50 | try: | ||
4701 | 51 | Gtk.main() | ||
4702 | 52 | except KeyboardInterrupt: | ||
4703 | 53 | self.on_keyboard_interrupt() | ||
4704 | 54 | |||
4705 | 55 | def on_keyboard_interrupt(self): | ||
4706 | 56 | """ | ||
4707 | 57 | This method is called by the default implementation of run() | ||
4708 | 58 | after a program is finished by pressing Control-C. | ||
4709 | 59 | """ | ||
4710 | 60 | pass | ||
4711 | 61 | |||
4712 | 62 | 0 | ||
4713 | === removed file 'UpdateManager/SimpleGtkbuilderApp.py' | |||
4714 | --- UpdateManager/SimpleGtkbuilderApp.py 2011-07-15 15:32:30 +0000 | |||
4715 | +++ UpdateManager/SimpleGtkbuilderApp.py 1970-01-01 00:00:00 +0000 | |||
4716 | @@ -1,61 +0,0 @@ | |||
4717 | 1 | """ | ||
4718 | 2 | SimpleGladeApp.py | ||
4719 | 3 | Module that provides an object oriented abstraction to pygtk and libglade. | ||
4720 | 4 | Copyright (C) 2004 Sandino Flores Moreno | ||
4721 | 5 | """ | ||
4722 | 6 | |||
4723 | 7 | # This library is free software; you can redistribute it and/or | ||
4724 | 8 | # modify it under the terms of the GNU Lesser General Public | ||
4725 | 9 | # License as published by the Free Software Foundation; either | ||
4726 | 10 | # version 2.1 of the License, or (at your option) any later version. | ||
4727 | 11 | # | ||
4728 | 12 | # This library is distributed in the hope that it will be useful, | ||
4729 | 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
4730 | 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
4731 | 15 | # Lesser General Public License for more details. | ||
4732 | 16 | # | ||
4733 | 17 | # You should have received a copy of the GNU Lesser General Public | ||
4734 | 18 | # License along with this library; if not, write to the Free Software | ||
4735 | 19 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 | ||
4736 | 20 | # USA | ||
4737 | 21 | |||
4738 | 22 | import logging | ||
4739 | 23 | |||
4740 | 24 | import gtk | ||
4741 | 25 | |||
4742 | 26 | # based on SimpleGladeApp | ||
4743 | 27 | class SimpleGtkbuilderApp: | ||
4744 | 28 | |||
4745 | 29 | def __init__(self, path, domain): | ||
4746 | 30 | self.builder = gtk.Builder() | ||
4747 | 31 | self.builder.set_translation_domain(domain) | ||
4748 | 32 | self.builder.add_from_file(path) | ||
4749 | 33 | self.builder.connect_signals(self) | ||
4750 | 34 | for o in self.builder.get_objects(): | ||
4751 | 35 | if issubclass(type(o), gtk.Buildable): | ||
4752 | 36 | name = gtk.Buildable.get_name(o) | ||
4753 | 37 | setattr(self, name, o) | ||
4754 | 38 | else: | ||
4755 | 39 | logging.debug("WARNING: can not get name for '%s'" % o) | ||
4756 | 40 | |||
4757 | 41 | def run(self): | ||
4758 | 42 | """ | ||
4759 | 43 | Starts the main loop of processing events checking for Control-C. | ||
4760 | 44 | |||
4761 | 45 | The default implementation checks wheter a Control-C is pressed, | ||
4762 | 46 | then calls on_keyboard_interrupt(). | ||
4763 | 47 | |||
4764 | 48 | Use this method for starting programs. | ||
4765 | 49 | """ | ||
4766 | 50 | try: | ||
4767 | 51 | gtk.main() | ||
4768 | 52 | except KeyboardInterrupt: | ||
4769 | 53 | self.on_keyboard_interrupt() | ||
4770 | 54 | |||
4771 | 55 | def on_keyboard_interrupt(self): | ||
4772 | 56 | """ | ||
4773 | 57 | This method is called by the default implementation of run() | ||
4774 | 58 | after a program is finished by pressing Control-C. | ||
4775 | 59 | """ | ||
4776 | 60 | pass | ||
4777 | 61 | |||
4778 | 62 | 0 | ||
4779 | === removed file 'UpdateManager/UnitySupport.py' | |||
4780 | --- UpdateManager/UnitySupport.py 2012-05-30 20:47:45 +0000 | |||
4781 | +++ UpdateManager/UnitySupport.py 1970-01-01 00:00:00 +0000 | |||
4782 | @@ -1,94 +0,0 @@ | |||
4783 | 1 | # UnitySupport.py | ||
4784 | 2 | # | ||
4785 | 3 | # Copyright (c) 2011 Canonical | ||
4786 | 4 | # | ||
4787 | 5 | # Author: Michael Vogt <mvo@ubuntu.com> | ||
4788 | 6 | # Bilal Akhtar <bilalakhtar@ubuntu.com> | ||
4789 | 7 | # | ||
4790 | 8 | # This program is free software; you can redistribute it and/or | ||
4791 | 9 | # modify it under the terms of the GNU General Public License as | ||
4792 | 10 | # published by the Free Software Foundation; either version 2 of the | ||
4793 | 11 | # License, or (at your option) any later version. | ||
4794 | 12 | # | ||
4795 | 13 | # This program is distributed in the hope that it will be useful, | ||
4796 | 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
4797 | 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
4798 | 16 | # GNU General Public License for more details. | ||
4799 | 17 | # | ||
4800 | 18 | # You should have received a copy of the GNU General Public License | ||
4801 | 19 | # along with this program; if not, write to the Free Software | ||
4802 | 20 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 | ||
4803 | 21 | # USA | ||
4804 | 22 | |||
4805 | 23 | import logging | ||
4806 | 24 | from gettext import gettext as _ | ||
4807 | 25 | |||
4808 | 26 | HAVE_UNITY_SUPPORT=False | ||
4809 | 27 | try: | ||
4810 | 28 | from gi.repository import Dbusmenu, Unity | ||
4811 | 29 | HAVE_UNITY_SUPPORT=True | ||
4812 | 30 | except ImportError as e: | ||
4813 | 31 | logging.warn("can not import unity GI %s" % e) | ||
4814 | 32 | |||
4815 | 33 | class IUnitySupport(object): | ||
4816 | 34 | """ interface for unity support """ | ||
4817 | 35 | def __init__(self, parent=None): pass | ||
4818 | 36 | def set_updates_count(self, num_updates): pass | ||
4819 | 37 | def set_urgency(self, urgent): pass | ||
4820 | 38 | def set_install_menuitem_visible(self, visible): pass | ||
4821 | 39 | def set_progress(self, progress): pass | ||
4822 | 40 | |||
4823 | 41 | class UnitySupportImpl(IUnitySupport): | ||
4824 | 42 | """ implementation of unity support (if unity is available) """ | ||
4825 | 43 | |||
4826 | 44 | def __init__(self, parent=None): | ||
4827 | 45 | # create launcher and quicklist | ||
4828 | 46 | um_launcher_entry = Unity.LauncherEntry.get_for_desktop_id( | ||
4829 | 47 | "update-manager.desktop") | ||
4830 | 48 | self._unity = um_launcher_entry | ||
4831 | 49 | if parent: | ||
4832 | 50 | self._add_quicklist(parent) | ||
4833 | 51 | |||
4834 | 52 | def _add_quicklist(self, parent): | ||
4835 | 53 | quicklist = Dbusmenu.Menuitem.new() | ||
4836 | 54 | # install | ||
4837 | 55 | self.install_dbusmenuitem = Dbusmenu.Menuitem.new() | ||
4838 | 56 | self.install_dbusmenuitem.property_set (Dbusmenu.MENUITEM_PROP_LABEL, | ||
4839 | 57 | _("Install All Available Updates")) | ||
4840 | 58 | self.install_dbusmenuitem.property_set_bool (Dbusmenu.MENUITEM_PROP_VISIBLE, True) | ||
4841 | 59 | self.install_dbusmenuitem.connect ( | ||
4842 | 60 | "item-activated", parent.install_all_updates, None) | ||
4843 | 61 | quicklist.child_append (self.install_dbusmenuitem) | ||
4844 | 62 | # add it | ||
4845 | 63 | self._unity.set_property ("quicklist", quicklist) | ||
4846 | 64 | |||
4847 | 65 | def set_progress(self, progress): | ||
4848 | 66 | """ set the progress [0,100] """ | ||
4849 | 67 | self._unity.set_property("progress", progress/100.0) | ||
4850 | 68 | # hide progress when out of bounds | ||
4851 | 69 | if progress < 0 or progress > 100: | ||
4852 | 70 | self._unity.set_property("progress_visible", False) | ||
4853 | 71 | else: | ||
4854 | 72 | self._unity.set_property("progress_visible", True) | ||
4855 | 73 | |||
4856 | 74 | def set_updates_count(self, num_updates): | ||
4857 | 75 | self._unity.set_property("count", num_updates) | ||
4858 | 76 | # FIXME: setup emblem as well(?) | ||
4859 | 77 | if num_updates > 0: | ||
4860 | 78 | self._unity.set_property("count-visible", True) | ||
4861 | 79 | else: | ||
4862 | 80 | self._unity.set_property("count-visible", False) | ||
4863 | 81 | |||
4864 | 82 | def set_urgency(self, urgent): | ||
4865 | 83 | self._unity.set_property("urgent", urgent) | ||
4866 | 84 | |||
4867 | 85 | def set_install_menuitem_visible(self, visible): | ||
4868 | 86 | self.install_dbusmenuitem.property_set_bool(Dbusmenu.MENUITEM_PROP_VISIBLE, visible) | ||
4869 | 87 | |||
4870 | 88 | |||
4871 | 89 | # check what to export to the clients | ||
4872 | 90 | if HAVE_UNITY_SUPPORT: | ||
4873 | 91 | UnitySupport = UnitySupportImpl | ||
4874 | 92 | else: | ||
4875 | 93 | # we just provide the empty interface | ||
4876 | 94 | UnitySupport = IUnitySupport | ||
4877 | 95 | 0 | ||
4878 | === removed file 'UpdateManager/UpdateManager.py' | |||
4879 | --- UpdateManager/UpdateManager.py 2012-06-15 20:02:33 +0000 | |||
4880 | +++ UpdateManager/UpdateManager.py 1970-01-01 00:00:00 +0000 | |||
4881 | @@ -1,335 +0,0 @@ | |||
4882 | 1 | # UpdateManager.py | ||
4883 | 2 | # -*- Mode: Python; indent-tabs-mode: nil; tab-width: 2; coding: utf-8 -*- | ||
4884 | 3 | # | ||
4885 | 4 | # Copyright (c) 2012 Canonical | ||
4886 | 5 | # | ||
4887 | 6 | # Author: Michael Terry <michael.terry@canonical.com> | ||
4888 | 7 | # | ||
4889 | 8 | # This program is free software; you can redistribute it and/or | ||
4890 | 9 | # modify it under the terms of the GNU General Public License as | ||
4891 | 10 | # published by the Free Software Foundation; either version 2 of the | ||
4892 | 11 | # License, or (at your option) any later version. | ||
4893 | 12 | # | ||
4894 | 13 | # This program is distributed in the hope that it will be useful, | ||
4895 | 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
4896 | 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
4897 | 16 | # GNU General Public License for more details. | ||
4898 | 17 | # | ||
4899 | 18 | # You should have received a copy of the GNU General Public License | ||
4900 | 19 | # along with this program; if not, write to the Free Software | ||
4901 | 20 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 | ||
4902 | 21 | # USA | ||
4903 | 22 | |||
4904 | 23 | from __future__ import absolute_import, print_function | ||
4905 | 24 | |||
4906 | 25 | from gi.repository import Gtk | ||
4907 | 26 | from gi.repository import Gdk | ||
4908 | 27 | from gi.repository import Gio | ||
4909 | 28 | from gi.repository import GLib | ||
4910 | 29 | |||
4911 | 30 | import warnings | ||
4912 | 31 | warnings.filterwarnings("ignore", "Accessed deprecated property", DeprecationWarning) | ||
4913 | 32 | |||
4914 | 33 | import apt_pkg | ||
4915 | 34 | import os | ||
4916 | 35 | import sys | ||
4917 | 36 | from gettext import gettext as _ | ||
4918 | 37 | |||
4919 | 38 | import dbus | ||
4920 | 39 | import dbus.service | ||
4921 | 40 | from dbus.mainloop.glib import DBusGMainLoop | ||
4922 | 41 | DBusGMainLoop(set_as_default=True) | ||
4923 | 42 | |||
4924 | 43 | from .UnitySupport import UnitySupport | ||
4925 | 44 | from .Dialogs import (DistUpgradeDialog, | ||
4926 | 45 | ErrorDialog, | ||
4927 | 46 | NeedRestartDialog, | ||
4928 | 47 | NoUpdatesDialog, | ||
4929 | 48 | PartialUpgradeDialog, | ||
4930 | 49 | UnsupportedDialog) | ||
4931 | 50 | from .InstallProgress import InstallProgress | ||
4932 | 51 | from .MetaReleaseGObject import MetaRelease | ||
4933 | 52 | from .UpdateProgress import UpdateProgress | ||
4934 | 53 | from .UpdatesAvailable import UpdatesAvailable | ||
4935 | 54 | from .Core.AlertWatcher import AlertWatcher | ||
4936 | 55 | from .Core.MyCache import MyCache | ||
4937 | 56 | from .Core.roam import NetworkManagerHelper | ||
4938 | 57 | from .Core.UpdateList import UpdateList | ||
4939 | 58 | |||
4940 | 59 | # file that signals if we need to reboot | ||
4941 | 60 | REBOOT_REQUIRED_FILE = "/var/run/reboot-required" | ||
4942 | 61 | |||
4943 | 62 | class UpdateManager(Gtk.Window): | ||
4944 | 63 | """ This class is the main window and work flow controller. Panes will add | ||
4945 | 64 | themselves to the main window and it will morph between them.""" | ||
4946 | 65 | |||
4947 | 66 | def __init__(self, datadir, options): | ||
4948 | 67 | Gtk.Window.__init__(self) | ||
4949 | 68 | |||
4950 | 69 | # Public members | ||
4951 | 70 | self.datadir = datadir | ||
4952 | 71 | self.options = options | ||
4953 | 72 | self.unity = UnitySupport() | ||
4954 | 73 | self.controller = None | ||
4955 | 74 | self.cache = None | ||
4956 | 75 | self.update_list = None | ||
4957 | 76 | self.meta_release = None | ||
4958 | 77 | |||
4959 | 78 | # Basic GTK+ parameters | ||
4960 | 79 | self.set_title(_("Software Updater")) | ||
4961 | 80 | self.set_icon_name("system-software-update") | ||
4962 | 81 | self.set_resizable(False) | ||
4963 | 82 | self.set_position(Gtk.WindowPosition.CENTER) | ||
4964 | 83 | self.set_size_request(500,-1) | ||
4965 | 84 | |||
4966 | 85 | # Signals | ||
4967 | 86 | self.connect("delete-event", self.close) | ||
4968 | 87 | |||
4969 | 88 | self._setup_dbus() | ||
4970 | 89 | |||
4971 | 90 | # deal with no-focus-on-map | ||
4972 | 91 | if self.options and self.options.no_focus_on_map: | ||
4973 | 92 | self.set_focus_on_map(False) | ||
4974 | 93 | self.iconify() | ||
4975 | 94 | self.stick() | ||
4976 | 95 | self.set_urgency_hint(True) | ||
4977 | 96 | self.unity.set_urgency(True) | ||
4978 | 97 | self.initial_focus_id = self.connect( | ||
4979 | 98 | "focus-in-event", self.on_initial_focus_in) | ||
4980 | 99 | |||
4981 | 100 | # Look for a new release in a thread | ||
4982 | 101 | self.meta_release = MetaRelease(self.options and self.options.devel_release, | ||
4983 | 102 | self.options and self.options.use_proposed) | ||
4984 | 103 | |||
4985 | 104 | |||
4986 | 105 | def on_initial_focus_in(self, widget, event): | ||
4987 | 106 | """callback run on initial focus-in (if started unmapped)""" | ||
4988 | 107 | self.unstick() | ||
4989 | 108 | self.set_urgency_hint(False) | ||
4990 | 109 | self.unity.set_urgency(False) | ||
4991 | 110 | self.disconnect(self.initial_focus_id) | ||
4992 | 111 | return False | ||
4993 | 112 | |||
4994 | 113 | def push(self, pane, controller): | ||
4995 | 114 | child = self.get_child() | ||
4996 | 115 | if child is not None: | ||
4997 | 116 | if self.controller and hasattr(self.controller, "save_state"): | ||
4998 | 117 | self.controller.save_state() | ||
4999 | 118 | child.destroy() | ||
5000 | 119 |
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!