diff options
| author | Michael Vogt <egon@top> | 2005-11-15 14:18:07 +0100 |
|---|---|---|
| committer | Michael Vogt <egon@top> | 2005-11-15 14:18:07 +0100 |
| commit | d632109cd5964f7d4baa408d517e44f801e1be8d (patch) | |
| tree | c1acf5f14bcfa183951c260a52e5560610f3a988 /SoftwareProperties | |
| download | python-apt-d632109cd5964f7d4baa408d517e44f801e1be8d.tar.gz | |
* initial revision (after accidently killing it)
Diffstat (limited to 'SoftwareProperties')
| -rw-r--r-- | SoftwareProperties/Makefile | 359 | ||||
| -rw-r--r-- | SoftwareProperties/Makefile.am | 9 | ||||
| -rw-r--r-- | SoftwareProperties/SoftwareProperties.py.in | 259 | ||||
| -rw-r--r-- | SoftwareProperties/aptsources.py | 437 | ||||
| -rw-r--r-- | SoftwareProperties/dialog_add.py | 111 | ||||
| -rw-r--r-- | SoftwareProperties/dialog_apt_key.py | 163 | ||||
| -rw-r--r-- | SoftwareProperties/dialog_edit.py | 106 | ||||
| -rw-r--r-- | SoftwareProperties/utils.py | 10 |
8 files changed, 1454 insertions, 0 deletions
diff --git a/SoftwareProperties/Makefile b/SoftwareProperties/Makefile new file mode 100644 index 00000000..1ecefbd9 --- /dev/null +++ b/SoftwareProperties/Makefile @@ -0,0 +1,359 @@ +# Makefile.in generated by automake 1.9.6 from Makefile.am. +# SoftwareProperties/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 = SoftwareProperties +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ + $(srcdir)/SoftwareProperties.py.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 = SoftwareProperties.py +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 = SoftwareProperties.py \ + dialog_edit.py \ + dialog_add.py \ + dialog_apt_key.py \ + utils.py \ + aptsources.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 SoftwareProperties/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu SoftwareProperties/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 +SoftwareProperties.py: $(top_builddir)/config.status $(srcdir)/SoftwareProperties.py.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ +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/SoftwareProperties/Makefile.am b/SoftwareProperties/Makefile.am new file mode 100644 index 00000000..e160d621 --- /dev/null +++ b/SoftwareProperties/Makefile.am @@ -0,0 +1,9 @@ +modules_DATA = SoftwareProperties.py \ + dialog_edit.py \ + dialog_add.py \ + dialog_apt_key.py \ + utils.py \ + aptsources.py +modulesdir = $(datadir)/update-manager/python + +EXTRA_DIST = $(modules_DATA) diff --git a/SoftwareProperties/SoftwareProperties.py.in b/SoftwareProperties/SoftwareProperties.py.in new file mode 100644 index 00000000..ce8d6b6f --- /dev/null +++ b/SoftwareProperties/SoftwareProperties.py.in @@ -0,0 +1,259 @@ +#!/usr/bin/env python +# gnome-software-properties.in - edit /etc/apt/sources.list +# +# Copyright (c) 2004 Canonical +# 2004-2005 Michiel Sikkes +# +# Author: Michiel Sikkes <michiel@eyesopened.nl> +# Michael Vogt <mvo@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 sys +import gnome +import gconf +import apt_pkg +import gobject +import shutil +import gettext + +sys.path.append("@prefix/share/update-manager/python") + +from SimpleGladeApp import * +import aptsources +import dialog_add +import dialog_edit +from dialog_apt_key import apt_key +from utils import * + +(LIST_MARKUP, LIST_ENABLED, LIST_ENTRY_OBJ) = range(3) + +CONF_MAP = { + "autoupdate" : "APT::Periodic::Update-Package-Lists", + "autodownload" : "APT::Periodic::Download-Upgradeable-Packages", + "autoclean" : "APT::Periodic::AutocleanInterval", + "max_size" : "APT::Archives::MaxSize", + "max_age" : "APT::Archives::MaxAge" +} + +DATADIR = "@prefix@/share/update-manager" + + +class SoftwareProperties(SimpleGladeApp): + + def __init__(self, gladefile, root, domain, options): + SimpleGladeApp.__init__(self, gladefile, None, domain) + apt_pkg.InitConfig() + + self.modified = False + + _ = gettext.gettext + + self.gnome_program = gnome.init("Software Properties", "0.41") + self.gconfclient = gconf.client_get_default() + + # Get some configuration options + self.show_disabled = self.gconfclient.get_bool("/apps/gnome-software-" \ + "properties/show_disabled") + + self.window_main.hide() + + # If externally called, reparent to external application. + if (options.socket != None): + plug = gtk.Plug(long(options.socket)) + self.vbox1.reparent(plug) + plug.show_all() + else: + self.window_main.show() + + self.init_sourceslist() + self.reload_sourceslist() + + update_days = apt_pkg.Config.FindI(CONF_MAP["autoupdate"]) + + self.spinbutton_update_interval.set_value(update_days) + + if update_days >= 1: + self.checkbutton_auto_update.set_active(True) + else: + self.checkbutton_auto_update.set_active(False) + + self.apt_key = apt_key() + + self.init_keyslist() + self.reload_keyslist() + + def init_sourceslist(self): + self.source_store = gtk.ListStore(str, bool, gobject.TYPE_PYOBJECT) + self.treeview1.set_model(self.source_store) + + tr = gtk.CellRendererText() + + source_col = gtk.TreeViewColumn("Description", tr, markup=LIST_MARKUP) + source_col.set_max_width(500) + self.treeview1.append_column(source_col) + + self.sourceslist = aptsources.SourcesList() + self.matcher = aptsources.SourceEntryMatcher() + + def init_keyslist(self): + self.keys_store = gtk.ListStore(str) + self.treeview2.set_model(self.keys_store) + + tr = gtk.CellRendererText() + + keys_col = gtk.TreeViewColumn("Key", tr, text=0) + self.treeview2.append_column(keys_col) + + def reload_sourceslist(self): + self.source_store.clear() + for source in self.sourceslist.list: + if source.invalid or source.disabled: + continue + (a_type, dists, comps) = self.matcher.match(source) + + contents = "" + if source.comment != "": + contents += "<i>%s</i>\n\n" % (source.comment) + contents += "%s <small>(%s)</small>" % (dists, a_type) + + self.source_store.append([contents, not source.disabled, source]) + + def reload_keyslist(self): + self.keys_store.clear() + for key in self.apt_key.list(): + self.keys_store.append([key]) + + def opt_autoupdate_toggled(self, widget): + if self.checkbutton_auto_update.get_active(): + if self.spinbutton_update_interval.get_value() == 0: + self.spinbutton_update_interval.set_value(1) + value = "1" + else: + value = str(self.spinbutton_update_interval.get_value()) + else: + value = "0" + + apt_pkg.Config.Set(CONF_MAP["autoupdate"], str(value)) + + # FIXME: Write config options, apt_pkg should be able to do this. + self.write_config() + + def write_config(self): + periodic = "/etc/apt/apt.conf.d/10periodic" + + content = [] + + if os.path.isfile(periodic): + content = open(periodic, "r").readlines() + + cnf = apt_pkg.Config.SubTree("APT::Periodic") + + f = open(periodic, "w+") + for line in content: + found = False + for key in cnf.List(): + if line.find("APT::Periodic::%s" % (key)) >= 0: + found = True + break + if not found: + f.write(line) + + for i in cnf.List(): + f.write("APT::Periodic::%s \"%s\";\n" % (i, cnf.FindI(i))) + f.close() + + def save_sourceslist(self): + location = "/etc/apt/sources.list" + shutil.copy(location, location + ".save") + self.sourceslist.save(location) + + def on_add_clicked(self, widget): + dialog = dialog_add.dialog_add(self.window_main, self.sourceslist, DATADIR) + if dialog.run() == gtk.RESPONSE_OK: + self.reload_sourceslist() + + self.modified = True + + def on_edit_clicked(self, widget): + sel = self.treeview1.get_selection() + (model, iter) = sel.get_selected() + source_entry = model.get_value(iter, LIST_ENTRY_OBJ) + + dialog = dialog_edit.dialog_edit(self.window_main, self.sourceslist, + source_entry, DATADIR) + + if dialog.run() == gtk.RESPONSE_OK: + self.reload_sourceslist() + + self.modified = True + + def on_remove_clicked(self, widget): + sel = self.treeview1.get_selection() + (model, iter) = sel.get_selected() + + if iter: + source = model.get_value(iter, LIST_ENTRY_OBJ) + self.sourceslist.remove(source) + self.reload_sourceslist() + + self.modified = True + + def add_key_clicked(self, widget): + _ = gettext.gettext + chooser = gtk.FileChooserDialog(title=_("Choose a key-file"), + parent=self.window_main, + buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_REJECT, + gtk.STOCK_OK,gtk.RESPONSE_ACCEPT)) + res = chooser.run() + chooser.hide() + if res == gtk.RESPONSE_ACCEPT: + if not self.apt_key.add(chooser.get_filename()): + error(self.window_main, + _("Error importing selected file"), + _("The selected file may not be a GPG key file " \ + "or it might be corrupt.")) + self.reload_keyslist() + + def remove_key_clicked(self, widget): + selection = self.treeview2.get_selection() + (model,a_iter) = selection.get_selected() + if a_iter == None: + return + key = model.get_value(a_iter,0) + if not self.apt_key.rm(key[:8]): + error(self.main, + _("Error removing the key"), + _("The key you selected could not be removed. " + "Please report this as a bug.")) + self.reload_keyslist() + + def on_restore_clicked(self, widget): + self.apt_key.update() + self.reload_keyslist() + + def on_delete_event(self, widget, args): + self.save_sourceslist() + self.quit() + + def on_close_button(self, widget): + self.save_sourceslist() + self.quit() + + def on_help_button(self, widget): + gnome.help_display_desktop(self.gnome_program, + "update-manager", "update-manager", + "setting-preferences") diff --git a/SoftwareProperties/aptsources.py b/SoftwareProperties/aptsources.py new file mode 100644 index 00000000..f86ade98 --- /dev/null +++ b/SoftwareProperties/aptsources.py @@ -0,0 +1,437 @@ +# aptsource.py.in - parse sources.list +# +# Copyright (c) 2004 Canonical +# 2004 Michiel Sikkes +# +# Author: Michiel Sikkes <michiel@eyesopened.nl> +# Michael Vogt <mvo@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 string +import gettext +import re +import apt_pkg +import glob + +from DistInfo import DistInfo + +# actual source.list entries +class SourceEntry: + + def __init__(self, line,file): + self.invalid = False + self.disabled = False + self.type = "" + self.uri = "" + self.dist = "" + self.comps = [] + self.comment = "" + self.line = line + self.file = file + self.parse(line) + + # works mostely like split but takes [] into account + def mysplit(self, line): + 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 + + + # parse a given source line and split it into the fields we need + def parse(self,line): + 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) + # Type, deb or deb-src + self.type = string.strip(pieces[0]) + # URI + self.uri = string.strip(pieces[1]) + # 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 = [] + + #print self.__dict__ + + + # set enabled/disabled + def set_enabled(self, new_value): + 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): + return self.line + + +def uniq(s): + """ simple (and not efficient) way to return uniq list """ + u = [] + for x in s: + if x not in u: + u.append(x) + return u + + +# the SourceList file as a class +class SourcesList: + def __init__(self): + self.list = [] # of Type SourceEntries + # 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) + + def is_mirror(self, add_uri, orig_uri): + """check if the given add_url is idential or a mirror of orig_uri + e.g. add_uri = archive.ubuntu.com + orig_uri = de.archive.ubuntu.com + -> True + """ + # remove traling spaces and "/" + add_uri = add_uri.rstrip("/ ") + orig_uri = orig_uri.rstrip("/ ") + # uri is identical + if add_uri == orig_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: + add_srv = add_uri.split("//")[1] + orig_srv = orig_uri.split("//")[1] + #print "%s == %s " % (add_srv, orig_srv) + except IndexError: # ok, somethings wrong here + #print "IndexError" + return False + if add_srv == orig_srv[3:]: + #print "Mirror" + return True + return False + + def add(self, type, uri, dist, comps, comment="", pos=-1): + # if there is a repo with the same (type, uri, dist) just add the + # components + for i in self.list: + if i.type == type and self.is_mirror(uri,i.uri) and i.dist == dist: + comps = uniq(i.comps + comps) + # set to the old position and preserve comment + comment = i.comment + pos = self.list.index(i) + self.list.remove(i) + 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" + self.list.insert(pos, SourceEntry(line)) + + def remove(self, source_entry): + self.list.remove(source_entry) + + def load(self,file): + f = open(file, "r") + lines = f.readlines() + for line in lines: + source = SourceEntry(line,file) + self.list.append(source) + f.close() + + def save(self,file): + 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() + + +# templates for the add dialog +class SourceEntryTemplate(SourceEntry): + def __init__(self,a_type,uri,dist,description,comps): + self.comps = [] + self.comps_descriptions = [] + self.type = a_type + self.uri = uri + self.dist = dist + self.description = description + self.comps = comps + +class SourceCompTemplate: + def __init__(self, name, description, on_by_default): + self.name = name + self.description = description + self.on_by_default = on_by_default + +class SourceEntryTemplates: + def __init__(self): + _ = gettext.gettext + self.templates = [] + + dinfo = DistInfo () + + for suite in dinfo.suites: + comps = [] + for comp in suite.components: + comps.append(SourceCompTemplate(comp.name, _(comp.description), + comp.enabled)) + self.templates.append (SourceEntryTemplate(suite.repository_type, + suite.base_uri, + suite.name, + suite.description, + comps)) + +# 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): + _ = gettext.gettext + self.type_list = [] + self.type_list.append(self.MatchType("^deb$",_("Binary"))) + self.type_list.append(self.MatchType("^deb-src$",_("Source"))) + + self.dist_list = [] + + ubuntu_comps = ["^main$","^restricted$","^universe$","^multiverse$"] + ubuntu_comps_descr = [_("Officially supported"), + _("Restricted copyright"), + _("Community maintained (Universe)"), + _("Non-free (Multiverse)")] + # CDs + self.dist_list.append(self.MatchDist("cdrom:\[Ubuntu.*5.10", + ".*", + _("CD disk with Ubuntu 5.10 \"Breezy Badger\""), + ubuntu_comps, ubuntu_comps_descr)) + self.dist_list.append(self.MatchDist("cdrom:\[Ubuntu.*5.04", + ".*", + _("CD disk with Ubuntu 5.04 \"Hoary Hedgehog\""), + ubuntu_comps, ubuntu_comps_descr)) + self.dist_list.append(self.MatchDist("cdrom:\[Ubuntu.*4.10", + ".*", + _("CD disk with Ubuntu 4.10 \"Warty Warthog\""), + ubuntu_comps, ubuntu_comps_descr)) + # URIs + # Warty + self.dist_list.append(self.MatchDist(".*archive.ubuntu.com/ubuntu", + "^warty$", + "Ubuntu 4.10 \"Warty Warthog\"", + ubuntu_comps, ubuntu_comps_descr)) + self.dist_list.append(self.MatchDist(".*security.ubuntu.com/ubuntu", + "^warty-security$", + _("Ubuntu 4.10 Security Updates"), + ubuntu_comps, ubuntu_comps_descr)) + self.dist_list.append(self.MatchDist(".*archive.ubuntu.com/ubuntu", + "^warty-security$", + _("Ubuntu 4.10 Security Updates"), + ubuntu_comps, ubuntu_comps_descr)) + self.dist_list.append(self.MatchDist(".*archive.ubuntu.com/ubuntu", + "^warty-updates$", + _("Ubuntu 4.10 Updates"), + ubuntu_comps, ubuntu_comps_descr)) + # Hoary + self.dist_list.append(self.MatchDist(".*archive.ubuntu.com/ubuntu", + "^hoary-security$", + _("Ubuntu 5.04 Security Updates"), + ubuntu_comps, ubuntu_comps_descr)) + self.dist_list.append(self.MatchDist(".*security.ubuntu.com/ubuntu", + "^hoary-security$", + _("Ubuntu 5.04 Security Updates"), + ubuntu_comps, ubuntu_comps_descr)) + self.dist_list.append(self.MatchDist(".*archive.ubuntu.com/ubuntu", + "^hoary$", + "Ubuntu 5.04 \"Hoary Hedgehog\"", + ubuntu_comps, ubuntu_comps_descr)) + self.dist_list.append(self.MatchDist(".*archive.ubuntu.com/ubuntu", + "^hoary-updates$", + _("Ubuntu 5.04 Updates"), + ubuntu_comps, ubuntu_comps_descr)) + # Breezy + self.dist_list.append(self.MatchDist(".*archive.ubuntu.com/ubuntu", + "^breezy-security$", + _("Ubuntu 5.10 Security Updates"), + ubuntu_comps, ubuntu_comps_descr)) + self.dist_list.append(self.MatchDist(".*security.ubuntu.com/ubuntu", + "^breezy-security$", + _("Ubuntu 5.10 Security Updates"), + ubuntu_comps, ubuntu_comps_descr)) + self.dist_list.append(self.MatchDist(".*archive.ubuntu.com/ubuntu", + "^breezy$", + "Ubuntu 5.10 \"Breezy Badger\"", + ubuntu_comps, ubuntu_comps_descr)) + self.dist_list.append(self.MatchDist(".*archive.ubuntu.com/ubuntu", + "^breezy-updates$", + _("Ubuntu 5.10 Updates"), + ubuntu_comps, ubuntu_comps_descr)) + + + # DEBIAN + debian_comps = ["^main$","^contrib$","^non-free$","^non-US$"] + debian_comps_descr = [_("Officially supported"), + _("Contributed software"), + _("Non-free software"), + _("US export restricted software") + ] + + # dists by name + self.dist_list.append(self.MatchDist(".*debian.org/debian", + "^sarge$", + _("Debian 3.1 \"Sarge\""), + debian_comps, debian_comps_descr)) + self.dist_list.append(self.MatchDist(".*debian.org/debian", + "^woody$", + _("Debian 3.0 \"Woody\""), + debian_comps, debian_comps_descr)) + # securtiy + self.dist_list.append(self.MatchDist(".*security.debian.org", + "^stable.*$", + _("Debian Stable Security Updates"), + debian_comps, debian_comps_descr)) + # dists by status + self.dist_list.append(self.MatchDist(".*debian.org/debian", + "^stable$", + _("Debian Stable"), + debian_comps, debian_comps_descr)) + self.dist_list.append(self.MatchDist(".*debian.org/debian", + "^testing$", + _("Debian Testing"), + debian_comps, debian_comps_descr)) + self.dist_list.append(self.MatchDist(".*debian.org/debian", + "^unstable$", + _("Debian Unstable \"Sid\""), + debian_comps, debian_comps_descr)) + + # non-us + self.dist_list.append(self.MatchDist(".*debian.org/debian-non-US", + "^stable.*$", + _("Debian Non-US (Stable)"), + debian_comps, debian_comps_descr)) + self.dist_list.append(self.MatchDist(".*debian.org/debian-non-US", + "^testing.*$", + _("Debian Non-US (Testing)"), + debian_comps, debian_comps_descr)) + self.dist_list.append(self.MatchDist(".*debian.org/debian-non-US", + "^unstable.*$", + _("Debian Non-US (Unstable)"), + debian_comps, debian_comps_descr)) + + + + + def match(self,source): + _ = gettext.gettext + # some sane defaults first + type_description = source.type + dist_description = source.uri + " " + source.dist + comp_description = "" + for c in source.comps: + comp_description = comp_description + " " + c + + for t in self.type_list: + if re.match(t.type, source.type): + type_description = _(t.description) + break + + for d in self.dist_list: + #print "'%s'" %source.uri + if re.match(d.uri, source.uri) and re.match(d.dist,source.dist): + dist_description = d.description + comp_description = "" + for c in source.comps: + found = False + for i in range(len(d.comps)): + if re.match(d.comps[i], c): + comp_description = comp_description+"\n"+d.comps_descriptions[i] + found = True + if found == False: + comp_description = comp_description+" "+c + break + + + return (type_description,dist_description,comp_description) diff --git a/SoftwareProperties/dialog_add.py b/SoftwareProperties/dialog_add.py new file mode 100644 index 00000000..70accfaf --- /dev/null +++ b/SoftwareProperties/dialog_add.py @@ -0,0 +1,111 @@ +# dialog_add.py.in - dialog to add a new repository +# +# Copyright (c) 2004 Canonical +# 2005 Michiel Sikkes +# +# Authors: +# Michael Vogt <mvo@debian.org> +# Michiel Sikkes <michiels@gnome.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 gobject +import gtk +import gtk.glade + +import aptsources + +class dialog_add: + def __init__(self, parent, sourceslist, datadir): + print datadir + self.sourceslist = sourceslist + + # templates + self.templatelist = aptsources.SourceEntryTemplates() + + # gtk stuff + if os.path.exists("../data/SoftwarePropertiesDialogs.glade"): + self.gladexml = gtk.glade.XML("../data/SoftwarePropertiesDialogs.glade") + else: + self.gladexml = gtk.glade.XML("%s/SoftwarePropertiesDialogs.glade" % datadir) + + self.main = widget = self.gladexml.get_widget("dialog_add") + self.main.set_transient_for(parent) + + combo = self.gladexml.get_widget("combobox_what") + self.gladexml.signal_connect("on_combobox_what_changed", self.on_combobox_what_changed, None) + # combox box needs + cell = gtk.CellRendererText() + combo.pack_start(cell, True) + combo.add_attribute(cell, 'text', 0) + self.fill_combo(combo) + self.gladexml.signal_connect("on_button_custom_clicked", + self.on_button_custom_clicked, None) + + + def fill_combo(self,combo): + liststore = gtk.ListStore(gobject.TYPE_STRING,gobject.TYPE_PYOBJECT) + for item in self.templatelist.templates: + liststore.append((item.description, item)) + combo.set_model(liststore) + combo.set_active(0) + + def on_combobox_what_changed(self, combobox, user): + #print "on_combobox_what_changed" + vbox = self.gladexml.get_widget("vbox_comps") + vbox.foreach(lambda widget,vbox: vbox.remove(widget), vbox) + liststore = combobox.get_model() + a_iter = liststore.iter_nth_child(None, combobox.get_active()) + (name, template) = liststore.get(a_iter, 0,1) + self.selected = template + comps = template.comps + for c in comps: + checkbox = gtk.CheckButton(c.description) + checkbox.set_active(c.on_by_default) + checkbox.set_data("name",c.name) + vbox.pack_start(checkbox) + checkbox.show() + + def on_button_custom_clicked(self, widget, data): + #print "on_button_custom_clicked()" + # this hide here is ugly :/ + self.main.hide() + dialog = self.gladexml.get_widget("dialog_add_custom") + res = dialog.run() + dialog.hide() + entry = self.gladexml.get_widget("entry_source_line") + line = entry.get_text() + "\n" + self.sourceslist.list.append(aptsources.SourceEntry(line)) + self.main.response(res) + + def get_enabled_comps(self, checkbutton): + if checkbutton.get_active(): + self.selected_comps.append(checkbutton.get_data("name")) + + def run(self): + res = self.main.run() + if res == gtk.RESPONSE_OK: + # add repository + self.selected_comps = [] + vbox = self.gladexml.get_widget("vbox_comps") + vbox.foreach(self.get_enabled_comps) + self.sourceslist.add(self.selected.type, + self.selected.uri, + self.selected.dist, + self.selected_comps) + self.main.hide() + return res diff --git a/SoftwareProperties/dialog_apt_key.py b/SoftwareProperties/dialog_apt_key.py new file mode 100644 index 00000000..67aa60ce --- /dev/null +++ b/SoftwareProperties/dialog_apt_key.py @@ -0,0 +1,163 @@ +# dialog_apt_key.py.in - edit the apt keys +# +# Copyright (c) 2004 Canonical +# +# Author: Michael Vogt <mvo@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 gobject +import gtk +import gtk.glade +import subprocess +import gettext +from utils import * +from subprocess import PIPE + +# gettext convenient +_ = gettext.gettext +def dummy(e): return e +N_ = dummy + +# some known keys +N_("Ubuntu Archive Automatic Signing Key <ftpmaster@ubuntu.com>") +N_("Ubuntu CD Image Automatic Signing Key <cdimage@ubuntu.com>") + +class apt_key: + def __init__(self): + self.gpg = ["/usr/bin/gpg"] + self.base_opt = self.gpg + ["--no-options", "--no-default-keyring", + "--secret-keyring", "/etc/apt/secring.gpg", + "--trustdb-name", "/etc/apt/trustdb.gpg", + "--keyring", "/etc/apt/trusted.gpg"] + self.list_opt = self.base_opt + ["--with-colons", "--batch", + "--list-keys"] + self.rm_opt = self.base_opt + ["--quiet", "--batch", + "--delete-key", "--yes"] + self.add_opt = self.base_opt + ["--quiet", "--batch", + "--import"] + + + def list(self): + res = [] + #print self.list_opt + p = subprocess.Popen(self.list_opt,stdout=PIPE).stdout + for line in p.readlines(): + fields = line.split(":") + if fields[0] == "pub": + name = fields[9] + res.append("%s %s\n%s" %((fields[4])[-8:],fields[5], _(name))) + return res + + def add(self, filename): + #print "request to add " + filename + cmd = self.add_opt[:] + cmd.append(filename) + p = subprocess.Popen(cmd) + return (p.wait() == 0) + + def update(self): + cmd = ["/usr/bin/apt-key", "update"] + p = subprocess.Popen(cmd) + return (p.wait() == 0) + + def rm(self, key): + #print "request to remove " + key + cmd = self.rm_opt[:] + cmd.append(key) + p = subprocess.Popen(cmd) + return (p.wait() == 0) + +class dialog_apt_key: + def __init__(self, parent, datadir): + # gtk stuff + if os.path.exists("../data/SoftwarePropertiesDialogs.glade"): + self.gladexml = gtk.glade.XML("../data/SoftwarePropertiesDialogs.glade") + else: + self.gladexml = gtk.glade.XML("%s/SoftwarePropertiesDialogs.glade", datadir) + self.main = self.gladexml.get_widget("dialog_apt_key") + self.main.set_transient_for(parent) + + self.gladexml.signal_connect("on_button_key_add_clicked", + self.on_button_key_add_clicked) + self.gladexml.signal_connect("on_button_key_remove_clicked", + self.on_button_key_remove_clicked) + self.gladexml.signal_connect("on_button_apt_key_update_clicked", + self.on_button_apt_key_update_clicked) + + # create apt-key object (abstraction for the apt-key command) + self.apt_key = apt_key() + + # get some widgets + self.treeview_apt_key = self.gladexml.get_widget("treeview_apt_key") + self.liststore_apt_key = gtk.ListStore(str) + self.treeview_apt_key.set_model(self.liststore_apt_key) + # Create columns and append them. + tr = gtk.CellRendererText() + tr.set_property("xpad", 10) + tr.set_property("ypad", 10) + c0 = gtk.TreeViewColumn("Key", tr, text=0) + self.treeview_apt_key.append_column(c0) + self.update_key_list() + + def on_button_apt_key_update_clicked(self, widget): + self.apt_key.update() + self.update_key_list() + + def on_button_key_add_clicked(self, widget): + chooser = gtk.FileChooserDialog(title=_("Choose a key-file"), + parent=self.main, + buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_REJECT, + gtk.STOCK_OK,gtk.RESPONSE_ACCEPT)) + res = chooser.run() + chooser.hide() + if res == gtk.RESPONSE_ACCEPT: + #print chooser.get_filename() + if not self.apt_key.add(chooser.get_filename()): + dialog_error(self.main, + _("Error importing selected file"), + _("The selected file may not be a GPG key file " + "or it might be corrupt.")) + self.update_key_list() + + def on_button_key_remove_clicked(self, widget): + selection = self.treeview_apt_key.get_selection() + (model,a_iter) = selection.get_selected() + if a_iter == None: + return + key = model.get_value(a_iter,0) + if not self.apt_key.rm(key[:8]): + error(self.main, + _("Error removing the key"), + _("The key you selected could not be removed. " + "Please report this as a bug.")) + self.update_key_list() + + def update_key_list(self): + self.liststore_apt_key.clear() + for key in self.apt_key.list(): + self.liststore_apt_key.append([key]) + + def run(self): + res = self.main.run() + self.main.hide() + + +if __name__ == "__main__": + ui = dialog_apt_key(None) + ui.run() + diff --git a/SoftwareProperties/dialog_edit.py b/SoftwareProperties/dialog_edit.py new file mode 100644 index 00000000..32e6ac0c --- /dev/null +++ b/SoftwareProperties/dialog_edit.py @@ -0,0 +1,106 @@ +# dialog_edit.py.in - edit a existing repository +# +# Copyright (c) 2004 Canonical +# 2005 Michiel Sikkes +# +# Authors: +# Michael Vogt <mvo@debian.org> +# Michiel Sikkes <michiels@gnome.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 gobject +import gtk +import gtk.glade + +import aptsources + +class dialog_edit: + def __init__(self, parent, sourceslist, source_entry, datadir): + self.sourceslist = sourceslist + self.source_entry = source_entry + + # gtk stuff + if os.path.exists("../data/SoftwarePropertiesDialogs.glade"): + self.gladexml = gtk.glade.XML("../data/SoftwarePropertiesDialogs.glade") + else: + self.gladexml = gtk.glade.XML("%s/SoftwarePropertiesDialogs.glade" % datadir) + self.main = self.gladexml.get_widget("dialog_edit") + self.main.set_transient_for(parent) + + # type + combo_type = self.gladexml.get_widget("combobox_type") + if source_entry.type == "deb": + combo_type.set_active(0) + elif source_entry.type == "deb-src": + combo_type.set_active(1) + else: + print "Error, unknown source type: '%s'" % source_enrty.type + + # uri + entry = self.gladexml.get_widget("entry_uri") + entry.set_text(source_entry.uri) + + entry = self.gladexml.get_widget("entry_dist") + entry.set_text(source_entry.dist) + + entry = self.gladexml.get_widget("entry_comps") + comps = "" + for c in source_entry.comps: + if len(comps) > 0: + comps = comps + " " + c + else: + comps = c + entry.set_text(comps) + + entry = self.gladexml.get_widget("entry_comment") + entry.set_text(source_entry.comment) + + def run(self): + res = self.main.run() + if res == gtk.RESPONSE_OK: + # get values + combo_type = self.gladexml.get_widget("combobox_type") + if combo_type.get_active() == 0: + line = "deb" + else: + line = "deb-src" + entry = self.gladexml.get_widget("entry_uri") + line = line + " " + entry.get_text() + + entry = self.gladexml.get_widget("entry_dist") + line = line + " " + entry.get_text() + + entry = self.gladexml.get_widget("entry_comps") + line = line + " " + entry.get_text() + + entry = self.gladexml.get_widget("entry_comment") + if entry.get_text() != "": + line = line + " #" + entry.get_text() + "\n" + else: + line = line + "\n" + + # change repository + index = self.sourceslist.list.index(self.source_entry) + file = self.sourceslist.list[index].file + self.sourceslist.list[index] = aptsources.SourceEntry(line,file) + #self.sourceslist.add(self.selected.type, + # self.selected.uri, + # self.selected.dist, + # self.selected_comps) + self.main.hide() + return res diff --git a/SoftwareProperties/utils.py b/SoftwareProperties/utils.py new file mode 100644 index 00000000..cf9a3343 --- /dev/null +++ b/SoftwareProperties/utils.py @@ -0,0 +1,10 @@ +import gtk + +def dialog_error(parent, primary, secondary): + p = "<span weight=\"bold\" size=\"larger\">%s</span>" % primary + dialog = gtk.MessageDialog(parent,gtk.DIALOG_MODAL, + gtk.MESSAGE_ERROR,gtk.BUTTONS_OK,"") + dialog.set_markup(p); + dialog.format_secondary_text(secondary); + dialog.run() + dialog.hide() |
