diff options
Diffstat (limited to 'UpdateManager')
| -rw-r--r-- | UpdateManager/Common/DistInfo.py | 164 | ||||
| -rw-r--r-- | UpdateManager/Common/HelpViewer.py | 33 | ||||
| -rw-r--r-- | UpdateManager/Common/Makefile | 350 | ||||
| -rw-r--r-- | UpdateManager/Common/Makefile.am | 5 | ||||
| -rw-r--r-- | UpdateManager/Common/SimpleGladeApp.py | 341 | ||||
| -rw-r--r-- | UpdateManager/Common/__init__.py | 2 | ||||
| -rw-r--r-- | UpdateManager/Common/aptsources.py | 694 | ||||
| -rw-r--r-- | UpdateManager/Common/utils.py | 42 | ||||
| -rw-r--r-- | UpdateManager/DistUpgradeFetcher.py | 240 | ||||
| -rw-r--r-- | UpdateManager/GtkProgress.py | 125 | ||||
| -rw-r--r-- | UpdateManager/MetaRelease.py | 177 | ||||
| -rw-r--r-- | UpdateManager/ReleaseNotesViewer.py | 179 | ||||
| -rw-r--r-- | UpdateManager/UpdateManager.py | 962 | ||||
| -rw-r--r-- | UpdateManager/__init__.py | 1 | ||||
| -rw-r--r-- | UpdateManager/fakegconf.py | 69 |
15 files changed, 0 insertions, 3384 deletions
diff --git a/UpdateManager/Common/DistInfo.py b/UpdateManager/Common/DistInfo.py deleted file mode 100644 index 57621f52..00000000 --- a/UpdateManager/Common/DistInfo.py +++ /dev/null @@ -1,164 +0,0 @@ -#!/usr/bin/env python -# DistInfo.py - simple parser for a xml-based metainfo file -# -# Copyright (c) 2005 Gustavo Noronha Silva -# -# Author: Gustavo Noronha Silva <kov@debian.org> -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 -# USA - -import os -import gettext -from os import getenv -import ConfigParser -import string - -from gettext import gettext as _ - -class Suite: - def __init__(self): - self.name = None - self.child = False - self.match_name = None - self.description = None - self.base_uri = None - self.type = None - self.components = {} - self.children = [] - self.match_uri = None - self.valid_mirrors = [] - self.distribution = None - self.available = True - -class Component: - def __init__(self): - self.name = "" - self.description = "" - self.description_long = "" - -class DistInfo: - def __init__(self, - dist = None, - base_dir = "/usr/share/update-manager/channels"): - self.metarelease_uri = '' - self.suites = [] - - if not dist: - pipe = os.popen("lsb_release -i -s") - dist = pipe.read().strip() - pipe.close() - del pipe - - self.dist = dist - - dist_fname = "%s/%s.info" % (base_dir, dist) - dist_file = open (dist_fname) - if not dist_file: - return - suite = None - component = None - for line in dist_file: - tokens = line.split (':', 1) - if len (tokens) < 2: - continue - field = tokens[0].strip () - value = tokens[1].strip () - if field == 'ChangelogURI': - self.changelogs_uri = _(value) - elif field == 'MetaReleaseURI': - self.metarelease_uri = value - elif field == 'Suite': - if suite: - if component: - suite.components["%s" % component.name] = \ - (component.description, - component.description_long) - component = None - self.suites.append (suite) - suite = Suite () - suite.name = value - suite.distribution = dist - suite.match_name = "^%s$" % value - elif field == 'MatchName': - suite.match_name = value - elif field == 'ParentSuite': - suite.child = True - for nanny in self.suites: - if nanny.name == value: - nanny.children.append(suite) - # reuse some properties of the parent suite - if suite.match_uri == None: - suite.match_uri = nanny.match_uri - if suite.valid_mirrors == None: - suite.valid_mirrors = nanny.valid_mirrors - if suite.base_uri == None: - suite.base_uri = nanny.base_uri - elif field == 'Available': - suite.available = value - elif field == 'RepositoryType': - suite.type = value - elif field == 'BaseURI': - suite.base_uri = value - suite.match_uri = value - elif field == 'MatchURI': - suite.match_uri = value - elif field == 'MirrorsFile': - if os.path.exists(value): - suite.valid_mirrors = filter(lambda s: - ((s != "") and - (not s.startswith("#"))), - map(string.strip, - open(value))) - else: - print "WARNING: can't read '%s'" % value - elif field == 'Description': - suite.description = _(value) - elif field == 'Component': - if component: - suite.components["%s" % component.name] = \ - (component.description, - component.description_long) - component = Component () - component.name = value - elif field == 'CompDescription': - component.description = _(value) - elif field == 'CompDescriptionLong': - component.description_long = _(value) - if suite: - if component: - suite.components["%s" % component.name] = \ - (component.description, - component.description_long) - component = None - self.suites.append (suite) - suite = None - - -if __name__ == "__main__": - d = DistInfo ("Ubuntu", "../../data/channels") - print d.changelogs_uri - for suite in d.suites: - print "\nSuite: %s" % suite.name - print "Desc: %s" % suite.description - print "BaseURI: %s" % suite.base_uri - print "MatchURI: %s" % suite.match_uri - print "Mirrors: %s" % suite.valid_mirrors - for component in suite.components: - print " %s - %s - %s - %s" % (component, - suite.components[component][0], - suite.components[component][1]) - for child in suite.children: - print " %s" % child.description diff --git a/UpdateManager/Common/HelpViewer.py b/UpdateManager/Common/HelpViewer.py deleted file mode 100644 index c8b099cc..00000000 --- a/UpdateManager/Common/HelpViewer.py +++ /dev/null @@ -1,33 +0,0 @@ -# helpviewer.py - -import os -import subprocess - -# Hardcoded list of available help viewers -# FIXME: khelpcenter support would be nice -#KNOWN_VIEWERS = ["/usr/bin/yelp", "/usr/bin/khelpcenter"] -KNOWN_VIEWERS = ["/usr/bin/yelp"] - -class HelpViewer: - def __init__(self, docu): - self.command = [] - self.docu = docu - for viewer in KNOWN_VIEWERS: - if os.path.exists(viewer): - self.command = [viewer, "ghelp:%s" % docu] - break - - def check(self): - """check if a viewer is available""" - if self.command == []: - return False - else: - return True - - def run(self): - """open the documentation in the viewer""" - # avoid running the help viewer as root - if os.getuid() == 0 and os.environ.has_key('SUDO_USER'): - self.command = ['sudo', '-u', os.environ['SUDO_USER']] +\ - self.command - subprocess.Popen(self.command) diff --git a/UpdateManager/Common/Makefile b/UpdateManager/Common/Makefile deleted file mode 100644 index 9409e7e8..00000000 --- a/UpdateManager/Common/Makefile +++ /dev/null @@ -1,350 +0,0 @@ -# Makefile.in generated by automake 1.9.6 from Makefile.am. -# Common/Makefile. Generated from Makefile.in by configure. - -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005 Free Software Foundation, Inc. -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - - - -srcdir = . -top_srcdir = .. - -pkgdatadir = $(datadir)/update-manager -pkglibdir = $(libdir)/update-manager -pkgincludedir = $(includedir)/update-manager -top_builddir = .. -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -INSTALL = /usr/bin/install -c -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -subdir = Common -DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/configure.in -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs -CONFIG_HEADER = $(top_builddir)/config.h -CONFIG_CLEAN_FILES = -SOURCES = -DIST_SOURCES = -am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; -am__vpath_adj = case $$p in \ - $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ - *) f=$$p;; \ - esac; -am__strip_dir = `echo $$p | sed -e 's|^.*/||'`; -am__installdirs = "$(DESTDIR)$(modulesdir)" -modulesDATA_INSTALL = $(INSTALL_DATA) -DATA = $(modules_DATA) -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = ${SHELL} /tmp/3/update-manager-0.37.1+svn20050404.15/missing --run aclocal-1.9 -AMDEP_FALSE = # -AMDEP_TRUE = -AMTAR = ${SHELL} /tmp/3/update-manager-0.37.1+svn20050404.15/missing --run tar -AUTOCONF = ${SHELL} /tmp/3/update-manager-0.37.1+svn20050404.15/missing --run autoconf -AUTOHEADER = ${SHELL} /tmp/3/update-manager-0.37.1+svn20050404.15/missing --run autoheader -AUTOMAKE = ${SHELL} /tmp/3/update-manager-0.37.1+svn20050404.15/missing --run automake-1.9 -AWK = gawk -CATALOGS = da.gmo de.gmo el.gmo en_CA.gmo es.gmo fi.gmo fr.gmo hu.gmo ja.gmo pl.gmo pt_BR.gmo ro.gmo rw.gmo sv.gmo zh_CN.gmo xh.gmo -CATOBJEXT = .gmo -CC = gcc -CCDEPMODE = depmode=none -CFLAGS = -g -O2 -CPP = gcc -E -CPPFLAGS = -CYGPATH_W = echo -DATADIRNAME = share -DEFS = -DHAVE_CONFIG_H -DEPDIR = .deps -ECHO_C = -ECHO_N = -n -ECHO_T = -EGREP = grep -E -EXEEXT = -GETTEXT_PACKAGE = update-manager -GMOFILES = da.gmo de.gmo el.gmo en_CA.gmo es.gmo fi.gmo fr.gmo hu.gmo ja.gmo pl.gmo pt_BR.gmo ro.gmo rw.gmo sv.gmo zh_CN.gmo xh.gmo -GMSGFMT = /usr/bin/msgfmt -INSTALL_DATA = ${INSTALL} -m 644 -INSTALL_PROGRAM = ${INSTALL} -INSTALL_SCRIPT = ${INSTALL} -INSTALL_STRIP_PROGRAM = ${SHELL} $(install_sh) -c -s -INSTOBJEXT = .mo -INTLLIBS = -INTLTOOL_CAVES_RULE = %.caves: %.caves.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@ -INTLTOOL_DESKTOP_RULE = %.desktop: %.desktop.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@ -INTLTOOL_DIRECTORY_RULE = %.directory: %.directory.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@ -INTLTOOL_EXTRACT = $(top_builddir)/intltool-extract -INTLTOOL_ICONV = /usr/bin/iconv -INTLTOOL_KBD_RULE = %.kbd: %.kbd.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -m -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@ -INTLTOOL_KEYS_RULE = %.keys: %.keys.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -k -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@ -INTLTOOL_MERGE = $(top_builddir)/intltool-merge -INTLTOOL_MSGFMT = /usr/bin/msgfmt -INTLTOOL_MSGMERGE = /usr/bin/msgmerge -INTLTOOL_OAF_RULE = %.oaf: %.oaf.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -o -p $(top_srcdir)/po $< $@ -INTLTOOL_PERL = /usr/bin/perl -INTLTOOL_PONG_RULE = %.pong: %.pong.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@ -INTLTOOL_PROP_RULE = %.prop: %.prop.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@ -INTLTOOL_SCHEMAS_RULE = %.schemas: %.schemas.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -s -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@ -INTLTOOL_SERVER_RULE = %.server: %.server.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -o -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@ -INTLTOOL_SHEET_RULE = %.sheet: %.sheet.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@ -INTLTOOL_SOUNDLIST_RULE = %.soundlist: %.soundlist.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@ -INTLTOOL_THEME_RULE = %.theme: %.theme.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@ -INTLTOOL_UI_RULE = %.ui: %.ui.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@ -INTLTOOL_UPDATE = $(top_builddir)/intltool-update -INTLTOOL_XAM_RULE = %.xam: %.xml.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@ -INTLTOOL_XGETTEXT = /usr/bin/xgettext -INTLTOOL_XML_NOMERGE_RULE = %.xml: %.xml.in $(INTLTOOL_MERGE) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u /tmp $< $@ -INTLTOOL_XML_RULE = %.xml: %.xml.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@ -LDFLAGS = -LIBOBJS = -LIBS = -LTLIBOBJS = -MAINT = # -MAINTAINER_MODE_FALSE = -MAINTAINER_MODE_TRUE = # -MAKEINFO = ${SHELL} /tmp/3/update-manager-0.37.1+svn20050404.15/missing --run makeinfo -MKINSTALLDIRS = ./mkinstalldirs -MSGFMT = /usr/bin/msgfmt -OBJEXT = o -PACKAGE = update-manager -PACKAGE_BUGREPORT = -PACKAGE_NAME = -PACKAGE_STRING = -PACKAGE_TARNAME = -PACKAGE_VERSION = -PATH_SEPARATOR = : -POFILES = da.po de.po el.po en_CA.po es.po fi.po fr.po hu.po ja.po pl.po pt_BR.po ro.po rw.po sv.po zh_CN.po xh.po -POSUB = po -PO_IN_DATADIR_FALSE = -PO_IN_DATADIR_TRUE = -SCROLLKEEPER_BUILD_REQUIRED = 0.3.5 -SCROLLKEEPER_CONFIG = /usr/bin/scrollkeeper-config -SET_MAKE = -SHELL = /bin/sh -STRIP = -USE_NLS = yes -VERSION = 0.37.2 -XGETTEXT = /usr/bin/xgettext -ac_ct_CC = gcc -ac_ct_STRIP = -am__fastdepCC_FALSE = -am__fastdepCC_TRUE = # -am__include = include -am__leading_dot = . -am__quote = -am__tar = ${AMTAR} chof - "$$tardir" -am__untar = ${AMTAR} xf - -bindir = ${exec_prefix}/bin -build_alias = -datadir = ${prefix}/share -exec_prefix = ${prefix} -host_alias = -includedir = ${prefix}/include -infodir = ${prefix}/info -install_sh = /tmp/3/update-manager-0.37.1+svn20050404.15/install-sh -libdir = ${exec_prefix}/lib -libexecdir = ${exec_prefix}/libexec -localstatedir = ${prefix}/var -mandir = ${prefix}/man -mkdir_p = mkdir -p -- -oldincludedir = /usr/include -prefix = /tmp/lala -program_transform_name = s,x,x, -sbindir = ${exec_prefix}/sbin -sharedstatedir = ${prefix}/com -sysconfdir = ${prefix}/etc -target_alias = -modules_DATA = SimpleGladeApp.py DistInfo.py -modulesdir = $(datadir)/update-manager/python -EXTRA_DIST = $(modules_DATA) -all: all-am - -.SUFFIXES: -$(srcdir)/Makefile.in: # $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ - && exit 0; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Common/Makefile'; \ - cd $(top_srcdir) && \ - $(AUTOMAKE) --gnu Common/Makefile -.PRECIOUS: Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: # $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): # $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -uninstall-info-am: -install-modulesDATA: $(modules_DATA) - @$(NORMAL_INSTALL) - test -z "$(modulesdir)" || $(mkdir_p) "$(DESTDIR)$(modulesdir)" - @list='$(modules_DATA)'; for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - f=$(am__strip_dir) \ - echo " $(modulesDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(modulesdir)/$$f'"; \ - $(modulesDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(modulesdir)/$$f"; \ - done - -uninstall-modulesDATA: - @$(NORMAL_UNINSTALL) - @list='$(modules_DATA)'; for p in $$list; do \ - f=$(am__strip_dir) \ - echo " rm -f '$(DESTDIR)$(modulesdir)/$$f'"; \ - rm -f "$(DESTDIR)$(modulesdir)/$$f"; \ - done -tags: TAGS -TAGS: - -ctags: CTAGS -CTAGS: - - -distdir: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ - list='$(DISTFILES)'; for file in $$list; do \ - case $$file in \ - $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ - $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ - esac; \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test "$$dir" != "$$file" && test "$$dir" != "."; then \ - dir="/$$dir"; \ - $(mkdir_p) "$(distdir)$$dir"; \ - else \ - dir=''; \ - fi; \ - if test -d $$d/$$file; then \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ - fi; \ - cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ - else \ - test -f $(distdir)/$$file \ - || cp -p $$d/$$file $(distdir)/$$file \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-am -all-am: Makefile $(DATA) -installdirs: - for dir in "$(DESTDIR)$(modulesdir)"; do \ - test -z "$$dir" || $(mkdir_p) "$$dir"; \ - done -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-generic mostlyclean-am - -distclean: distclean-am - -rm -f Makefile -distclean-am: clean-am distclean-generic - -dvi: dvi-am - -dvi-am: - -html: html-am - -info: info-am - -info-am: - -install-data-am: install-modulesDATA - -install-exec-am: - -install-info: install-info-am - -install-man: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-generic - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: uninstall-info-am uninstall-modulesDATA - -.PHONY: all all-am check check-am clean clean-generic distclean \ - distclean-generic distdir dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-exec \ - install-exec-am install-info install-info-am install-man \ - install-modulesDATA install-strip installcheck installcheck-am \ - installdirs maintainer-clean maintainer-clean-generic \ - mostlyclean mostlyclean-generic pdf pdf-am ps ps-am uninstall \ - uninstall-am uninstall-info-am uninstall-modulesDATA - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/UpdateManager/Common/Makefile.am b/UpdateManager/Common/Makefile.am deleted file mode 100644 index e32500bd..00000000 --- a/UpdateManager/Common/Makefile.am +++ /dev/null @@ -1,5 +0,0 @@ -modules_DATA = SimpleGladeApp.py DistInfo.py -modulesdir = $(datadir)/update-manager/python - - -EXTRA_DIST = $(modules_DATA) diff --git a/UpdateManager/Common/SimpleGladeApp.py b/UpdateManager/Common/SimpleGladeApp.py deleted file mode 100644 index 90c598cc..00000000 --- a/UpdateManager/Common/SimpleGladeApp.py +++ /dev/null @@ -1,341 +0,0 @@ -""" - SimpleGladeApp.py - Module that provides an object oriented abstraction to pygtk and libglade. - Copyright (C) 2004 Sandino Flores Moreno -""" - -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 -# USA - -import os -import sys -import re - -import tokenize -import gtk -import gtk.glade -import weakref -import inspect - -__version__ = "1.0" -__author__ = 'Sandino "tigrux" Flores-Moreno' - -def bindtextdomain(app_name, locale_dir=None): - """ - Bind the domain represented by app_name to the locale directory locale_dir. - It has the effect of loading translations, enabling applications for different - languages. - - app_name: - a domain to look for translations, tipically the name of an application. - - locale_dir: - a directory with locales like locale_dir/lang_isocode/LC_MESSAGES/app_name.mo - If omitted or None, then the current binding for app_name is used. - """ - try: - import locale - import gettext - locale.setlocale(locale.LC_ALL, "") - gtk.glade.bindtextdomain(app_name, locale_dir) - gettext.install(app_name, locale_dir, unicode=1) - except (IOError,locale.Error), e: - print "Warning", app_name, e - __builtins__.__dict__["_"] = lambda x : x - - -class SimpleGladeApp: - - def __init__(self, path, root=None, domain=None, **kwargs): - """ - Load a glade file specified by glade_filename, using root as - root widget and domain as the domain for translations. - - If it receives extra named arguments (argname=value), then they are used - as attributes of the instance. - - path: - path to a glade filename. - If glade_filename cannot be found, then it will be searched in the - same directory of the program (sys.argv[0]) - - root: - the name of the widget that is the root of the user interface, - usually a window or dialog (a top level widget). - If None or ommited, the full user interface is loaded. - - domain: - A domain to use for loading translations. - If None or ommited, no translation is loaded. - - **kwargs: - a dictionary representing the named extra arguments. - It is useful to set attributes of new instances, for example: - glade_app = SimpleGladeApp("ui.glade", foo="some value", bar="another value") - sets two attributes (foo and bar) to glade_app. - """ - if os.path.isfile(path): - self.glade_path = path - else: - glade_dir = os.path.dirname( sys.argv[0] ) - self.glade_path = os.path.join(glade_dir, path) - for key, value in kwargs.items(): - try: - setattr(self, key, weakref.proxy(value) ) - except TypeError: - setattr(self, key, value) - self.glade = None - self.install_custom_handler(self.custom_handler) - self.glade = self.create_glade(self.glade_path, root, domain) - if root: - self.main_widget = self.get_widget(root) - else: - self.main_widget = None - self.normalize_names() - self.add_callbacks(self) - self.new() - - def __repr__(self): - class_name = self.__class__.__name__ - if self.main_widget: - root = gtk.Widget.get_name(self.main_widget) - repr = '%s(path="%s", root="%s")' % (class_name, self.glade_path, root) - else: - repr = '%s(path="%s")' % (class_name, self.glade_path) - return repr - - def new(self): - """ - Method called when the user interface is loaded and ready to be used. - At this moment, the widgets are loaded and can be refered as self.widget_name - """ - pass - - def add_callbacks(self, callbacks_proxy): - """ - It uses the methods of callbacks_proxy as callbacks. - The callbacks are specified by using: - Properties window -> Signals tab - in glade-2 (or any other gui designer like gazpacho). - - Methods of classes inheriting from SimpleGladeApp are used as - callbacks automatically. - - callbacks_proxy: - an instance with methods as code of callbacks. - It means it has methods like on_button1_clicked, on_entry1_activate, etc. - """ - self.glade.signal_autoconnect(callbacks_proxy) - - def normalize_names(self): - """ - It is internally used to normalize the name of the widgets. - It means a widget named foo:vbox-dialog in glade - is refered self.vbox_dialog in the code. - - It also sets a data "prefixes" with the list of - prefixes a widget has for each widget. - """ - for widget in self.get_widgets(): - widget_name = gtk.Widget.get_name(widget) - prefixes_name_l = widget_name.split(":") - prefixes = prefixes_name_l[ : -1] - widget_api_name = prefixes_name_l[-1] - widget_api_name = "_".join( re.findall(tokenize.Name, widget_api_name) ) - gtk.Widget.set_name(widget, widget_api_name) - if hasattr(self, widget_api_name): - raise AttributeError("instance %s already has an attribute %s" % (self,widget_api_name)) - else: - setattr(self, widget_api_name, widget) - if prefixes: - gtk.Widget.set_data(widget, "prefixes", prefixes) - - def add_prefix_actions(self, prefix_actions_proxy): - """ - By using a gui designer (glade-2, gazpacho, etc) - widgets can have a prefix in theirs names - like foo:entry1 or foo:label3 - It means entry1 and label3 has a prefix action named foo. - - Then, prefix_actions_proxy must have a method named prefix_foo which - is called everytime a widget with prefix foo is found, using the found widget - as argument. - - prefix_actions_proxy: - An instance with methods as prefix actions. - It means it has methods like prefix_foo, prefix_bar, etc. - """ - prefix_s = "prefix_" - prefix_pos = len(prefix_s) - - is_method = lambda t : callable( t[1] ) - is_prefix_action = lambda t : t[0].startswith(prefix_s) - drop_prefix = lambda (k,w): (k[prefix_pos:],w) - - members_t = inspect.getmembers(prefix_actions_proxy) - methods_t = filter(is_method, members_t) - prefix_actions_t = filter(is_prefix_action, methods_t) - prefix_actions_d = dict( map(drop_prefix, prefix_actions_t) ) - - for widget in self.get_widgets(): - prefixes = gtk.Widget.get_data(widget, "prefixes") - if prefixes: - for prefix in prefixes: - if prefix in prefix_actions_d: - prefix_action = prefix_actions_d[prefix] - prefix_action(widget) - - def custom_handler(self, - glade, function_name, widget_name, - str1, str2, int1, int2): - """ - Generic handler for creating custom widgets, internally used to - enable custom widgets (custom widgets of glade). - - The custom widgets have a creation function specified in design time. - Those creation functions are always called with str1,str2,int1,int2 as - arguments, that are values specified in design time. - - Methods of classes inheriting from SimpleGladeApp are used as - creation functions automatically. - - If a custom widget has create_foo as creation function, then the - method named create_foo is called with str1,str2,int1,int2 as arguments. - """ - try: - handler = getattr(self, function_name) - return handler(str1, str2, int1, int2) - except AttributeError: - return None - - def gtk_widget_show(self, widget, *args): - """ - Predefined callback. - The widget is showed. - Equivalent to widget.show() - """ - widget.show() - - def gtk_widget_hide(self, widget, *args): - """ - Predefined callback. - The widget is hidden. - Equivalent to widget.hide() - """ - widget.hide() - - def gtk_widget_grab_focus(self, widget, *args): - """ - Predefined callback. - The widget grabs the focus. - Equivalent to widget.grab_focus() - """ - widget.grab_focus() - - def gtk_widget_destroy(self, widget, *args): - """ - Predefined callback. - The widget is destroyed. - Equivalent to widget.destroy() - """ - widget.destroy() - - def gtk_window_activate_default(self, window, *args): - """ - Predefined callback. - The default widget of the window is activated. - Equivalent to window.activate_default() - """ - widget.activate_default() - - def gtk_true(self, *args): - """ - Predefined callback. - Equivalent to return True in a callback. - Useful for stopping propagation of signals. - """ - return True - - def gtk_false(self, *args): - """ - Predefined callback. - Equivalent to return False in a callback. - """ - return False - - def gtk_main_quit(self, *args): - """ - Predefined callback. - Equivalent to self.quit() - """ - self.quit() - - def main(self): - """ - Starts the main loop of processing events. - The default implementation calls gtk.main() - - Useful for applications that needs a non gtk main loop. - For example, applications based on gstreamer needs to override - this method with gst.main() - - Do not directly call this method in your programs. - Use the method run() instead. - """ - gtk.main() - - def quit(self): - """ - Quit processing events. - The default implementation calls gtk.main_quit() - - Useful for applications that needs a non gtk main loop. - For example, applications based on gstreamer needs to override - this method with gst.main_quit() - """ - gtk.main_quit() - - def run(self): - """ - Starts the main loop of processing events checking for Control-C. - - The default implementation checks wheter a Control-C is pressed, - then calls on_keyboard_interrupt(). - - Use this method for starting programs. - """ - try: - self.main() - except KeyboardInterrupt: - self.on_keyboard_interrupt() - - def on_keyboard_interrupt(self): - """ - This method is called by the default implementation of run() - after a program is finished by pressing Control-C. - """ - pass - - def install_custom_handler(self, custom_handler): - gtk.glade.set_custom_handler(custom_handler) - - def create_glade(self, glade_path, root, domain): - return gtk.glade.XML(self.glade_path, root, domain) - - def get_widget(self, widget_name): - return self.glade.get_widget(widget_name) - - def get_widgets(self): - return self.glade.get_widget_prefix("") diff --git a/UpdateManager/Common/__init__.py b/UpdateManager/Common/__init__.py deleted file mode 100644 index 139597f9..00000000 --- a/UpdateManager/Common/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/UpdateManager/Common/aptsources.py b/UpdateManager/Common/aptsources.py deleted file mode 100644 index 34b5b967..00000000 --- a/UpdateManager/Common/aptsources.py +++ /dev/null @@ -1,694 +0,0 @@ -# aptsource.py.in - parse sources.list -# -# Copyright (c) 2004-2006 Canonical -# 2004 Michiel Sikkes -# 2006 Sebastian Heinlein -# -# Author: Michiel Sikkes <michiel@eyesopened.nl> -# Michael Vogt <mvo@debian.org> -# Sebastian Heinlein -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 -# USA - -import string -import gettext -import re -import apt_pkg -import glob -import shutil -import time -import os.path -import sys - -#import pdb - -#from UpdateManager.Common.DistInfo import DistInfo -from DistInfo import DistInfo - -# some global helpers -def is_mirror(master_uri, compare_uri): - """check if the given add_url is idential or a mirror of orig_uri - e.g. master_uri = archive.ubuntu.com - compare_uri = de.archive.ubuntu.com - -> True - """ - # remove traling spaces and "/" - compare_uri = compare_uri.rstrip("/ ") - master_uri = master_uri.rstrip("/ ") - # uri is identical - if compare_uri == master_uri: - #print "Identical" - return True - # add uri is a master site and orig_uri has the from "XX.mastersite" - # (e.g. de.archive.ubuntu.com) - try: - compare_srv = compare_uri.split("//")[1] - master_srv = master_uri.split("//")[1] - #print "%s == %s " % (add_srv, orig_srv) - except IndexError: # ok, somethings wrong here - #print "IndexError" - return False - # remove the leading "<country>." (if any) and see if that helps - if "." in compare_srv and \ - compare_srv[compare_srv.index(".")+1:] == master_srv: - #print "Mirror" - return True - return False - -def uniq(s): - """ simple and efficient way to return uniq list """ - return list(set(s)) - -class SourceEntry: - """ single sources.list entry """ - def __init__(self, line,file=None): - self.invalid = False # is the source entry valid - self.disabled = False # is it disabled ('#' in front) - self.type = "" # what type (deb, deb-src) - self.uri = "" # base-uri - self.dist = "" # distribution (dapper, edgy, etc) - self.comps = [] # list of available componetns (may empty) - self.comment = "" # (optional) comment - self.line = line # the original sources.list line - if file == None: - file = apt_pkg.Config.FindDir("Dir::Etc")+apt_pkg.Config.Find("Dir::Etc::sourcelist") - self.file = file # the file that the entry is located in - self.parse(line) - self.template = None # type DistInfo.Suite - self.children = [] - - def __eq__(self, other): - """ equal operator for two sources.list entries """ - return (self.disabled == other.disabled and - self.type == other.type and - self.uri == other.uri and - self.dist == other.dist and - self.comps == other.comps) - - - def mysplit(self, line): - """ a split() implementation that understands the sources.list - format better and takes [] into account (for e.g. cdroms) """ - line = string.strip(line) - pieces = [] - tmp = "" - # we are inside a [..] block - p_found = False - space_found = False - for i in range(len(line)): - if line[i] == "[": - p_found=True - tmp += line[i] - elif line[i] == "]": - p_found=False - tmp += line[i] - elif space_found and not line[i].isspace(): # we skip one or more space - space_found = False - pieces.append(tmp) - tmp = line[i] - elif line[i].isspace() and not p_found: # found a whitespace - space_found = True - else: - tmp += line[i] - # append last piece - if len(tmp) > 0: - pieces.append(tmp) - return pieces - - def parse(self,line): - """ parse a given sources.list (textual) line and break it up - into the field we have """ - line = string.strip(self.line) - #print line - # check if the source is enabled/disabled - if line == "" or line == "#": # empty line - self.invalid = True - return - if line[0] == "#": - self.disabled = True - pieces = string.split(line[1:]) - # if it looks not like a disabled deb line return - if not (pieces[0] == "deb" or pieces[0] == "deb-src"): - self.invalid = True - return - else: - line = line[1:] - # check for another "#" in the line (this is treated as a comment) - i = line.find("#") - if i > 0: - self.comment = line[i+1:] - line = line[:i] - # source is ok, split it and see what we have - pieces = self.mysplit(line) - # Sanity check - if len(pieces) < 3: - self.invalid = True - return - # Type, deb or deb-src - self.type = string.strip(pieces[0]) - # Sanity check - if self.type not in ("deb", "deb-src"): - self.invalid = True - return - # URI - self.uri = string.strip(pieces[1]) - if len(self.uri) < 1: - self.invalid = True - # distro and components (optional) - # Directory or distro - self.dist = string.strip(pieces[2]) - if len(pieces) > 3: - # List of components - self.comps = pieces[3:] - else: - self.comps = [] - - def set_enabled(self, new_value): - """ set a line to enabled or disabled """ - self.disabled = not new_value - # enable, remove all "#" from the start of the line - if new_value == True: - i=0 - self.line = string.lstrip(self.line) - while self.line[i] == "#": - i += 1 - self.line = self.line[i:] - else: - # disabled, add a "#" - if string.strip(self.line)[0] != "#": - self.line = "#" + self.line - - def __str__(self): - """ debug helper """ - return self.str().strip() - - def str(self): - """ return the current line as string """ - if self.invalid: - return self.line - line = "" - if self.disabled: - line = "# " - line += "%s %s %s" % (self.type, self.uri, self.dist) - if len(self.comps) > 0: - line += " " + " ".join(self.comps) - if self.comment != "": - line += " #"+self.comment - line += "\n" - return line - -class NullMatcher(object): - """ a Matcher that does nothing """ - def match(self, s): - return True - -class SourcesList: - """ represents the full sources.list + sources.list.d file """ - def __init__(self, - withMatcher=True, - matcherPath="/usr/share/update-manager/channels/"): - self.list = [] # the actual SourceEntries Type - if withMatcher: - self.matcher = SourceEntryMatcher(matcherPath) - else: - self.matcher = NullMatcher() - self.refresh() - - def refresh(self): - """ update the list of known entries """ - self.list = [] - # read sources.list - dir = apt_pkg.Config.FindDir("Dir::Etc") - file = apt_pkg.Config.Find("Dir::Etc::sourcelist") - self.load(dir+file) - # read sources.list.d - partsdir = apt_pkg.Config.FindDir("Dir::Etc::sourceparts") - for file in glob.glob("%s/*.list" % partsdir): - self.load(file) - # check if the source item fits a predefined template - for source in self.list: - if source.invalid == False: - self.matcher.match(source) - - def __iter__(self): - """ simple iterator to go over self.list, returns SourceEntry - types """ - for entry in self.list: - yield entry - raise StopIteration - - def add(self, type, uri, dist, comps, comment="", pos=-1, file=None): - """ - Add a new source to the sources.list. - The method will search for existing matching repos and will try to - reuse them as far as possible - """ - # check if we have this source already in the sources.list - for source in self.list: - if source.disabled == False and source.invalid == False and \ - source.type == type and uri == source.uri and \ - source.dist == dist: - for new_comp in comps: - if new_comp in source.comps: - # we have this component already, delete it from the new_comps - # list - del comps[comps.index(new_comp)] - if len(comps) == 0: - return source - for source in self.list: - # if there is a repo with the same (type, uri, dist) just add the - # components - if source.disabled == False and source.invalid == False and \ - source.type == type and uri == source.uri and \ - source.dist == dist: - comps = uniq(source.comps + comps) - source.comps = comps - return source - # if there is a corresponding repo which is disabled, enable it - elif source.disabled == True and source.invalid == False and \ - source.type == type and uri == source.uri and \ - source.dist == dist and \ - len(set(source.comps) & set(comps)) == len(comps): - source.disabled = False - return source - # there isn't any matching source, so create a new line and parse it - line = "%s %s %s" % (type,uri,dist) - for c in comps: - line = line + " " + c; - if comment != "": - line = "%s #%s\n" %(line,comment) - line = line + "\n" - new_entry = SourceEntry(line) - if file != None: - new_entry.file = file - self.matcher.match(new_entry) - self.list.insert(pos, new_entry) - return new_entry - - def remove(self, source_entry): - """ remove the specified entry from the sources.list """ - self.list.remove(source_entry) - - def restoreBackup(self, backup_ext): - " restore sources.list files based on the backup extension " - dir = apt_pkg.Config.FindDir("Dir::Etc") - file = apt_pkg.Config.Find("Dir::Etc::sourcelist") - if os.path.exists(dir+file+backup_ext): - shutil.copy(dir+file+backup_ext,dir+file) - # now sources.list.d - partsdir = apt_pkg.Config.FindDir("Dir::Etc::sourceparts") - for file in glob.glob("%s/*.list" % partsdir): - if os.path.exists(file+backup_ext): - shutil.copy(file+backup_ext,file) - - def backup(self, backup_ext=None): - """ make a backup of the current source files, if no backup extension - is given, the current date/time is used (and returned) """ - already_backuped = set() - if backup_ext == None: - backup_ext = time.strftime("%y%m%d.%H%M") - for source in self.list: - if not source.file in already_backuped: - shutil.copy(source.file,"%s%s" % (source.file,backup_ext)) - return backup_ext - - def load(self,file): - """ (re)load the current sources """ - try: - f = open(file, "r") - lines = f.readlines() - for line in lines: - source = SourceEntry(line,file) - self.list.append(source) - except: - print "could not open file '%s'" % file - else: - f.close() - - def save(self): - """ save the current sources """ - files = {} - for source in self.list: - if not files.has_key(source.file): - files[source.file]=open(source.file,"w") - files[source.file].write(source.str()) - for f in files: - files[f].close() - - def check_for_relations(self, sources_list): - """get all parent and child channels in the sources list""" - parents = [] - used_child_templates = {} - for source in sources_list: - # try to avoid checking uninterressting sources - if source.template == None: - continue - # set up a dict with all used child templates and corresponding - # source entries - if source.template.child == True: - key = source.template - if not used_child_templates.has_key(key): - used_child_templates[key] = [] - temp = used_child_templates[key] - temp.append(source) - else: - # store each source with children aka. a parent :) - if len(source.template.children) > 0: - parents.append(source) - #print self.used_child_templates - #print self.parents - return (parents, used_child_templates) - -# matcher class to make a source entry look nice -# lots of predefined matchers to make it i18n/gettext friendly -class SourceEntryMatcher: - class MatchType: - def __init__(self, a_type,a_descr): - self.type = a_type - self.description = a_descr - - class MatchDist: - def __init__(self,a_uri,a_dist, a_descr,l_comps, l_comps_descr): - self.uri = a_uri - self.dist = a_dist - self.description = a_descr - self.comps = l_comps - self.comps_descriptions = l_comps_descr - - def __init__(self, matcherPath): - self.templates = [] - # Get the human readable channel and comp names from the channel .infos - spec_files = glob.glob("%s/*.info" % matcherPath) - for f in spec_files: - f = os.path.basename(f) - i = f.find(".info") - f = f[0:i] - dist = DistInfo(f,base_dir=matcherPath) - for suite in dist.suites: - if suite.match_uri != None: - self.templates.append(suite) - return - - def match(self, source): - """Add a matching template to the source""" - _ = gettext.gettext - found = False - for template in self.templates: - if (re.search(template.match_uri, source.uri) and - re.match(template.match_name, source.dist)): - found = True - source.template = template - break - for mirror in template.valid_mirrors: - if (is_mirror(mirror,source.uri) and - re.match(template.match_name, source.dist)): - found = True - source.template = template - break - return found - -class Distribution: - def __init__(self): - """ Container for distribution specific informations """ - # LSB information - self.id = "" - self.codename = "" - self.description = "" - self.release = "" - - # get the LSB information - lsb_info = [] - for lsb_option in ["-i", "-c", "-d", "-r"]: - pipe = os.popen("lsb_release %s -s" % lsb_option) - lsb_info.append(pipe.read().strip()) - del pipe - (self.id, self.codename, self.description, self.release) = lsb_info - - # get a list of country codes and real names - self.countries = {} - try: - f = open("/usr/share/iso-codes/iso_3166.tab", "r") - lines = f.readlines() - for line in lines: - parts = line.split("\t") - self.countries[parts[0].lower()] = parts[1] - except: - print "could not open file '%s'" % file - else: - f.close() - - def get_sources(self, sources_list): - """ - Find the corresponding template, main and child sources - for the distribution - """ - # corresponding sources - self.source_template = None - self.child_sources = [] - self.main_sources = [] - self.disabled_sources = [] - self.cdrom_sources = [] - self.download_comps = [] - self.enabled_comps = [] - self.cdrom_comps = [] - self.used_media = [] - self.get_source_code = False - self.source_code_sources = [] - - # location of the sources - self.default_server = "" - self.main_server = "" - self.nearest_server = "" - self.used_servers = [] - - # find the distro template - for template in sources_list.matcher.templates: - if template.name == self.codename and\ - template.distribution == self.id: - #print "yeah! found a template for %s" % self.description - #print template.description, template.base_uri, template.components - self.source_template = template - break - if self.source_template == None: - print "Error: could not find a distribution template" - # FIXME: will go away - only for debugging issues - sys.exit(1) - - # find main and child sources - media = [] - comps = [] - cdrom_comps = [] - enabled_comps = [] - source_code = [] - for source in sources_list.list: - if source.invalid == False and\ - source.dist == self.codename and\ - source.template and\ - source.template.name == self.codename: - #print "yeah! found a distro repo: %s" % source.line - # cdroms need do be handled differently - if source.uri.startswith("cdrom:") and \ - source.disabled == False: - self.cdrom_sources.append(source) - cdrom_comps.extend(source.comps) - elif source.uri.startswith("cdrom:") and \ - source.disabled == True: - self.cdrom_sources.append(source) - elif source.type == "deb" and source.disabled == False: - self.main_sources.append(source) - comps.extend(source.comps) - media.append(source.uri) - elif source.type == "deb" and source.disabled == True: - self.disabled_sources.append(source) - elif source.type.endswith("-src") and source.disabled == False: - self.source_code_sources.append(source) - elif source.type.endswith("-src") and source.disabled == True: - self.disabled_sources.append(source) - if source.invalid == False and\ - source.template in self.source_template.children: - if source.disabled == False and source.type == "deb": - self.child_sources.append(source) - elif source.disabled == False and source.type == "deb-src": - self.source_code_sources.append(source) - else: - self.disabled_sources.append(source) - self.download_comps = set(comps) - self.cdrom_comps = set(cdrom_comps) - enabled_comps.extend(comps) - enabled_comps.extend(cdrom_comps) - self.enabled_comps = set(enabled_comps) - self.used_media = set(media) - - self.get_mirrors() - - def get_mirrors(self): - """ - Provide a set of mirrors where you can get the distribution from - """ - # the main server is stored in the template - self.main_server = self.source_template.base_uri - - # try to guess the nearest mirror from the locale - # FIXME: for debian we need something different - if self.id == "Ubuntu": - locale = os.getenv("LANG", default="en.UK") - a = locale.find("_") - z = locale.find(".") - if z == -1: - z = len(locale) - country_code = locale[a+1:z].lower() - self.nearest_server = "http://%s.archive.ubuntu.com/ubuntu/" % \ - country_code - if self.countries.has_key(country_code): - self.country = self.countries[country_code] - else: - self.country = None - - # other used servers - for medium in self.used_media: - if not medium.startswith("cdrom:"): - # seems to be a network source - self.used_servers.append(medium) - - if len(self.main_sources) == 0: - self.default_server = self.main_server - else: - self.default_server = self.main_sources[0].uri - - def add_source(self, sources_list, type=None, - uri=None, dist=None, comps=None, comment=""): - """ - Add distribution specific sources - """ - if uri == None: - # FIXME: Add support for the server selector - uri = self.default_server - if dist == None: - dist = self.codename - if comps == None: - comps = list(self.enabled_comps) - if type == None: - type = "deb" - if comment == "": - comment == "Added by software-properties" - new_source = sources_list.add(type, uri, dist, comps, comment) - # if source code is enabled add a deb-src line after the new - # source - if self.get_source_code == True and not type.endswith("-src"): - sources_list.add("%s-src" % type, uri, dist, comps, comment, - file=new_source.file, - pos=sources_list.list.index(new_source)+1) - - def enable_component(self, sourceslist, comp): - """ - Enable a component in all main, child and source code sources - (excluding cdrom based sources) - - sourceslist: an aptsource.sources_list - comp: the component that should be enabled - """ - def add_component_only_once(source, comps_per_dist): - """ - Check if we already added the component to the repository, since - a repository could be splitted into different apt lines. If not - add the component - """ - # if we don't that distro, just reutnr (can happen for e.g. - # dapper-update only in deb-src - if not comps_per_dist.has_key(source.dist): - return - # if we have seen this component already for this distro, - # return (nothing to do - if comp in comps_per_dist[source.dist]: - return - # add it - source.comps.append(comp) - comps_per_dist[source.dist].add(comp) - - sources = [] - sources.extend(self.main_sources) - sources.extend(self.child_sources) - sources.extend(self.source_code_sources) - # store what comps are enabled already per distro (where distro is - # e.g. "dapper", "dapper-updates") - comps_per_dist = {} - for s in sources: - if s.type != "deb": - continue - if not comps_per_dist.has_key(s.dist): - comps_per_dist[s.dist] = set() - map(comps_per_dist[s.dist].add, s.comps) - # check if there is a main source at all - if len(self.main_sources) < 1: - # create a new main source - self.add_source(sourceslist, comps=["%s"%comp]) - else: - # add the comp to all main, child and source code sources - for source in sources: - add_component_only_once(source, comps_per_dist) - - # now do the same for source dists - if self.get_source_code == True: - comps_per_dist = {} - for s in self.source_code_sources: - if s.type != "deb-src": - continue - if not comps_per_dist.has_key(s.dist): - comps_per_dist[s.dist] = set() - map(comps_per_dist[s.dist].add, s.comps) - for source in self.source_code_sources: - if comp not in source.comps: - add_component_only_once(source, comps_per_dist) - - - def disable_component(self, sourceslist, comp): - """ - Disable a component in all main, child and source code sources - (excluding cdrom based sources) - """ - sources = [] - sources.extend(self.main_sources) - sources.extend(self.child_sources) - sources.extend(self.source_code_sources) - if comp in self.cdrom_comps: - sources = [] - sources.extend(self.main_sources) - - for source in sources: - if comp in source.comps: - source.comps.remove(comp) - if len(source.comps) < 1: - sourceslist.remove(source) - - -# some simple tests -if __name__ == "__main__": - apt_pkg.InitConfig() - sources = SourcesList() - - for entry in sources: - print entry.str() - #print entry.uri - - mirror = is_mirror("http://archive.ubuntu.com/ubuntu/", - "http://de.archive.ubuntu.com/ubuntu/") - print "is_mirror(): %s" % mirror - - print is_mirror("http://archive.ubuntu.com/ubuntu", - "http://de.archive.ubuntu.com/ubuntu/") - print is_mirror("http://archive.ubuntu.com/ubuntu/", - "http://de.archive.ubuntu.com/ubuntu") - diff --git a/UpdateManager/Common/utils.py b/UpdateManager/Common/utils.py deleted file mode 100644 index 1fcd022f..00000000 --- a/UpdateManager/Common/utils.py +++ /dev/null @@ -1,42 +0,0 @@ -import gtk -from gettext import gettext as _ -import locale - -def str_to_bool(str): - if str == "0" or str.upper() == "FALSE": - return False - return True - -def utf8(str): - return unicode(str, 'latin1').encode('utf-8') - - -def error(parent, summary, message): - d = gtk.MessageDialog(parent=parent, - flags=gtk.DIALOG_MODAL, - type=gtk.MESSAGE_ERROR, - buttons=gtk.BUTTONS_CLOSE) - d.set_markup("<big><b>%s</b></big>\n\n%s" % (summary, message)) - d.realize() - d.window.set_functions(gtk.gdk.FUNC_MOVE) - d.set_title("") - res = d.run() - d.destroy() - return - -def humanize_size(bytes): - """ - Convert a given size in bytes to a nicer better readable unit - """ - if bytes == 0: - # TRANSLATORS: download size is 0 - return _("None") - elif bytes < 1024: - # TRANSLATORS: download size of very small updates - return _("1 KB") - elif bytes < 1024 * 1024: - # TRANSLATORS: download size of small updates, e.g. "250 KB" - return locale.format(_("%.0f KB"), bytes/1024) - else: - # TRANSLATORS: download size of updates, e.g. "2.3 MB" - return locale.format(_("%.1f MB"), bytes / 1024 / 1024) diff --git a/UpdateManager/DistUpgradeFetcher.py b/UpdateManager/DistUpgradeFetcher.py deleted file mode 100644 index cda27e2f..00000000 --- a/UpdateManager/DistUpgradeFetcher.py +++ /dev/null @@ -1,240 +0,0 @@ -# DistUpgradeFetcher.py -# -# Copyright (c) 2006 Canonical -# -# Author: Michael Vogt <michael.vogt@ubuntu.com> -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 -# USA - -import pygtk -pygtk.require('2.0') -import gtk -import os -import apt_pkg -import tarfile -import urllib2 -import tempfile -import shutil -import GnuPGInterface -from gettext import gettext as _ - -import GtkProgress -from ReleaseNotesViewer import ReleaseNotesViewer -from Common.utils import * - -class DistUpgradeFetcher(object): - - def __init__(self, parent, new_dist): - self.parent = parent - self.window_main = parent.window_main - self.new_dist = new_dist - - def showReleaseNotes(self): - # FIXME: care about i18n! (append -$lang or something) - if self.new_dist.releaseNotesURI != None: - uri = self.new_dist.releaseNotesURI - self.window_main.set_sensitive(False) - self.window_main.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH)) - while gtk.events_pending(): - gtk.main_iteration() - - # download/display the release notes - # FIXME: add some progress reporting here - res = gtk.RESPONSE_CANCEL - try: - release_notes = urllib2.urlopen(uri) - notes = release_notes.read() - textview_release_notes = ReleaseNotesViewer(notes) - textview_release_notes.show() - self.parent.scrolled_notes.add(textview_release_notes) - self.parent.dialog_release_notes.set_transient_for(self.window_main) - res = self.parent.dialog_release_notes.run() - self.parent.dialog_release_notes.hide() - except urllib2.HTTPError: - primary = "<span weight=\"bold\" size=\"larger\">%s</span>" % \ - _("Could not find the release notes") - secondary = _("The server may be overloaded. ") - dialog = gtk.MessageDialog(self.window_main,gtk.DIALOG_MODAL, - gtk.MESSAGE_ERROR,gtk.BUTTONS_CLOSE,"") - dialog.set_title("") - dialog.set_markup(primary); - dialog.format_secondary_text(secondary); - dialog.run() - dialog.destroy() - except IOError: - primary = "<span weight=\"bold\" size=\"larger\">%s</span>" % \ - _("Could not download the release notes") - secondary = _("Please check your internet connection.") - dialog = gtk.MessageDialog(self.window_main,gtk.DIALOG_MODAL, - gtk.MESSAGE_ERROR,gtk.BUTTONS_CLOSE,"") - dialog.set_title("") - dialog.set_markup(primary); - dialog.format_secondary_text(secondary); - dialog.run() - dialog.destroy() - self.window_main.set_sensitive(True) - self.window_main.window.set_cursor(None) - # user clicked cancel - if res == gtk.RESPONSE_CANCEL: - return False - return True - - def authenticate(self): - if self.new_dist.upgradeToolSig: - f = self.tmpdir+"/"+os.path.basename(self.new_dist.upgradeTool) - sig = self.tmpdir+"/"+os.path.basename(self.new_dist.upgradeToolSig) - print "authenticate '%s' against '%s' " % (f,sig) - if not self.gpgauthenticate(f, sig): - return False - - # we may return False here by default if we want to make a sig - # mandatory - return True - - def gpgauthenticate(self, file, signature, - keyring='/etc/apt/trusted.gpg'): - """ authenticated a file against a given signature, if no keyring - is given use the apt default keyring - """ - gpg = GnuPGInterface.GnuPG() - gpg.options.extra_args = ['--no-options', - '--no-default-keyring', - '--keyring', keyring] - proc = gpg.run(['--verify', signature, file], - create_fhs=['status','logger','stderr']) - gpgres = proc.handles['status'].read() - try: - proc.wait() - except IOError,e: - # gnupg returned a problem (non-zero exit) - print "exception from gpg: %s" % e - return False - if "VALIDSIG" in gpgres: - return True - print "invalid result from gpg:" - print gpgres - return False - - def extractDistUpgrader(self): - # extract the tarbal - print "extracting '%s'" % (self.tmpdir+"/"+os.path.basename(self.uri)) - tar = tarfile.open(self.tmpdir+"/"+os.path.basename(self.uri),"r") - for tarinfo in tar: - tar.extract(tarinfo) - tar.close() - return True - - def verifyDistUprader(self): - # FIXME: check a internal dependency file to make sure - # that the script will run correctly - - # see if we have a script file that we can run - self.script = script = "%s/%s" % (self.tmpdir, self.new_dist.name) - if not os.path.exists(script): - # no script file found in extracted tarbal - primary = "<span weight=\"bold\" size=\"larger\">%s</span>" % \ - _("Could not run the upgrade tool") - secondary = _("This is most likely a bug in the upgrade tool. " - "Please report it as a bug") - dialog = gtk.MessageDialog(self.window_main,gtk.DIALOG_MODAL, - gtk.MESSAGE_ERROR,gtk.BUTTONS_CLOSE,"") - dialog.set_title("") - dialog.set_markup(primary); - dialog.format_secondary_text(secondary); - dialog.run() - dialog.destroy() - return False - return True - - def fetchDistUpgrader(self): - # now download the tarball with the upgrade script - self.tmpdir = tmpdir = tempfile.mkdtemp() - os.chdir(tmpdir) - - # turn debugging on here (if required) - #apt_pkg.Config.Set("Debug::Acquire::http","1") - - progress = GtkProgress.GtkFetchProgress(self.parent, - _("Downloading the upgrade " - "tool"), - _("The upgrade tool will " - "guide you through the " - "upgrade process.")) - fetcher = apt_pkg.GetAcquire(progress) - - if self.new_dist.upgradeToolSig != None: - uri = self.new_dist.upgradeToolSig - af = apt_pkg.GetPkgAcqFile(fetcher,uri, descr=_("Upgrade tool signature")) - if self.new_dist.upgradeTool != None: - self.uri = self.new_dist.upgradeTool - af = apt_pkg.GetPkgAcqFile(fetcher,self.uri, descr=_("Upgrade tool")) - if fetcher.Run() != fetcher.ResultContinue: - return False - return True - return False - - def runDistUpgrader(self): - #print "runing: %s" % script - if os.getuid() != 0: - os.execv("/usr/bin/gksu",["gksu",self.script]) - else: - os.execv(self.script,[self.script]) - - def cleanup(self): - # cleanup - os.chdir("..") - # del tmpdir - shutil.rmtree(self.tmpdir) - - def run(self): - # see if we have release notes - if not self.showReleaseNotes(): - return - if not self.fetchDistUpgrader(): - error(self.window_main, - _("Failed to fetch"), - _("Fetching the upgrade failed. There may be a network " - "problem. ")) - return - if not self.extractDistUpgrader(): - error(self.window_main, - _("Failed to extract"), - _("Extracting the upgrade failed. There may be a problem " - "with the network or with the server. ")) - - return - if not self.verifyDistUprader(): - error(self.window_main, - _("Verfication failed"), - _("Verifying the upgrade failed. There may be a problem " - "with the network or with the server. ")) - self.cleanup() - return - if not self.authenticate(): - error(self.window_main, - _("Authentication failed"), - _("Authenticating the upgrade failed. There may be a problem " - "with the network or with the server. ")) - self.cleanup() - return - self.runDistUpgrader() - - -if __name__ == "__main__": - error(None, "summary","message") - d = DistUpgradeFetcher(None,None) - print d.authenticate('/tmp/Release','/tmp/Release.gpg') - diff --git a/UpdateManager/GtkProgress.py b/UpdateManager/GtkProgress.py deleted file mode 100644 index cb635e87..00000000 --- a/UpdateManager/GtkProgress.py +++ /dev/null @@ -1,125 +0,0 @@ -# GtkProgress.py -# -# Copyright (c) 2004,2005 Canonical -# -# Author: Michael Vogt <michael.vogt@ubuntu.com> -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 -# USA - -import pygtk -pygtk.require('2.0') -import gtk -import apt -import apt_pkg -from gettext import gettext as _ -from Common.utils import * - -# intervals of the start up progress -# 3x caching and menu creation -STEPS_UPDATE_CACHE = [33, 66, 100] - -class GtkOpProgress(apt.OpProgress): - def __init__(self, host_window, progressbar, status, parent, - steps=STEPS_UPDATE_CACHE): - # used for the "one run progressbar" - self.steps = steps[:] - self.base = 0 - self.old = 0 - self.next = int(self.steps.pop(0)) - - self._parent = parent - self._window = host_window - self._status = status - self._progressbar = progressbar - # Do not show the close button - self._window.realize() - host_window.window.set_functions(gtk.gdk.FUNC_MOVE) - self._window.set_transient_for(parent) - - def update(self, percent): - #print percent - #print self.Op - #print self.SubOp - self._window.show() - self._parent.set_sensitive(False) - # if the old percent was higher, a new progress was started - if self.old > percent: - # set the borders to the next interval - self.base = self.next - try: - self.next = int(self.steps.pop(0)) - except: - pass - progress = self.base + percent/100 * (self.next - self.base) - self.old = percent - self._status.set_markup("<i>%s</i>" % self.op) - self._progressbar.set_fraction(progress/100.0) - while gtk.events_pending(): - gtk.main_iteration() - - def done(self): - self._parent.set_sensitive(True) - def hide(self): - self._window.hide() - -class GtkFetchProgress(apt.progress.FetchProgress): - def __init__(self, parent, summary="", descr=""): - # if this is set to false the download will cancel - self._continue = True - # init vars here - # FIXME: find a more elegant way, this sucks - self.summary = parent.label_fetch_summary - self.status = parent.label_fetch_status - self.progress = parent.progressbar_fetch - self.window_fetch = parent.window_fetch - self.window_fetch.set_transient_for(parent.window_main) - self.window_fetch.realize() - self.window_fetch.window.set_functions(gtk.gdk.FUNC_MOVE) - # set summary - if self.summary != "": - self.summary.set_markup("<big><b>%s</b></big> \n\n%s" % - (summary, descr)) - def start(self): - self.progress.set_fraction(0) - self.window_fetch.show() - def stop(self): - self.window_fetch.hide() - def on_button_fetch_cancel_clicked(self, widget): - self._continue = False - def pulse(self): - apt.progress.FetchProgress.pulse(self) - currentItem = self.currentItems + 1 - if currentItem > self.totalItems: - currentItem = self.totalItems - if self.currentCPS > 0: - statusText = (_("Downloading file %(current)li of %(total)li with " - "%(speed)s/s") % {"current" : currentItem, - "total" : self.totalItems, - "speed" : humanize_size(self.currentCPS)}) - else: - statusText = (_("Downloading file %(current)li of %(total)li") % \ - {"current" : currentItem, - "total" : self.totalItems }) - self.progress.set_fraction(self.percent/100.0) - self.status.set_markup("<i>%s</i>" % statusText) - # TRANSLATORS: show the remaining time in a progress bar: - #self.progress.set_text(_("About %s left" % (apt_pkg.TimeToStr(self.eta)))) - # FIXME: show remaining time - self.progress.set_text("") - - while gtk.events_pending(): - gtk.main_iteration() - return self._continue diff --git a/UpdateManager/MetaRelease.py b/UpdateManager/MetaRelease.py deleted file mode 100644 index 70993eaf..00000000 --- a/UpdateManager/MetaRelease.py +++ /dev/null @@ -1,177 +0,0 @@ -# MetaRelease.py -# -# Copyright (c) 2004,2005 Canonical -# -# Author: Michael Vogt <michael.vogt@ubuntu.com> -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 -# USA - -import pygtk -pygtk.require('2.0') -import gobject -import thread -import urllib2 -import os -import string -import apt_pkg -import time -import rfc822 -from subprocess import Popen,PIPE - -class Dist(object): - def __init__(self, name, version, date, supported): - self.name = name - self.version = version - self.date = date - self.supported = supported - self.releaseNotesURI = None - self.upgradeTool = None - self.upgradeToolSig = None - -class MetaRelease(gobject.GObject): - - # some constants - METARELEASE_URI = "http://changelogs.ubuntu.com/meta-release" - METARELEASE_URI_UNSTABLE = "http://changelogs.ubuntu.com/meta-release-development" - METARELEASE_FILE = "/var/lib/update-manager/meta-release" - - __gsignals__ = { - 'new_dist_available' : (gobject.SIGNAL_RUN_LAST, - gobject.TYPE_NONE, - (gobject.TYPE_PYOBJECT,)), - 'dist_no_longer_supported' : (gobject.SIGNAL_RUN_LAST, - gobject.TYPE_NONE, - ()) - - } - - def __init__(self, useDevelopmentRelase=False): - gobject.GObject.__init__(self) - # check what uri to use - if useDevelopmentRelase: - self.METARELEASE_URI = self.METARELEASE_URI_UNSTABLE - # check if we can access the METARELEASE_FILE - if not os.access(self.METARELEASE_FILE, os.F_OK|os.W_OK|os.R_OK): - path = os.path.expanduser("~/.update-manager/") - if not os.path.exists(path): - os.mkdir(path) - self.METARELEASE_FILE = os.path.join(path,"meta-release") - self.metarelease_information = None - self.downloading = True - # we start the download thread here and we have a timeout - # in the gtk space to test if the download already finished - # this is needed because gtk is not thread-safe - t=thread.start_new_thread(self.download, ()) - gobject.timeout_add(1000,self.check) - - def get_dist(self): - " return the codename of the current runing distro " - p = Popen(["/bin/lsb_release","-c","-s"],stdout=PIPE) - res = p.wait() - if res != 0: - sys.stderr.write("lsb_release returned exitcode: %i\n" % res) - dist = string.strip(p.stdout.readline()) - #dist = "breezy" - return dist - - def check(self): - #print "check" - # check if we have a metarelease_information file - if self.metarelease_information != None: - self.parse() - # return False makes g_timeout() stop - return False - # no information yet, keep runing - return True - - def parse(self): - #print "parse" - current_dist_name = self.get_dist() - current_dist = None - dists = [] - - # parse the metarelease_information file - index_tag = apt_pkg.ParseTagFile(self.metarelease_information) - step_result = index_tag.Step() - while step_result: - if index_tag.Section.has_key("Dist"): - name = index_tag.Section["Dist"] - #print name - rawdate = index_tag.Section["Date"] - date = time.mktime(rfc822.parsedate(rawdate)) - supported = bool(index_tag.Section["Supported"]) - version = index_tag.Section["Version"] - # add the information to a new date object - dist = Dist(name, version, date,supported) - if index_tag.Section.has_key("ReleaseNotes"): - dist.releaseNotesURI = index_tag.Section["ReleaseNotes"] - if index_tag.Section.has_key("UpgradeTool"): - dist.upgradeTool = index_tag.Section["UpgradeTool"] - if index_tag.Section.has_key("UpgradeToolSignature"): - dist.upgradeToolSig = index_tag.Section["UpgradeToolSignature"] - dists.append(dist) - if name == current_dist_name: - current_dist = dist - step_result = index_tag.Step() - - # first check if the current runing distro is in the meta-release - # information. if not, we assume that we run on something not - # supported and silently return - if current_dist == None: - print "current dist not found in meta-release file" - return False - - # then see what we can upgrade to (only upgrade to supported dists) - upgradable_to = "" - for dist in dists: - if dist.date > current_dist.date and dist.supported == True: - upgradable_to = dist - #print "new dist: %s" % upgradable_to - break - - # only warn if unsupported and a new dist is available (because - # the development version is also unsupported) - if upgradable_to != "" and not current_dist.supported: - self.emit("dist_no_longer_supported",upgradabl_to) - elif upgradable_to != "": - self.emit("new_dist_available",upgradable_to) - - # parsing done and sucessfully - return True - - # the network thread that tries to fetch the meta-index file - # can't touch the gui, runs as a thread - def download(self): - #print "download" - lastmodified = 0 - req = urllib2.Request(self.METARELEASE_URI) - if os.access(self.METARELEASE_FILE, os.W_OK): - lastmodified = os.stat(self.METARELEASE_FILE).st_mtime - if lastmodified > 0: - req.add_header("If-Modified-Since", lastmodified) - try: - uri=urllib2.urlopen(req) - f=open(self.METARELEASE_FILE,"w+") - for line in uri.readlines(): - f.write(line) - f.flush() - f.seek(0,0) - self.metarelease_information=f - uri.close() - except urllib2.URLError: - if os.path.exists(self.METARELEASE_FILE): - f=open(self.METARELEASE_FILE,"r") - diff --git a/UpdateManager/ReleaseNotesViewer.py b/UpdateManager/ReleaseNotesViewer.py deleted file mode 100644 index 33122be9..00000000 --- a/UpdateManager/ReleaseNotesViewer.py +++ /dev/null @@ -1,179 +0,0 @@ -# ReleaseNotesViewer.py -# -# Copyright (c) 2006 Sebastian Heinlein -# -# Author: Sebastian Heinlein <sebastian.heinlein@web.de> -# -# This modul provides an inheritance of the gtk.TextView that is -# aware of http URLs and allows to open them in a browser. -# It is based on the pygtk-demo "hypertext". -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 -# USA - - -import pygtk -import gtk -import pango -import subprocess -import os - -class ReleaseNotesViewer(gtk.TextView): - def __init__(self, notes): - """Init the ReleaseNotesViewer as an Inheritance of the gtk.TextView. - Load the notes into the buffer and make links clickable""" - # init the parent - gtk.TextView.__init__(self) - # global hovering over link state - self.hovering = False - self.first = True - # setup the buffer and signals - self.set_property("editable", False) - self.set_cursor_visible(False) - self.buffer = gtk.TextBuffer() - self.set_buffer(self.buffer) - self.buffer.set_text(notes) - self.connect("event-after", self.event_after) - self.connect("motion-notify-event", self.motion_notify_event) - self.connect("visibility-notify-event", self.visibility_notify_event) - # search for links in the notes and make them clickable - self.search_links() - - def tag_link(self, start, end, url): - """Apply the tag that marks links to the specified buffer selection""" - tag = self.buffer.create_tag(None, foreground="blue", - underline=pango.UNDERLINE_SINGLE) - tag.set_data("url", url) - self.buffer.apply_tag(tag , start, end) - - def search_links(self): - """Search for http URLs in the buffer and call the tag_link method - for each one to tag them as links""" - # start at the beginning of the buffer - iter = self.buffer.get_iter_at_offset(0) - while 1: - # search for the next URL in the buffer - ret = iter.forward_search("http://", gtk.TEXT_SEARCH_VISIBLE_ONLY, - None) - # if we reach the end break the loop - if not ret: - break - # get the position of the protocol prefix - (match_start, match_end) = ret - match_tmp = match_end.copy() - while 1: - # extend the selection to the complete URL - if match_tmp.forward_char(): - text = match_end.get_text(match_tmp) - if text in (" ", ")", "]", "\n", "\t"): - break - else: - break - match_end = match_tmp.copy() - # call the tagging method for the complete URL - url = match_start.get_text(match_end) - self.tag_link(match_start, match_end, url) - # set the starting point for the next search - iter = match_end - - def event_after(self, text_view, event): - """callback for mouse click events""" - # we only react on left mouse clicks - if event.type != gtk.gdk.BUTTON_RELEASE: - return False - if event.button != 1: - return False - - # try to get a selection - try: - (start, end) = self.buffer.get_selection_bounds() - except ValueError: - pass - else: - if start.get_offset() != end.get_offset(): - return False - - # get the iter at the mouse position - (x, y) = self.window_to_buffer_coords(gtk.TEXT_WINDOW_WIDGET, - int(event.x), int(event.y)) - iter = self.get_iter_at_location(x, y) - - # call open_url if an URL is assigned to the iter - tags = iter.get_tags() - for tag in tags: - url = tag.get_data("url") - if url != "": - self.open_url(url) - break - - def open_url(self, url): - """Open the specified URL in a browser""" - # Find an appropiate browser - if os.path.exists('usr/bin/gnome-open'): - command = ['gnome-open', url] - else: - command = ['x-www-browser', url] - - # Avoid to run the browser as user root - if os.getuid() == 0 and os.environ.has_key('SUDO_USER'): - command = ['sudo', '-u', os.environ['SUDO_USER']] + command - - subprocess.Popen(command) - - def motion_notify_event(self, text_view, event): - """callback for the mouse movement event, that calls the - check_hovering method with the mouse postition coordiantes""" - x, y = text_view.window_to_buffer_coords(gtk.TEXT_WINDOW_WIDGET, - int(event.x), int(event.y)) - self.check_hovering(x, y) - self.window.get_pointer() - return False - - def visibility_notify_event(self, text_view, event): - """callback if the widgets gets visible (e.g. moves to the foreground) - that calls the check_hovering method with the mouse position - coordinates""" - (wx, wy, mod) = text_view.window.get_pointer() - (bx, by) = text_view.window_to_buffer_coords(gtk.TEXT_WINDOW_WIDGET, wx, - wy) - self.check_hovering(bx, by) - return False - - def check_hovering(self, x, y): - """Check if the mouse is above a tagged link and if yes show - a hand cursor""" - _hovering = False - # get the iter at the mouse position - iter = self.get_iter_at_location(x, y) - - # set _hovering if the iter has the tag "url" - tags = iter.get_tags() - for tag in tags: - url = tag.get_data("url") - if url != "": - _hovering = True - break - - # change the global hovering state - if _hovering != self.hovering or self.first == True: - self.first = False - self.hovering = _hovering - # Set the appropriate cursur icon - if self.hovering: - self.get_window(gtk.TEXT_WINDOW_TEXT).\ - set_cursor(gtk.gdk.Cursor(gtk.gdk.HAND2)) - else: - self.get_window(gtk.TEXT_WINDOW_TEXT).\ - set_cursor(gtk.gdk.Cursor(gtk.gdk.LEFT_PTR)) diff --git a/UpdateManager/UpdateManager.py b/UpdateManager/UpdateManager.py deleted file mode 100644 index af1a1b8e..00000000 --- a/UpdateManager/UpdateManager.py +++ /dev/null @@ -1,962 +0,0 @@ -# UpdateManager.py -# -# Copyright (c) 2004-2006 Canonical -# 2004 Michiel Sikkes -# 2005 Martin Willemoes Hansen -# -# Author: Michiel Sikkes <michiel@eyesopened.nl> -# Michael Vogt <mvo@debian.org> -# Martin Willemoes Hansen <mwh@sysrq.dk> -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 -# USA - -import pygtk -pygtk.require('2.0') -import gtk -import gtk.gdk -import gtk.glade -try: - import gconf -except: - import fakegconf as gconf -import gobject -import warnings -warnings.filterwarnings("ignore", "apt API not stable yet", FutureWarning) -import apt -import apt_pkg - -import gettext -import copy -import string -import sys -import os -import os.path -import re -import locale -import tempfile -import pango -import subprocess -import pwd -import urllib2 -import time -import thread -import xml.sax.saxutils -from Common.HelpViewer import HelpViewer - -import dbus -import dbus.service -import dbus.glib - -from gettext import gettext as _ - -from Common.utils import * -from Common.SimpleGladeApp import SimpleGladeApp -from DistUpgradeFetcher import DistUpgradeFetcher -import GtkProgress - -from MetaRelease import Dist, MetaRelease - -#import pdb - -# FIXME: -# - kill "all_changes" and move the changes into the "Update" class - -# list constants -(LIST_CONTENTS, LIST_NAME, LIST_PKG) = range(3) - -# actions for "invoke_manager" -(INSTALL, UPDATE) = range(2) - -SYNAPTIC_PINFILE = "/var/lib/synaptic/preferences" - -CHANGELOGS_URI="http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" - - -class MyCache(apt.Cache): - def __init__(self, progress): - apt.Cache.__init__(self, progress) - self._initDepCache() - assert self._depcache.BrokenCount == 0 and self._depcache.DelCount == 0 - self.all_changes = {} - def _initDepCache(self): - #apt_pkg.Config.Set("Debug::pkgPolicy","1") - #self.depcache = apt_pkg.GetDepCache(self.cache) - #self._depcache = apt_pkg.GetDepCache(self._cache) - self._depcache.ReadPinFile() - if os.path.exists(SYNAPTIC_PINFILE): - self._depcache.ReadPinFile(SYNAPTIC_PINFILE) - self._depcache.Init() - def clear(self): - self._initDepCache() - @property - def requiredDownload(self): - """ get the size of the packages that are required to download """ - pm = apt_pkg.GetPackageManager(self._depcache) - fetcher = apt_pkg.GetAcquire() - pm.GetArchives(fetcher, self._list, self._records) - return fetcher.FetchNeeded - @property - def installCount(self): - return self._depcache.InstCount - def saveDistUpgrade(self): - """ this functions mimics a upgrade but will never remove anything """ - self._depcache.Upgrade(True) - wouldDelete = self._depcache.DelCount - if self._depcache.DelCount > 0: - self.clear() - assert self._depcache.BrokenCount == 0 and self._depcache.DelCount == 0 - self._depcache.Upgrade() - return wouldDelete - - def get_changelog(self, name, lock): - # don't touch the gui in this function, it needs to be thread-safe - pkg = self[name] - - # get the src package name - srcpkg = pkg.sourcePackageName - - # assume "main" section - src_section = "main" - # use the section of the candidate as a starting point - section = pkg._depcache.GetCandidateVer(pkg._pkg).Section - - # get the source version, start with the binaries version - binver = pkg.candidateVersion - srcver = pkg.candidateVersion - #print "bin: %s" % binver - try: - # try to get the source version of the pkg, this differs - # for some (e.g. libnspr4 on ubuntu) - # this feature only works if the correct deb-src are in the - # sources.list - # otherwise we fall back to the binary version number - srcrecords = apt_pkg.GetPkgSrcRecords() - srcrec = srcrecords.Lookup(srcpkg) - if srcrec: - srcver = srcrecords.Version - if apt_pkg.VersionCompare(binver, srcver) > 0: - srcver = binver - #print "srcver: %s" % srcver - section = srcrecords.Section - #print "srcsect: %s" % section - else: - # fail into the error handler - raise SystemError - except SystemError, e: - srcver = binver - - l = section.split("/") - if len(l) > 1: - src_section = l[0] - - # lib is handled special - prefix = srcpkg[0] - if srcpkg.startswith("lib"): - prefix = "lib" + srcpkg[3] - - # stip epoch - l = string.split(srcver,":") - if len(l) > 1: - srcver = "".join(l[1:]) - - try: - uri = CHANGELOGS_URI % (src_section,prefix,srcpkg,srcpkg, srcver) - # print "Trying: %s " % uri - changelog = urllib2.urlopen(uri) - #print changelog.read() - # do only get the lines that are new - alllines = "" - regexp = "^%s \((.*)\)(.*)$" % (re.escape(srcpkg)) - - i=0 - while True: - line = changelog.readline() - if line == "": - break - match = re.match(regexp,line) - if match: - # FIXME: the installed version can have a epoch, but th - # changelog does not have one, we do a dumb - # approach here and just strip it away, but I'm - # sure that this can lead to problems - installed = pkg.installedVersion - if installed and ":" in installed: - installed = installed.split(":",1)[1] - if installed and \ - apt_pkg.VersionCompare(match.group(1),installed)<=0: - break - # EOF (shouldn't really happen) - alllines = alllines + line - - # Print an error if we failed to extract a changelog - if len(alllines) == 0: - alllines = _("The list of changes is not available") - # only write if we where not canceld - if lock.locked(): - self.all_changes[name] = [alllines, srcpkg] - except urllib2.HTTPError: - if lock.locked(): - self.all_changes[name] = [_("The list of changes is not " - "available yet.\nPlease try again " - "later."), srcpkg] - except IOError: - if lock.locked(): - self.all_changes[name] = [_("Failed to download the list " - "of changes. \nPlease " - "check your Internet " - "connection."), srcpkg] - if lock.locked(): - lock.release() - -class UpdateList: - class UpdateOrigin: - def __init__(self, desc, importance): - self.packages = [] - self.importance = importance - self.description = desc - - def __init__(self): - # a map of packages under their origin - pipe = os.popen("lsb_release -c -s") - dist = pipe.read().strip() - del pipe - - templates = [("%s-security" % dist, "Ubuntu", _("Important security updates") - , 10), - ("%s-updates" % dist, "Ubuntu", _("Recommended updates"), 9), - ("%s-proposed" % dist, "Ubuntu", _("Proposed updates"), 8), - ("%s-backports" % dist, "Ubuntu", _("Backports"), 7), - (dist, "Ubuntu", _("Distribution updates"), 6)] - - self.pkgs = {} - self.matcher = {} - self.num_updates = 0 - for (origin, archive, desc, importance) in templates: - self.matcher[(origin, archive)] = self.UpdateOrigin(desc, importance) - self.unknown_origin = self.UpdateOrigin(_("Other updates"), -1) - - def update(self, cache): - self.held_back = [] - - # do the upgrade - self.distUpgradeWouldDelete = cache.saveDistUpgrade() - - # sort by origin - for pkg in cache: - if pkg.isUpgradable: - if pkg.candidateOrigin == None: - # can happen for e.g. loged packages - # FIXME: do something more sensible here (but what?) - print "WARNING: upgradable but no canidateOrigin?!?: ", pkg.name - continue - # TRANSLATORS: updates from an 'unknown' origin - originstr = _("Other updates") - for aorigin in pkg.candidateOrigin: - archive = aorigin.archive - origin = aorigin.origin - if self.matcher.has_key((archive,origin)) and aorigin.trusted: - origin_node = self.matcher[(archive,origin)] - else: - origin_node = self.unknown_origin - if not self.pkgs.has_key(origin_node): - self.pkgs[origin_node] = [] - self.pkgs[origin_node].append(pkg) - self.num_updates = self.num_updates + 1 - if pkg.isUpgradable and not (pkg.markedUpgrade or pkg.markedInstall): - self.held_back.append(pkg.name) - for l in self.pkgs.keys(): - self.pkgs[l].sort(lambda x,y: cmp(x.name,y.name)) - self.keepcount = cache._depcache.KeepCount - - -class UpdateManagerDbusControler(dbus.service.Object): - """ this is a helper to provide the UpdateManagerIFace """ - def __init__(self, parent, bus_name, - object_path='/org/freedesktop/UpdateManagerObject'): - dbus.service.Object.__init__(self, bus_name, object_path) - self.parent = parent - - @dbus.service.method('org.freedesktop.UpdateManagerIFace') - def bringToFront(self): - self.parent.window_main.present() - return True - -class UpdateManager(SimpleGladeApp): - - def __init__(self, datadir): - self.setupDbus() - gtk.window_set_default_icon_name("update-manager") - - self.datadir = datadir - SimpleGladeApp.__init__(self, datadir+"glade/UpdateManager.glade", - None, domain="update-manager") - - self.image_logo.set_from_icon_name("update-manager", gtk.ICON_SIZE_DIALOG) - self.window_main.set_sensitive(False) - self.window_main.grab_focus() - self.button_close.grab_focus() - - self.dl_size = 0 - - # create text view - changes_buffer = self.textview_changes.get_buffer() - changes_buffer.create_tag("versiontag", weight=pango.WEIGHT_BOLD) - - # expander - self.expander_details.connect("notify::expanded", self.activate_details) - - # useful exit stuff - self.window_main.connect("delete_event", self.close) - self.button_close.connect("clicked", lambda w: self.exit()) - - # the treeview (move into it's own code!) - self.store = gtk.ListStore(str, str, gobject.TYPE_PYOBJECT) - self.treeview_update.set_model(self.store) - self.treeview_update.set_headers_clickable(True); - - tr = gtk.CellRendererText() - tr.set_property("xpad", 6) - tr.set_property("ypad", 6) - cr = gtk.CellRendererToggle() - cr.set_property("activatable", True) - cr.set_property("xpad", 6) - cr.connect("toggled", self.toggled) - - column_install = gtk.TreeViewColumn("Install", cr) - column_install.set_cell_data_func (cr, self.install_column_view_func) - column = gtk.TreeViewColumn("Name", tr, markup=LIST_CONTENTS) - column.set_cell_data_func (tr, self.package_column_view_func) - column.set_resizable(True) - major,minor,patch = gtk.pygtk_version - if (major >= 2) and (minor >= 5): - column_install.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED) - column_install.set_fixed_width(30) - column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED) - column.set_fixed_width(100) - #self.treeview_update.set_fixed_height_mode(True) - - self.treeview_update.append_column(column_install) - column_install.set_visible(True) - self.treeview_update.append_column(column) - self.treeview_update.set_search_column(LIST_NAME) - self.treeview_update.connect("button-press-event", self.show_context_menu) - - - - # setup the help viewer and disable the help button if there - # is no viewer available - self.help_viewer = HelpViewer("update-manager") - if self.help_viewer.check() == False: - self.button_help.set_sensitive(False) - - self.gconfclient = gconf.client_get_default() - self.init_proxy() - - # restore state - self.restore_state() - self.window_main.show() - - def init_proxy(self): - # proxy settings, first check for http_proxy environment (always wins), - # then look into synaptics conffile, then into gconf - if os.getenv("http_proxy"): - return - SYNAPTIC_CONF_FILE = "%s/.synaptic/synaptic.conf" % pwd.getpwuid(0)[5] - proxy = None - if os.path.exists(SYNAPTIC_CONF_FILE): - cnf = apt_pkg.newConfiguration() - apt_pkg.ReadConfigFile(cnf, SYNAPTIC_CONF_FILE) - use_proxy = cnf.FindB("Synaptic::useProxy", False) - if use_proxy: - proxy_host = cnf.Find("Synaptic::httpProxy") - proxy_port = str(cnf.FindI("Synaptic::httpProxyPort")) - if proxy_host and proxy_port: - # FIXME: set the proxy for libapt here as well (e.g. for the - # DistUpgradeFetcher - proxy = "http://%s:%s/" % (proxy_host, proxy_port) - elif self.gconfclient.get_bool("/system/http_proxy/use_http_proxy"): - host = self.gconfclient.get_string("/system/http_proxy/host") - port = self.gconfclient.get_int("/system/http_proxy/port") - use_auth = self.gconfclient.get_bool("/system/http_proxy/use_authentication") - if use_auth: - auth_user = self.gconfclient.get_string("/system/http_proxy/authentication_user") - auth_pw = self.gconfclient.get_string("/system/http_proxy/authentication_password") - proxy = "http://%s:%s@%s:%s/" % (auth_user,auth_pass,host, port) - else: - proxy = "http://%s:%s/" % (host, port) - if proxy: - proxy_support = urllib2.ProxyHandler({"http":proxy}) - opener = urllib2.build_opener(proxy_support) - urllib2.install_opener(opener) - os.putenv("http_proxy",proxy) - - def header_column_func(self, cell_layout, renderer, model, iter): - pkg = model.get_value(iter, LIST_PKG) - if pkg == None: - renderer.set_property("sensitive", False) - else: - renderer.set_property("sensitive", True) - - def install_column_view_func(self, cell_layout, renderer, model, iter): - self.header_column_func(cell_layout, renderer, model, iter) - pkg = model.get_value(iter, LIST_PKG) - # hide it if we are only a header line - renderer.set_property("visible", pkg != None) - if pkg is None: - return - to_install = pkg.markedInstall or pkg.markedUpgrade - renderer.set_property("active", to_install) - if pkg.name in self.list.held_back: - renderer.set_property("activatable", False) - else: - renderer.set_property("activatable", True) - - def package_column_view_func(self, cell_layout, renderer, model, iter): - self.header_column_func(cell_layout, renderer, model, iter) - - def setupDbus(self): - """ this sets up a dbus listener if none is installed alread """ - # check if there is another g-a-i already and if not setup one - # listening on dbus - try: - bus = dbus.SessionBus() - except: - print "warning: could not initiate dbus" - return - proxy_obj = bus.get_object('org.freedesktop.UpdateManager', - '/org/freedesktop/UpdateManagerObject') - iface = dbus.Interface(proxy_obj, 'org.freedesktop.UpdateManagerIFace') - try: - iface.bringToFront() - #print "send bringToFront" - sys.exit(0) - except dbus.DBusException, e: - print "no listening object (%s) "% e - bus_name = dbus.service.BusName('org.freedesktop.UpdateManager',bus) - self.dbusControler = UpdateManagerDbusControler(self, bus_name) - - - def on_checkbutton_reminder_toggled(self, checkbutton): - self.gconfclient.set_bool("/apps/update-manager/remind_reload", - not checkbutton.get_active()) - - def close(self, widget, data=None): - if self.window_main.get_property("sensitive") is False: - return True - else: - self.exit() - - - def set_changes_buffer(self, changes_buffer, text, name, srcpkg): - changes_buffer.set_text("") - lines = text.split("\n") - if len(lines) == 1: - changes_buffer.set_text(text) - return - - for line in lines: - end_iter = changes_buffer.get_end_iter() - version_match = re.match(r'^%s \((.*)\)(.*)\;.*$' % re.escape(srcpkg), line) - #bullet_match = re.match("^.*[\*-]", line) - author_match = re.match("^.*--.*<.*@.*>.*$", line) - if version_match: - version = version_match.group(1) - upload_archive = version_match.group(2).strip() - version_text = _("Version %s: \n") % version - changes_buffer.insert_with_tags_by_name(end_iter, version_text, "versiontag") - elif (author_match): - pass - else: - changes_buffer.insert(end_iter, line+"\n") - - - def on_treeview_update_cursor_changed(self, widget): - tuple = widget.get_cursor() - path = tuple[0] - # check if we have a path at all - if path == None: - return - model = widget.get_model() - iter = model.get_iter(path) - - # set descr - pkg = model.get_value(iter, LIST_PKG) - if pkg == None or pkg.description == None: - changes_buffer = self.textview_changes.get_buffer() - changes_buffer.set_text("") - desc_buffer = self.textview_descr.get_buffer() - desc_buffer.set_text("") - self.notebook_details.set_sensitive(False) - return - long_desc = pkg.description - self.notebook_details.set_sensitive(True) - # Skip the first line - it's a duplicate of the summary - i = long_desc.find("\n") - long_desc = long_desc[i+1:] - # do some regular expression magic on the description - # Add a newline before each bullet - p = re.compile(r'^(\s|\t)*(\*|0|-)',re.MULTILINE) - long_desc = p.sub('\n*', long_desc) - # replace all newlines by spaces - p = re.compile(r'\n', re.MULTILINE) - long_desc = p.sub(" ", long_desc) - # replace all multiple spaces by newlines - p = re.compile(r'\s\s+', re.MULTILINE) - long_desc = p.sub("\n", long_desc) - - desc_buffer = self.textview_descr.get_buffer() - desc_buffer.set_text(long_desc) - - # now do the changelog - name = model.get_value(iter, LIST_NAME) - if name == None: - return - - changes_buffer = self.textview_changes.get_buffer() - - # check if we have the changes already - if self.cache.all_changes.has_key(name): - changes = self.cache.all_changes[name] - self.set_changes_buffer(changes_buffer, changes[0], name, changes[1]) - else: - if self.expander_details.get_expanded(): - lock = thread.allocate_lock() - lock.acquire() - t=thread.start_new_thread(self.cache.get_changelog,(name,lock)) - changes_buffer.set_text("%s\n" % _("Downloading list of changes...")) - iter = changes_buffer.get_iter_at_line(1) - anchor = changes_buffer.create_child_anchor(iter) - button = gtk.Button(stock="gtk-cancel") - self.textview_changes.add_child_at_anchor(button, anchor) - button.show() - id = button.connect("clicked", - lambda w,lock: lock.release(), lock) - # wait for the dl-thread - while lock.locked(): - time.sleep(0.05) - while gtk.events_pending(): - gtk.main_iteration() - # download finished (or canceld, or time-out) - button.hide() - button.disconnect(id); - - if self.cache.all_changes.has_key(name): - changes = self.cache.all_changes[name] - self.set_changes_buffer(changes_buffer, changes[0], name, changes[1]) - - def show_context_menu(self, widget, event): - """ - Show a context menu if a right click was performed on an update entry - """ - if event.type == gtk.gdk.BUTTON_PRESS and event.button == 3: - menu = gtk.Menu() - item_select_none = gtk.MenuItem(_("_Uncheck All")) - item_select_none.connect("activate", self.select_none_updgrades) - menu.add(item_select_none) - num_updates = self.cache.installCount - if num_updates == 0: - item_select_none.set_property("sensitive", False) - item_select_all = gtk.MenuItem(_("_Check All")) - item_select_all.connect("activate", self.select_all_updgrades) - menu.add(item_select_all) - menu.popup(None, None, None, 0, event.time) - menu.show_all() - return True - - def select_all_updgrades(self, widget): - """ - Select all updates - """ - self.setBusy(True) - self.cache.saveDistUpgrade() - self.treeview_update.queue_draw() - self.setBusy(False) - - def select_none_updgrades(self, widget): - """ - Select none updates - """ - self.setBusy(True) - self.cache.clear() - self.treeview_update.queue_draw() - self.setBusy(False) - - def setBusy(self, flag): - """ Show a watch cursor if the app is busy for more than 0.3 sec. - Furthermore provide a loop to handle user interface events """ - if self.window_main.window is None: - return - if flag == True: - self.window_main.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH)) - else: - self.window_main.window.set_cursor(None) - while gtk.events_pending(): - gtk.main_iteration() - - def refresh_updates_count(self): - self.button_install.set_sensitive(self.cache.installCount) - self.dl_size = self.cache.requiredDownload - # TRANSLATORS: b stands for Bytes - self.label_downsize.set_markup(_("Download size: %s") % \ - humanize_size(self.dl_size)) - - def update_count(self): - """activate or disable widgets and show dialog texts correspoding to - the number of available updates""" - self.refresh_updates_count() - num_updates = self.cache.installCount - if num_updates == 0: - text_header= "<big><b>%s</b></big>" % _("Your system is up-to-date") - text_download = "" - self.notebook_details.set_sensitive(False) - self.treeview_update.set_sensitive(False) - self.button_install.set_sensitive(False) - self.label_downsize.set_text="" - self.button_close.grab_default() - self.textview_changes.get_buffer().set_text("") - self.textview_descr.get_buffer().set_text("") - else: - text_header = "<big><b>%s</b></big>" % \ - (gettext.ngettext("You can install %s update", - "You can install %s updates", - num_updates) % \ - num_updates) - text_download = _("Download size: %s") % humanize_size(self.dl_size) - self.notebook_details.set_sensitive(True) - self.treeview_update.set_sensitive(True) - self.button_install.grab_default() - self.treeview_update.set_cursor(1) - self.label_header.set_markup(text_header) - self.label_downsize.set_markup(text_download) - - def activate_details(self, expander, data): - expanded = self.expander_details.get_expanded() - self.vbox_updates.set_child_packing(self.expander_details, - expanded, - True, - 0, - True) - self.gconfclient.set_bool("/apps/update-manager/show_details",expanded) - if expanded: - self.on_treeview_update_cursor_changed(self.treeview_update) - - def run_synaptic(self, id, action, lock): - try: - apt_pkg.PkgSystemUnLock() - except SystemError: - pass - cmd = ["gksu", "--desktop", "/usr/share/applications/update-manager.desktop", - "--", "/usr/sbin/synaptic", "--hide-main-window", - "--non-interactive", "--parent-window-id", "%s" % (id) ] - if action == INSTALL: - cmd.append("--progress-str") - cmd.append("%s" % _("Please wait, this can take some time.")) - cmd.append("--finish-str") - cmd.append("%s" % _("Update is complete")) - f = tempfile.NamedTemporaryFile() - for pkg in self.cache: - if pkg.markedInstall or pkg.markedUpgrade: - f.write("%s\tinstall\n" % pkg.name) - cmd.append("--set-selections-file") - cmd.append("%s" % f.name) - f.flush() - subprocess.call(cmd) - f.close() - elif action == UPDATE: - cmd.append("--update-at-startup") - subprocess.call(cmd) - else: - print "run_synaptic() called with unknown action" - sys.exit(1) - lock.release() - - def on_button_reload_clicked(self, widget): - #print "on_button_reload_clicked" - self.invoke_manager(UPDATE) - - def on_button_help_clicked(self, widget): - self.help_viewer.run() - - def on_button_install_clicked(self, widget): - #print "on_button_install_clicked" - self.invoke_manager(INSTALL) - - def invoke_manager(self, action): - # check first if no other package manager is runing - - # don't display apt-listchanges, we already showed the changelog - os.environ["APT_LISTCHANGES_FRONTEND"]="none" - - # Do not suspend during the update process - (dev, cookie) = self.inhibit_sleep() - - # set window to insensitive - self.window_main.set_sensitive(False) - self.window_main.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH)) - lock = thread.allocate_lock() - lock.acquire() - t = thread.start_new_thread(self.run_synaptic, - (self.window_main.window.xid,action,lock)) - while lock.locked(): - while gtk.events_pending(): - gtk.main_iteration() - time.sleep(0.05) - while gtk.events_pending(): - gtk.main_iteration() - self.label_cache_progress_title.set_label("<b><big>%s</big></b>" % _("Checking for updates")) - self.fillstore() - - # Allow suspend after synaptic is finished - if cookie != False: - self.allow_sleep(dev, cookie) - self.window_main.set_sensitive(True) - self.window_main.window.set_cursor(None) - - - def inhibit_sleep(self): - """Send a dbus signal to gnome-power-manager to not suspend - the system""" - try: - bus = dbus.Bus(dbus.Bus.TYPE_SESSION) - devobj = bus.get_object('org.gnome.PowerManager', - '/org/gnome/PowerManager') - dev = dbus.Interface(devobj, "org.gnome.PowerManager") - cookie = dev.Inhibit('UpdateManager', 'Updating system') - return (dev, cookie) - except Exception, e: - print "could not send the dbus Inhibit signal: %s" % e - return (False, False) - - def allow_sleep(self, dev, cookie): - """Send a dbus signal to gnome-power-manager to allow a suspending - the system""" - dev.UnInhibit(cookie) - - def toggled(self, renderer, path): - """ a toggle button in the listview was toggled """ - iter = self.store.get_iter(path) - pkg = self.store.get_value(iter, LIST_PKG) - # make sure that we don't allow to toggle deactivated updates - # this is needed for the call by the row activation callback - if pkg.name in self.list.held_back: - return False - self.setBusy(True) - # update the cache - if pkg.markedInstall or pkg.markedUpgrade: - pkg.markKeep() - if self.cache._depcache.BrokenCount: - Fix = apt_pkg.GetPkgProblemResolver(self.cache._depcache) - Fix.ResolveByKeep() - else: - pkg.markInstall() - self.treeview_update.queue_draw() - self.refresh_updates_count() - self.setBusy(False) - - def on_treeview_update_row_activated(self, treeview, path, column, *args): - """ - If an update row was activated (by pressing space), toggle the - install check box - """ - self.toggled(None, path) - - def exit(self): - """ exit the application, save the state """ - self.save_state() - gtk.main_quit() - sys.exit(0) - - def save_state(self): - """ save the state (window-size for now) """ - (x,y) = self.window_main.get_size() - self.gconfclient.set_pair("/apps/update-manager/window_size", - gconf.VALUE_INT, gconf.VALUE_INT, x, y) - - def restore_state(self): - """ restore the state (window-size for now) """ - expanded = self.gconfclient.get_bool("/apps/update-manager/show_details") - self.expander_details.set_expanded(expanded) - self.vbox_updates.set_child_packing(self.expander_details, - expanded, - True, - 0, - True) - (x,y) = self.gconfclient.get_pair("/apps/update-manager/window_size", - gconf.VALUE_INT, gconf.VALUE_INT) - if x > 0 and y > 0: - self.window_main.resize(x,y) - - def fillstore(self): - # use the watch cursor - self.setBusy(True) - - # clean most objects - self.dl_size = 0 - self.initCache() - self.store.clear() - self.list = UpdateList() - - # fill them again - self.list.update(self.cache) - if self.list.num_updates > 0: - origin_list = self.list.pkgs.keys() - origin_list.sort(lambda x,y: cmp(x.importance,y.importance)) - origin_list.reverse() - for origin in origin_list: - self.store.append(['<b><big>%s</big></b>' % origin.description, - origin.description, None]) - for pkg in self.list.pkgs[origin]: - name = xml.sax.saxutils.escape(pkg.name) - summary = xml.sax.saxutils.escape(pkg.summary) - contents = "<b>%s</b>\n<small>%s</small>" % (name, summary) - if pkg.installedVersion != None: - version = _("From version %(old_version)s to %(new_version)s") %\ - {"old_version" : pkg.installedVersion, - "new_version" : pkg.candidateVersion} - else: - version = _("Version %s") % pkg.candidateVersion - #TRANSLATORS: the b stands for Bytes - size = _("(Size: %s)") % humanize_size(pkg.packageSize) - contents = "%s\n<small>%s %s</small>" % (contents, version, size) - - self.store.append([contents, pkg.name, pkg]) - self.update_count() - self.setBusy(False) - self.check_all_updates_installable() - return False - - def dist_no_longer_supported(self, meta_release): - msg = "<big><b>%s</b></big>\n\n%s" % \ - (_("Your distribution is not supported anymore"), - _("You will not get any further security fixes or critical " - "updates. " - "Upgrade to a later version of Ubuntu Linux. See " - "http://www.ubuntu.com for more information on " - "upgrading.")) - dialog = gtk.MessageDialog(self.window_main, 0, gtk.MESSAGE_WARNING, - gtk.BUTTONS_CLOSE,"") - dialog.set_title("") - dialog.set_markup(msg) - dialog.run() - dialog.destroy() - - def on_button_dist_upgrade_clicked(self, button): - #print "on_button_dist_upgrade_clicked" - fetcher = DistUpgradeFetcher(self, self.new_dist) - fetcher.run() - - def new_dist_available(self, meta_release, upgradable_to): - self.frame_new_release.show() - self.label_new_release.set_markup(_("<b>New distribution release '%s' is available</b>") % upgradable_to.version) - self.new_dist = upgradable_to - - - # fixme: we should probably abstract away all the stuff from libapt - def initCache(self): - # get the lock - try: - apt_pkg.PkgSystemLock() - except SystemError, e: - pass - #d = gtk.MessageDialog(parent=self.window_main, - # flags=gtk.DIALOG_MODAL, - # type=gtk.MESSAGE_ERROR, - # buttons=gtk.BUTTONS_CLOSE) - #d.set_markup("<big><b>%s</b></big>\n\n%s" % ( - # _("Only one software management tool is allowed to " - # "run at the same time"), - # _("Please close the other application e.g. 'aptitude' " - # "or 'Synaptic' first."))) - #print "error from apt: '%s'" % e - #d.set_title("") - #res = d.run() - #d.destroy() - #sys.exit() - - try: - progress = GtkProgress.GtkOpProgress(self.dialog_cacheprogress, - self.progressbar_cache, - self.label_cache, - self.window_main) - if hasattr(self, "cache"): - self.cache.open(progress) - self.cache._initDepCache() - else: - self.cache = MyCache(progress) - except AssertionError: - # we assert a clean cache - msg=("<big><b>%s</b></big>\n\n%s"% \ - (_("Software index is broken"), - _("It is impossible to install or remove any software. " - "Please use the package manager \"Synaptic\" or run " - "\"sudo apt-get install -f\" in a terminal to fix " - "this issue at first."))) - dialog = gtk.MessageDialog(self.window_main, - 0, gtk.MESSAGE_ERROR, - gtk.BUTTONS_CLOSE,"") - dialog.set_markup(msg) - dialog.vbox.set_spacing(6) - dialog.run() - dialog.destroy() - sys.exit(1) - else: - progress.hide() - - def check_auto_update(self): - # Check if automatic update is enabled. If not show a dialog to inform - # the user about the need of manual "reloads" - remind = self.gconfclient.get_bool("/apps/update-manager/remind_reload") - if remind == False: - return - - update_days = apt_pkg.Config.FindI("APT::Periodic::Update-Package-Lists") - if update_days < 1: - self.dialog_manual_update.set_transient_for(self.window_main) - res = self.dialog_manual_update.run() - self.dialog_manual_update.hide() - if res == gtk.RESPONSE_YES: - self.on_button_reload_clicked(None) - - def check_all_updates_installable(self): - """ Check if all available updates can be installed and suggest - to run a distribution upgrade if not """ - if self.list.distUpgradeWouldDelete > 0: - self.dialog_dist_upgrade.set_transient_for(self.window_main) - res = self.dialog_dist_upgrade.run() - self.dialog_dist_upgrade.hide() - if res == gtk.RESPONSE_YES: - os.execl("/usr/bin/gksu", - "/usr/bin/gksu", "--desktop", - "/usr/share/applications/update-manager.desktop", - "--", "/usr/bin/update-manager", "--dist-upgrade") - - def main(self, options): - gconfclient = gconf.client_get_default() - self.meta = MetaRelease(options.devel_release) - self.meta.connect("dist_no_longer_supported",self.dist_no_longer_supported) - - # check if we are interessted in dist-upgrade information - # (we are not by default on dapper) - if options.check_dist_upgrades or \ - gconfclient.get_bool("/apps/update-manager/check_dist_upgrades"): - self.meta.connect("new_dist_available",self.new_dist_available) - - while gtk.events_pending(): - gtk.main_iteration() - - self.fillstore() - self.check_auto_update() - gtk.main() diff --git a/UpdateManager/__init__.py b/UpdateManager/__init__.py deleted file mode 100644 index 8b137891..00000000 --- a/UpdateManager/__init__.py +++ /dev/null @@ -1 +0,0 @@ - diff --git a/UpdateManager/fakegconf.py b/UpdateManager/fakegconf.py deleted file mode 100644 index 7e387b56..00000000 --- a/UpdateManager/fakegconf.py +++ /dev/null @@ -1,69 +0,0 @@ -# Copyright (c) 2006 Jani Monoses <jani@ubuntu.com> - -# This is a class which handles settings when the gconf library -# is unavailable such as in a non-Gnome environment -# The configuration is stored in python hash format which is sourced -# at program start and dumped at exit - -import string -import atexit - -CONFIG_FILE="/root/.update-manager-conf" - -class FakeGconf: - - def __init__(self): - self.config = {} - try: - #execute python file which contains the dictionary called config - exec open (CONFIG_FILE) - self.config = config - except: - pass - - #only get the 'basename' from the gconf key - def keyname(self, key): - return string.rsplit(key, '/', 1)[-1] - - def get_bool(self, key): - key = self.keyname(key) - return self.config.setdefault(self.keyname(key), True) - - def set_bool(self, key,value): - key = self.keyname(key) - self.config[key] = value - - # FIXME assume type is int for now - def get_pair(self, key, ta = None, tb = None): - key = self.keyname(key) - return self.config.setdefault(self.keyname(key), [400, 500]) - - # FIXME assume type is int for now - def set_pair(self, key, ta, tb, a, b): - key = self.keyname(key) - self.config[key] = [a, b] - - #Save current dictionary to config file - def save(self): - file = open(CONFIG_FILE, "w") - data = "config = {" - for i in self.config: - data += "'"+i+"'" + ":" + str(self.config[i])+",\n" - data += "}" - file.write(data) - file.close() - - -VALUE_INT = "" - -fakegconf = FakeGconf() - -def client_get_default(): - return fakegconf - -def fakegconf_atexit(): - fakegconf.save() - -atexit.register(fakegconf_atexit) - - |
