summaryrefslogtreecommitdiff
path: root/SoftwareProperties
diff options
context:
space:
mode:
authorMichael Vogt <egon@top>2005-11-15 14:18:07 +0100
committerMichael Vogt <egon@top>2005-11-15 14:18:07 +0100
commitd632109cd5964f7d4baa408d517e44f801e1be8d (patch)
treec1acf5f14bcfa183951c260a52e5560610f3a988 /SoftwareProperties
downloadpython-apt-d632109cd5964f7d4baa408d517e44f801e1be8d.tar.gz
* initial revision (after accidently killing it)
Diffstat (limited to 'SoftwareProperties')
-rw-r--r--SoftwareProperties/Makefile359
-rw-r--r--SoftwareProperties/Makefile.am9
-rw-r--r--SoftwareProperties/SoftwareProperties.py.in259
-rw-r--r--SoftwareProperties/aptsources.py437
-rw-r--r--SoftwareProperties/dialog_add.py111
-rw-r--r--SoftwareProperties/dialog_apt_key.py163
-rw-r--r--SoftwareProperties/dialog_edit.py106
-rw-r--r--SoftwareProperties/utils.py10
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()