From 28d131b543b638589c243abb6b1c247c8c653321 Mon Sep 17 00:00:00 2001 From: Sebastian Heinlein Date: Thu, 23 Feb 2006 13:24:40 +0100 Subject: * Move the mime type handling of sources.lists to gnome-software-properties * Renamed mime type to text/x-apt-sources-list * Remove all depricated add-software-channel code * Add a schemas file for update-manager * Use dh_gconf * Software Properties: - Move the channel buttons to the bottom of the notebook to get more vertical space for the channels - Set a global window icon for SoftwareProperties and its children - Add drag and drop support for sources.list on the treeview_sources - Allow to enable and disable channels - Do not use so much space for rendering the sources lista - Use the comment instead of the URI in the channel list if we don't find a nice name - Show the type only on source channels - "binary" is too technial - Add some small sanity checks to aptsources - Use single quotes in the predefind distru names * Dialog add: - merge the custom and the default add dialog - sanity checks for the custom apt line, that do not allow to add a wrong one * Update Manager: - add an option to hide the reload reminder --- SoftwareProperties/SoftwareProperties.py | 107 ++++++++++++++++++++++++------- SoftwareProperties/aptsources.py | 32 ++++++--- SoftwareProperties/dialog_add.py | 89 +++++++++++++++++-------- 3 files changed, 167 insertions(+), 61 deletions(-) (limited to 'SoftwareProperties') diff --git a/SoftwareProperties/SoftwareProperties.py b/SoftwareProperties/SoftwareProperties.py index 690b30dd..0e9a0f0d 100644 --- a/SoftwareProperties/SoftwareProperties.py +++ b/SoftwareProperties/SoftwareProperties.py @@ -37,6 +37,7 @@ from UpdateManager.Common.SimpleGladeApp import SimpleGladeApp import aptsources import dialog_add import dialog_edit +import dialog_sources_list from dialog_apt_key import apt_key from utils import * @@ -50,11 +51,22 @@ CONF_MAP = { "max_size" : "APT::Archives::MaxSize", "max_age" : "APT::Archives::MaxAge" } - +( + COLUMN_ACTIVE, + COLUMN_DESC +) = range(2) class SoftwareProperties(SimpleGladeApp): - def __init__(self, datadir=None, options=None, parent=None): + def __init__(self, datadir=None, options=None, file=None, parent=None): + + # set a default window icon + icons = gtk.icon_theme_get_default() + try: + logo=icons.load_icon("update-manager", 48, 0) + gtk.window_set_default_icon_list(logo) + except: + pass # FIXME: some saner way is needed here if datadir == None: @@ -64,6 +76,8 @@ class SoftwareProperties(SimpleGladeApp): None, domain="update-manager") self.modified = False + self.file = file + #self.gnome_program = gnome.init("Software Properties", "0.41") #self.gconfclient = gconf.client_get_default() @@ -170,25 +184,72 @@ class SoftwareProperties(SimpleGladeApp): self.init_keyslist() self.reload_keyslist() + # drag and drop support for sources.list + self.treeview_sources.drag_dest_set(gtk.DEST_DEFAULT_ALL, \ + [('text/uri-list',0, 0)], \ + gtk.gdk.ACTION_COPY) + self.treeview_sources.connect("drag_data_received",\ + self.on_sources_drag_data_received) + + + # call the add sources.list dialog if we got a file from the cli + if self.file != None: + self.open_file(file) + + def open_file(self, file): + """Show an confirmation for adding the channels of the specified file""" + dialog = dialog_sources_list.AddSourcesList(self.window_main, + self.sourceslist, + self.datadir, + file) + res = dialog.run() + if res == gtk.RESPONSE_OK: + self.reload_sourceslist() + self.modified = True + + def on_sources_drag_data_received(self, widget, context, x, y, + selection, target_type, timestamp): + """Extract the dropped file pathes and open the first file, only""" + uri = selection.data.strip() + uri_splitted = uri.split() + if len(uri_splitted)>0: + self.open_file(uri_splitted[0]) + def hide(self): self.window_main.hide() def init_sourceslist(self): - self.source_store = gtk.ListStore(str, bool, gobject.TYPE_PYOBJECT) + self.source_store = gtk.ListStore(gobject.TYPE_BOOLEAN, + gobject.TYPE_STRING, + gobject.TYPE_PYOBJECT) self.treeview_sources.set_model(self.source_store) - tr = gtk.CellRendererText() - tr.set_property("xpad", 10) - tr.set_property("ypad", 10) - - source_col = gtk.TreeViewColumn("Description", tr, markup=LIST_MARKUP) - source_col.set_max_width(500) - - self.treeview_sources.append_column(source_col) + cell_desc = gtk.CellRendererText() + #cell_desc.set_property("xpad", 10) + #cell_desc.set_property("ypad", 10) + col_desc = gtk.TreeViewColumn(_("Software Channel"), cell_desc, + markup=COLUMN_DESC) + col_desc.set_max_width(500) + + cell_toggle = gtk.CellRendererToggle() + cell_toggle.connect('toggled', self.on_channel_toggled) + col_active = gtk.TreeViewColumn(_("Active"), cell_toggle, + active=COLUMN_ACTIVE) + + self.treeview_sources.append_column(col_active) + self.treeview_sources.append_column(col_desc) self.sourceslist = aptsources.SourcesList() self.matcher = aptsources.SourceEntryMatcher() + def on_channel_toggled(self, cell_toggle, path): + """Enable or disable the selected channel""" + iter = self.source_store.get_iter((int(path),)) + source_entry = self.source_store.get_value(iter, LIST_ENTRY_OBJ) + source_entry.disabled = not source_entry.disabled + self.reload_sourceslist() + self.modified = True + def init_keyslist(self): self.keys_store = gtk.ListStore(str) self.treeview2.set_model(self.keys_store) @@ -201,16 +262,14 @@ class SoftwareProperties(SimpleGladeApp): def reload_sourceslist(self): self.source_store.clear() for source in self.sourceslist.list: - if source.invalid or source.disabled: + if source.invalid: continue - (a_type, dist, comps) = self.matcher.match(source) - - contents = "" - if source.comment != "": - contents += "%s\n\n" % (source.comment) - contents +="%s (%s) \n%s" % (dist,a_type, comps) + (nice_type, nice_dist, nice_comps) = self.matcher.match(source) - self.source_store.append([contents, not source.disabled, source]) + contents = "%s%s" % (nice_dist, nice_comps) + if source.type == "deb-src": + contents = "%s - %s %s" % (nice_dist, nice_type, nice_comps) + self.source_store.append([not source.disabled, contents, source]) def reload_keyslist(self): self.keys_store.clear() @@ -220,11 +279,11 @@ class SoftwareProperties(SimpleGladeApp): def on_combobox_update_interval_changed(self, widget): i = self.combobox_update_interval.get_active() if i != -1: - value = self.combobox_interval_mapping[i] - # Only write the key if it has changed - if not value == apt_pkg.Config.FindI(CONF_MAP["autoupdate"]): - apt_pkg.Config.Set(CONF_MAP["autoupdate"], str(value)) - self.write_config() + value = self.combobox_interval_mapping[i] + # Only write the key if it has changed + if not value == apt_pkg.Config.FindI(CONF_MAP["autoupdate"]): + apt_pkg.Config.Set(CONF_MAP["autoupdate"], str(value)) + self.write_config() def on_opt_autoupdate_toggled(self, widget): if self.checkbutton_auto_update.get_active(): diff --git a/SoftwareProperties/aptsources.py b/SoftwareProperties/aptsources.py index 03459adf..f751cf7c 100644 --- a/SoftwareProperties/aptsources.py +++ b/SoftwareProperties/aptsources.py @@ -102,8 +102,16 @@ class SourceEntry: line = line[:i] # source is ok, split it and see what we have pieces = self.mysplit(line) + # Sanity check + if len(pieces) < 3: + self.invalid = True + return # Type, deb or deb-src self.type = string.strip(pieces[0]) + # Sanity check + if self.type not in ("deb", "deb-src"): + self.invalid = True + return # URI self.uri = string.strip(pieces[1]) # distro and components (optional) @@ -326,7 +334,7 @@ class SourceEntryMatcher: _ = gettext.gettext self.type_list = [] self.type_list.append(self.MatchType("^deb$",_("Binary"))) - self.type_list.append(self.MatchType("^deb-src$",_("Source"))) + self.type_list.append(self.MatchType("^deb-src$",_("Source Code"))) self.dist_list = [] @@ -338,7 +346,7 @@ class SourceEntryMatcher: # CDs self.dist_list.append(self.MatchDist("cdrom:\[Ubuntu.*5.10", ".*", - _("CD disk with Ubuntu 5.10 \"Breezy Badger\""), + _("CD disk with Ubuntu 5.10 'Breezy Badger'"), ubuntu_comps, ubuntu_comps_descr)) self.dist_list.append(self.MatchDist("cdrom:\[Ubuntu.*5.04", ".*", @@ -352,7 +360,7 @@ class SourceEntryMatcher: # Warty self.dist_list.append(self.MatchDist(".*archive.ubuntu.com/ubuntu", "^warty$", - "Ubuntu 4.10 \"Warty Warthog\"", + "Ubuntu 4.10 'Warty Warthog'", ubuntu_comps, ubuntu_comps_descr)) self.dist_list.append(self.MatchDist(".*security.ubuntu.com/ubuntu", "^warty-security$", @@ -377,7 +385,7 @@ class SourceEntryMatcher: ubuntu_comps, ubuntu_comps_descr)) self.dist_list.append(self.MatchDist(".*archive.ubuntu.com/ubuntu", "^hoary$", - "Ubuntu 5.04 \"Hoary Hedgehog\"", + "Ubuntu 5.04 'Hoary Hedgehog'", ubuntu_comps, ubuntu_comps_descr)) self.dist_list.append(self.MatchDist(".*archive.ubuntu.com/ubuntu", "^hoary-updates$", @@ -394,7 +402,7 @@ class SourceEntryMatcher: ubuntu_comps, ubuntu_comps_descr)) self.dist_list.append(self.MatchDist(".*archive.ubuntu.com/ubuntu", "^breezy$", - "Ubuntu 5.10 \"Breezy Badger\"", + "Ubuntu 5.10 'Breezy Badger'", ubuntu_comps, ubuntu_comps_descr)) self.dist_list.append(self.MatchDist(".*archive.ubuntu.com/ubuntu", "^breezy-updates$", @@ -411,7 +419,7 @@ class SourceEntryMatcher: ubuntu_comps, ubuntu_comps_descr)) self.dist_list.append(self.MatchDist(".*archive.ubuntu.com/ubuntu", "^dapper$", - "Ubuntu 6.04 \"Dapper Drake\"", + "Ubuntu 6.04 'Dapper Drake'", ubuntu_comps, ubuntu_comps_descr)) self.dist_list.append(self.MatchDist(".*archive.ubuntu.com/ubuntu", "^dapper-updates$", @@ -430,11 +438,11 @@ class SourceEntryMatcher: # dists by name self.dist_list.append(self.MatchDist(".*debian.org/debian", "^sarge$", - _("Debian 3.1 \"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 3.0 'Woody'"), debian_comps, debian_comps_descr)) # securtiy self.dist_list.append(self.MatchDist(".*security.debian.org", @@ -452,7 +460,7 @@ class SourceEntryMatcher: debian_comps, debian_comps_descr)) self.dist_list.append(self.MatchDist(".*debian.org/debian", "^unstable$", - _("Debian Unstable \"Sid\""), + _("Debian Unstable 'Sid'"), debian_comps, debian_comps_descr)) # non-us @@ -477,6 +485,10 @@ class SourceEntryMatcher: # some sane defaults first type_description = source.type dist_description = source.uri + " " + source.dist + # if there is a comment use it instead of the url + if source.comment: + dist_description = source.comment + comp_description = "" for c in source.comps: comp_description = comp_description + " " + c @@ -488,7 +500,7 @@ class SourceEntryMatcher: for d in self.dist_list: #print "'%s'" %source.uri - if re.match(d.uri, source.uri) and re.match(d.dist,source.dist): + 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: diff --git a/SoftwareProperties/dialog_add.py b/SoftwareProperties/dialog_add.py index 9b384623..effd9f24 100644 --- a/SoftwareProperties/dialog_add.py +++ b/SoftwareProperties/dialog_add.py @@ -45,16 +45,58 @@ class dialog_add: self.main = widget = self.gladexml.get_widget("dialog_add") self.main.set_transient_for(self.parent) - combo = self.gladexml.get_widget("combobox_what") + # Setup the official channel widgets + self.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) + self.combo.pack_start(cell, True) + self.combo.add_attribute(cell, 'text', 0) + self.fill_combo(self.combo) + # Setup the custom channel widgets + self.entry = self.gladexml.get_widget("entry_source_line") + self.gladexml.signal_connect("on_entry_source_line_changed", + self.check_line) + + # Setup the toggle action + self.radio_official = self.gladexml.get_widget("radiobutton_official") + self.radio_custom = self.gladexml.get_widget("radiobutton_custom") + self.button_add = self.gladexml.get_widget("button_add_channel") + self.gladexml.signal_connect("on_radiobutton_custom_toggled", + self.on_radio_custom_toggled) + self.gladexml.signal_connect("on_radiobutton_official_toggled", + self.on_radio_official_toggled) + + # We start with the official channels: + self.official = True + self.radio_custom.toggled() + + def check_line(self, *args): + """Check for a valid apt line""" + if self.official == True: + self.button_add.set_sensitive(True) + return + + line = self.entry.get_text() + "\n" + source_entry = aptsources.SourceEntry(line) + if source_entry.invalid == True or source_entry.disabled == True: + self.button_add.set_sensitive(False) + else: + self.button_add.set_sensitive(True) + + + def on_radio_custom_toggled(self, radio): + state = radio.get_active() + self.entry.set_sensitive(state) + self.check_line() + + def on_radio_official_toggled(self, radio): + state = radio.get_active() + self.combo.set_sensitive(state) + for check in self.comps: + check.set_sensitive(state) + self.official = state + self.button_add.set_sensitive(state) def fill_combo(self,combo): liststore = gtk.ListStore(gobject.TYPE_STRING,gobject.TYPE_PYOBJECT) @@ -72,25 +114,14 @@ class dialog_add: (name, template) = liststore.get(a_iter, 0,1) self.selected = template comps = template.comps + self.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") - dialog.set_transient_for(self.parent) - 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) + self.comps.append(checkbox) def get_enabled_comps(self, checkbutton): if checkbutton.get_active(): @@ -100,12 +131,16 @@ class dialog_add: 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) + if self.official == True: + 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) + else: + line = self.entry.get_text() + "\n" + self.sourceslist.list.append(aptsources.SourceEntry(line)) self.main.hide() return res -- cgit v1.2.3 From fcea944da8f0ce5e178f79ec670658e279c07467 Mon Sep 17 00:00:00 2001 From: Sebastian Heinlein Date: Thu, 23 Feb 2006 15:14:57 +0100 Subject: * Use a smaller border in the add cdrom dialog * add sources list was missing --- SoftwareProperties/dialog_sources_list.py | 122 ++++++++++++++++++++++++++++++ data/SoftwarePropertiesDialogs.glade | 2 +- 2 files changed, 123 insertions(+), 1 deletion(-) create mode 100644 SoftwareProperties/dialog_sources_list.py (limited to 'SoftwareProperties') diff --git a/SoftwareProperties/dialog_sources_list.py b/SoftwareProperties/dialog_sources_list.py new file mode 100644 index 00000000..9159d01f --- /dev/null +++ b/SoftwareProperties/dialog_sources_list.py @@ -0,0 +1,122 @@ +#!/usr/bin/env python +import pygtk +import gtk +import gtk.glade +import gobject +import os +from optparse import OptionParser +from aptsources import SourcesList, SourceEntryMatcher +from gettext import gettext as _ +import gettext +import urllib + +class AddSourcesList: + def __init__(self, parent, sourceslist, datadir, file): + print file + self.parent = parent + self.sources_old = sourceslist + self.file = self.format_uri(file) + self.glade = gtk.glade.XML(os.path.join(datadir, + "glade/SoftwarePropertiesDialogs.glade")) + self.glade.signal_autoconnect(self) + self.dialog = self.glade.get_widget("dialog_sources_list") + self.label = self.glade.get_widget("label_sources") + self.button_add = self.glade.get_widget("button_add") + self.button_cancel = self.glade.get_widget("button_cancel") + self.treeview = self.glade.get_widget("treeview_sources") + self.button_close = self.glade.get_widget("button_close") + self.scrolled = self.glade.get_widget("scrolled_window") + self.image = self.glade.get_widget("image_sources_list") + + self.dialog.realize() + if self.parent != None: + self.dialog.set_transient_for(parent) + else: + self.dialog.set_title(_("Add Software Channels")) + self.dialog.window.set_functions(gtk.gdk.FUNC_MOVE) + + # Setup the treeview + self.store = gtk.ListStore(gobject.TYPE_STRING) + self.treeview.set_model(self.store) + cell = gtk.CellRendererText() + column = gtk.TreeViewColumn("Software Channel", cell, markup=0) + column.set_max_width(500) + self.treeview.append_column(column) + + # Parse the source.list file + try: + self.sources = SingleSourcesList(self.file) + except: + self.error() + return + self.matcher = SourceEntryMatcher() + + # show the found channels or an error message + if len(self.sources.list) > 0: + self.button_close.hide() + found = False + for source in self.sources.list: + if source.invalid or source.disabled: + continue + found = True + (a_type, dist, comps) = self.matcher.match(source) + + line = "%s (%s)%s" %\ + (dist, a_type, comps) + self.store.append([line]) + if found == False: + self.error() + return + + header = gettext.ngettext("Add the following software channel?", + "Add the following software channels?", + len(self.sources.list)) + body = _("You can install software from a channel. Use "\ + "trusted channels, only.") + self.label.set_markup("%s\n\n%s" % (header, body)) + self.button_add.set_use_underline(True) + self.button_add.set_label(gettext.ngettext("_Add Channel", + "_Add Channels", + len(self.sources.list))) + else: + self.error() + return + + def error(self): + self.button_add.hide() + self.button_cancel.hide() + self.scrolled.hide() + self.button_close.show() + self.image.set_from_stock(gtk.STOCK_DIALOG_ERROR, gtk.ICON_SIZE_DIALOG) + header = _("Could not add any software channels") + body = _("The file '%s' does not contain any valid " + "software channels." % self.file) + self.label.set_markup("%s\n\n%s" % (header, body)) + + def run(self): + res = self.dialog.run() + if res == gtk.RESPONSE_OK: + for source in self.sources: + self.sources_old.add(source.type, + source.uri, + source.dist, + source.comps, + source.comment) + self.dialog.destroy() + return res + + def format_uri(self, uri): + path = urllib.url2pathname(uri) # escape special chars + path = path.strip('\r\n\x00') # remove \r\n and NULL + if path.startswith('file:\\\\\\'): # windows + path = path[8:] # 8 is len('file:///') + elif path.startswith('file://'): #nautilus, rox + path = path[7:] # 7 is len('file://') + elif path.startswith('file:'): # xffm + path = path[5:] # 5 is len('file:') + return path + +class SingleSourcesList(SourcesList): + def __init__(self, file): + self.list = [] + self.load(file) diff --git a/data/SoftwarePropertiesDialogs.glade b/data/SoftwarePropertiesDialogs.glade index c98cc636..3e4be82f 100644 --- a/data/SoftwarePropertiesDialogs.glade +++ b/data/SoftwarePropertiesDialogs.glade @@ -1945,7 +1945,7 @@ You can add and remove authentication keys in this dialog. A key makes it possib - 12 + 6 Scanning CD-ROM GTK_WINDOW_TOPLEVEL GTK_WIN_POS_NONE -- cgit v1.2.3 From 51f21da0e24b8d3b1577a47d7a8342997e6cbc83 Mon Sep 17 00:00:00 2001 From: Sebastian Heinlein Date: Thu, 23 Feb 2006 22:46:50 +0100 Subject: * Automatic security updates --- SoftwareProperties/SoftwareProperties.py | 62 +++++++++++++++++++++++++++++++- SoftwareProperties/aptsources.py | 55 +++++++++++++++++++--------- 2 files changed, 99 insertions(+), 18 deletions(-) (limited to 'SoftwareProperties') diff --git a/SoftwareProperties/SoftwareProperties.py b/SoftwareProperties/SoftwareProperties.py index 0e9a0f0d..fb9c8b05 100644 --- a/SoftwareProperties/SoftwareProperties.py +++ b/SoftwareProperties/SoftwareProperties.py @@ -260,16 +260,76 @@ class SoftwareProperties(SimpleGladeApp): self.treeview2.append_column(keys_col) def reload_sourceslist(self): + # To store the sources that provide updates + self.sources_updates = [] + # To store the sources that provide securtiy fixes + self.sources_security = [] + # To store the activated components of each dist + self.system_comps = {} + self.source_store.clear() for source in self.sourceslist.list: if source.invalid: continue - (nice_type, nice_dist, nice_comps) = self.matcher.match(source) + (nice_type, nice_dist, nice_comps, special) = self.matcher.match(source) + print "match: %s %s" % (source.dist, special) contents = "%s%s" % (nice_dist, nice_comps) if source.type == "deb-src": contents = "%s - %s %s" % (nice_dist, nice_type, nice_comps) self.source_store.append([not source.disabled, contents, source]) + + # Collect the components of an activated system dist + if special == aptsources.SOURCE_SYSTEM and source.disabled != True: + if self.system_comps.has_key(source.dist): + current = self.system_comps[source.dist] + self.system_comps[source.dist] = (current | set(source.comps)) + else: + self.system_comps[source.dist] = set(source.comps) + + # Collect sources that provide updates + elif special == aptsources.SOURCE_UPDATES: + self.sources_updates.append(source) + elif special == aptsources.SOURCE_SECURITY: + self.sources_security.append(source) + + + print "\n\nSecurity Updates: %s" % self.sources_security + print "\nSystem Sources: %s " % self.sources_system + print "\nUpdates: %s" % self.sources_updates + print "\nSystem Compos: %s " % self.system_comps + + modified = False + # Check if each security source contains all components of + # the same dist + for source in self.sources_security: + print "SecSource: %s" % source.dist + # Skip the "-security" from the dist + # FIXME: Does not work for debian + i = source.dist.find("-") + dist = source.dist[:i] + # Are there any active components for the dist? + if self.system_comps.has_key(dist): + comps_sys = self.system_comps[dist] + comps_sec = set(source.comps) + # Are there components without sec updates? + comps_endangered = comps_sys - comps_sec + print "In Danger: %s " % comps_endangered + if len(comps_endangered) > 0: + # convert the set into a list + comps_new=[] + for comp in comps_endangered: + comps_new.append(comp) + # add a security source with the additional components + print "Adding security updates for %s - %s" % (source.dist, comps_new) + self.sourceslist.add(source.type, source.uri, + source.dist, comps_new, + source.comment) + modified = True + # Reload the sourceslist if we added a new source + if modified == True: + print "modified" + self.reload_sourceslist() def reload_keyslist(self): self.keys_store.clear() diff --git a/SoftwareProperties/aptsources.py b/SoftwareProperties/aptsources.py index f751cf7c..7cb58168 100644 --- a/SoftwareProperties/aptsources.py +++ b/SoftwareProperties/aptsources.py @@ -32,6 +32,8 @@ import os.path from UpdateManager.Common.DistInfo import DistInfo +(SOURCE_SECURITY, SOURCE_UPDATES, SOURCE_SYSTEM) = range(3) + # actual source.list entries class SourceEntry: @@ -323,12 +325,14 @@ class SourceEntryMatcher: self.description = a_descr class MatchDist: - def __init__(self,a_uri,a_dist, a_descr,l_comps, l_comps_descr): + def __init__(self, a_uri, a_dist, a_descr, l_comps, + l_comps_descr, special=None): self.uri = a_uri self.dist = a_dist self.description = a_descr self.comps = l_comps self.comps_descriptions = l_comps_descr + self.special = special def __init__(self): _ = gettext.gettext @@ -338,23 +342,32 @@ class SourceEntryMatcher: self.dist_list = [] + #UBUNTU 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.*6.04", + ".*", + _("Cdrom with Ubuntu 6.04 'Dapper "\ + "Drake'"), + ubuntu_comps, ubuntu_comps_descr)) self.dist_list.append(self.MatchDist("cdrom:\[Ubuntu.*5.10", ".*", - _("CD disk with Ubuntu 5.10 'Breezy Badger'"), + _("Cdrom 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\""), + _("Cdrom 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\""), + _("Cdrom with Ubuntu 4.10 'Warty "\ + "Warthog'"), ubuntu_comps, ubuntu_comps_descr)) # URIs # Warty @@ -365,7 +378,8 @@ class SourceEntryMatcher: self.dist_list.append(self.MatchDist(".*security.ubuntu.com/ubuntu", "^warty-security$", _("Ubuntu 4.10 Security Updates"), - ubuntu_comps, ubuntu_comps_descr)) + ubuntu_comps, ubuntu_comps_descr, + SOURCE_SECURITY)) self.dist_list.append(self.MatchDist(".*archive.ubuntu.com/ubuntu", "^warty-security$", _("Ubuntu 4.10 Security Updates"), @@ -395,36 +409,44 @@ class SourceEntryMatcher: self.dist_list.append(self.MatchDist(".*archive.ubuntu.com/ubuntu", "^breezy-security$", _("Ubuntu 5.10 Security Updates"), - ubuntu_comps, ubuntu_comps_descr)) + ubuntu_comps, ubuntu_comps_descr, + SOURCE_SECURITY)) self.dist_list.append(self.MatchDist(".*security.ubuntu.com/ubuntu", "^breezy-security$", _("Ubuntu 5.10 Security Updates"), - ubuntu_comps, ubuntu_comps_descr)) + ubuntu_comps, ubuntu_comps_descr, + SOURCE_SECURITY)) self.dist_list.append(self.MatchDist(".*archive.ubuntu.com/ubuntu", "^breezy$", "Ubuntu 5.10 'Breezy Badger'", - ubuntu_comps, ubuntu_comps_descr)) + ubuntu_comps, ubuntu_comps_descr, + SOURCE_SYSTEM)) self.dist_list.append(self.MatchDist(".*archive.ubuntu.com/ubuntu", "^breezy-updates$", _("Ubuntu 5.10 Updates"), - ubuntu_comps, ubuntu_comps_descr)) + ubuntu_comps, ubuntu_comps_descr, + SOURCE_UPDATES)) # dapper self.dist_list.append(self.MatchDist(".*archive.ubuntu.com/ubuntu", "^dapper-security$", _("Ubuntu 6.04 Security Updates"), - ubuntu_comps, ubuntu_comps_descr)) + ubuntu_comps, ubuntu_comps_descr, + SOURCE_SECURITY)) self.dist_list.append(self.MatchDist(".*security.ubuntu.com/ubuntu", "^dapper-security$", _("Ubuntu 6.04 Security Updates"), - ubuntu_comps, ubuntu_comps_descr)) + ubuntu_comps, ubuntu_comps_descr, + SOURCE_SECURITY)) self.dist_list.append(self.MatchDist(".*archive.ubuntu.com/ubuntu", "^dapper$", "Ubuntu 6.04 'Dapper Drake'", - ubuntu_comps, ubuntu_comps_descr)) + ubuntu_comps, ubuntu_comps_descr, + SOURCE_SYSTEM)) self.dist_list.append(self.MatchDist(".*archive.ubuntu.com/ubuntu", "^dapper-updates$", _("Ubuntu 6.04 Updates"), - ubuntu_comps, ubuntu_comps_descr)) + ubuntu_comps, ubuntu_comps_descr, + SOURCE_UPDATES)) # DEBIAN @@ -477,12 +499,10 @@ class SourceEntryMatcher: _("Debian Non-US (Unstable)"), debian_comps, debian_comps_descr)) - - - def match(self,source): _ = gettext.gettext # some sane defaults first + special = None type_description = source.type dist_description = source.uri + " " + source.dist # if there is a comment use it instead of the url @@ -503,6 +523,7 @@ class SourceEntryMatcher: if re.match(d.uri, source.uri) and re.match(d.dist, source.dist): dist_description = d.description comp_description = "" + special = d.special for c in source.comps: found = False for i in range(len(d.comps)): @@ -514,7 +535,7 @@ class SourceEntryMatcher: break - return (type_description,dist_description,comp_description) + return (type_description, dist_description, comp_description, special) # some simple tests -- cgit v1.2.3 From 4c058967a18024dc127179c98fb02bbc4eda2e7b Mon Sep 17 00:00:00 2001 From: Sebastian Heinlein Date: Thu, 23 Feb 2006 23:26:04 +0100 Subject: * Move the check_endangered_comps to aptsources.py * Tag the older distrus, too * Add support for backports --- SoftwareProperties/SoftwareProperties.py | 60 +-------------- SoftwareProperties/aptsources.py | 125 ++++++++++++++++++++++++++++--- 2 files changed, 114 insertions(+), 71 deletions(-) (limited to 'SoftwareProperties') diff --git a/SoftwareProperties/SoftwareProperties.py b/SoftwareProperties/SoftwareProperties.py index fb9c8b05..0209825d 100644 --- a/SoftwareProperties/SoftwareProperties.py +++ b/SoftwareProperties/SoftwareProperties.py @@ -260,14 +260,8 @@ class SoftwareProperties(SimpleGladeApp): self.treeview2.append_column(keys_col) def reload_sourceslist(self): - # To store the sources that provide updates - self.sources_updates = [] - # To store the sources that provide securtiy fixes - self.sources_security = [] - # To store the activated components of each dist - self.system_comps = {} - self.source_store.clear() + self.sourceslist.check_for_endangered_dists() for source in self.sourceslist.list: if source.invalid: continue @@ -279,58 +273,6 @@ class SoftwareProperties(SimpleGladeApp): contents = "%s - %s %s" % (nice_dist, nice_type, nice_comps) self.source_store.append([not source.disabled, contents, source]) - # Collect the components of an activated system dist - if special == aptsources.SOURCE_SYSTEM and source.disabled != True: - if self.system_comps.has_key(source.dist): - current = self.system_comps[source.dist] - self.system_comps[source.dist] = (current | set(source.comps)) - else: - self.system_comps[source.dist] = set(source.comps) - - # Collect sources that provide updates - elif special == aptsources.SOURCE_UPDATES: - self.sources_updates.append(source) - elif special == aptsources.SOURCE_SECURITY: - self.sources_security.append(source) - - - print "\n\nSecurity Updates: %s" % self.sources_security - print "\nSystem Sources: %s " % self.sources_system - print "\nUpdates: %s" % self.sources_updates - print "\nSystem Compos: %s " % self.system_comps - - modified = False - # Check if each security source contains all components of - # the same dist - for source in self.sources_security: - print "SecSource: %s" % source.dist - # Skip the "-security" from the dist - # FIXME: Does not work for debian - i = source.dist.find("-") - dist = source.dist[:i] - # Are there any active components for the dist? - if self.system_comps.has_key(dist): - comps_sys = self.system_comps[dist] - comps_sec = set(source.comps) - # Are there components without sec updates? - comps_endangered = comps_sys - comps_sec - print "In Danger: %s " % comps_endangered - if len(comps_endangered) > 0: - # convert the set into a list - comps_new=[] - for comp in comps_endangered: - comps_new.append(comp) - # add a security source with the additional components - print "Adding security updates for %s - %s" % (source.dist, comps_new) - self.sourceslist.add(source.type, source.uri, - source.dist, comps_new, - source.comment) - modified = True - # Reload the sourceslist if we added a new source - if modified == True: - print "modified" - self.reload_sourceslist() - def reload_keyslist(self): self.keys_store.clear() for key in self.apt_key.list(): diff --git a/SoftwareProperties/aptsources.py b/SoftwareProperties/aptsources.py index 7cb58168..5f9c6d24 100644 --- a/SoftwareProperties/aptsources.py +++ b/SoftwareProperties/aptsources.py @@ -32,7 +32,7 @@ import os.path from UpdateManager.Common.DistInfo import DistInfo -(SOURCE_SECURITY, SOURCE_UPDATES, SOURCE_SYSTEM) = range(3) +(SOURCE_SECURITY, SOURCE_UPDATES, SOURCE_SYSTEM, SOURCE_BACKPORTS) = range(4) # actual source.list entries class SourceEntry: @@ -280,6 +280,76 @@ class SourcesList: files[source.file].write(source.str()) for f in files: files[f].close() + + def check_for_endangered_dists(self): + # To store the sources that provide updates + self.sources_updates = [] + # To store the sources that provide backports + self.sources_backports = [] + # To store the sources that provide securtiy fixes + self.sources_security = [] + # To store the activated components of each dist + self.system_comps = {} + + # The matcher searches sets the required special tags + self.matcher = SourceEntryMatcher() + + for source in self.list: + if source.invalid: + continue + (nice_type, nice_dist, nice_comps, special) = self.matcher.match(source) + print "match: %s %s" % (source.dist, special) + + # Collect the components of an activated system dist + if special == SOURCE_SYSTEM and source.disabled != True: + if self.system_comps.has_key(source.dist): + current = self.system_comps[source.dist] + self.system_comps[source.dist] = (current | set(source.comps)) + else: + self.system_comps[source.dist] = set(source.comps) + + # Collect sources that provide updates + elif special == SOURCE_UPDATES: + self.sources_updates.append(source) + elif special == SOURCE_SECURITY: + self.sources_security.append(source) + elif special == SOURCE_BACKPORTS: + self.sources_backports.append(source) + + + print "\nSystem Compos: %s " % self.system_comps + + # Check if each security source contains all components of + # the same dist + self.add_updates(self.sources_security) + self.add_updates(self.sources_updates) + self.add_updates(self.sources_backports) + + def add_updates(self, updates): + modified = False + for source in updates: + print "SecSource: %s" % source.dist + # Skip the "-security" and "-updates" from the dist + i = source.dist.find("-") + dist = source.dist[:i] + # Are there any active components for the dist? + if self.system_comps.has_key(dist): + comps_sys = self.system_comps[dist] + comps_sec = set(source.comps) + # Are there components without updates? + comps_endangered = comps_sys - comps_sec + print "In Danger: %s " % comps_endangered + if len(comps_endangered) > 0: + # convert the set into a list + comps_new=[] + for comp in comps_endangered: + comps_new.append(comp) + # add a security source with the additional components + print "Adding updates for %s - %s" % (source.dist, comps_new) + self.add(source.type, source.uri, source.dist, comps_new, + source.comment) + modified = True + return modified # templates for the add dialog class SourceEntryTemplate(SourceEntry): @@ -353,28 +423,33 @@ class SourceEntryMatcher: ".*", _("Cdrom with Ubuntu 6.04 'Dapper "\ "Drake'"), - ubuntu_comps, ubuntu_comps_descr)) + ubuntu_comps, ubuntu_comps_descr, + SOURCE_SYSTEM)) self.dist_list.append(self.MatchDist("cdrom:\[Ubuntu.*5.10", ".*", _("Cdrom with Ubuntu 5.10 'Breezy "\ "Badger'"), - ubuntu_comps, ubuntu_comps_descr)) + ubuntu_comps, ubuntu_comps_descr, + SOURCE_SYSTEM)) self.dist_list.append(self.MatchDist("cdrom:\[Ubuntu.*5.04", ".*", _("Cdrom with Ubuntu 5.04 'Hoary "\ "Hedgehog'"), - ubuntu_comps, ubuntu_comps_descr)) + ubuntu_comps, ubuntu_comps_descr, + SOURCE_SYSTEM)) self.dist_list.append(self.MatchDist("cdrom:\[Ubuntu.*4.10", ".*", _("Cdrom with Ubuntu 4.10 'Warty "\ "Warthog'"), - ubuntu_comps, ubuntu_comps_descr)) + ubuntu_comps, ubuntu_comps_descr, + SOURCE_SYSTEM)) # URIs # Warty self.dist_list.append(self.MatchDist(".*archive.ubuntu.com/ubuntu", "^warty$", "Ubuntu 4.10 'Warty Warthog'", - ubuntu_comps, ubuntu_comps_descr)) + ubuntu_comps, ubuntu_comps_descr, + SOURCE_SYSTEM)) self.dist_list.append(self.MatchDist(".*security.ubuntu.com/ubuntu", "^warty-security$", _("Ubuntu 4.10 Security Updates"), @@ -383,28 +458,44 @@ class SourceEntryMatcher: self.dist_list.append(self.MatchDist(".*archive.ubuntu.com/ubuntu", "^warty-security$", _("Ubuntu 4.10 Security Updates"), - ubuntu_comps, ubuntu_comps_descr)) + ubuntu_comps, ubuntu_comps_descr, + SOURCE_SECURITY)) + self.dist_list.append(self.MatchDist(".*archive.ubuntu.com/ubuntu", + "^warty-backports$", + _("Ubuntu 4.10 Backports"), + ubuntu_comps, ubuntu_comps_descr, + SOURCE_BACKPORTS)) self.dist_list.append(self.MatchDist(".*archive.ubuntu.com/ubuntu", "^warty-updates$", _("Ubuntu 4.10 Updates"), - ubuntu_comps, ubuntu_comps_descr)) + ubuntu_comps, ubuntu_comps_descr, + SOURCE_UPDATES)) # Hoary self.dist_list.append(self.MatchDist(".*archive.ubuntu.com/ubuntu", "^hoary-security$", _("Ubuntu 5.04 Security Updates"), - ubuntu_comps, ubuntu_comps_descr)) + ubuntu_comps, ubuntu_comps_descr, + SOURCE_SECURITY)) self.dist_list.append(self.MatchDist(".*security.ubuntu.com/ubuntu", "^hoary-security$", _("Ubuntu 5.04 Security Updates"), - ubuntu_comps, ubuntu_comps_descr)) + ubuntu_comps, ubuntu_comps_descr, + SOURCE_SECURITY)) self.dist_list.append(self.MatchDist(".*archive.ubuntu.com/ubuntu", "^hoary$", "Ubuntu 5.04 'Hoary Hedgehog'", - ubuntu_comps, ubuntu_comps_descr)) + ubuntu_comps, ubuntu_comps_descr, + SOURCE_SYSTEM)) + self.dist_list.append(self.MatchDist(".*archive.ubuntu.com/ubuntu", + "^hoary-backports$", + _("Ubuntu 5.04 Backports"), + ubuntu_comps, ubuntu_comps_descr, + SOURCE_BACKPORTS)) self.dist_list.append(self.MatchDist(".*archive.ubuntu.com/ubuntu", "^hoary-updates$", _("Ubuntu 5.04 Updates"), - ubuntu_comps, ubuntu_comps_descr)) + ubuntu_comps, ubuntu_comps_descr, + SOURCE_UPDATES)) # Breezy self.dist_list.append(self.MatchDist(".*archive.ubuntu.com/ubuntu", "^breezy-security$", @@ -421,6 +512,11 @@ class SourceEntryMatcher: "Ubuntu 5.10 'Breezy Badger'", ubuntu_comps, ubuntu_comps_descr, SOURCE_SYSTEM)) + self.dist_list.append(self.MatchDist(".*archive.ubuntu.com/ubuntu", + "^breezy-backports$", + _("Ubuntu 5.10 Backports"), + ubuntu_comps, ubuntu_comps_descr, + SOURCE_BACKPORTS)) self.dist_list.append(self.MatchDist(".*archive.ubuntu.com/ubuntu", "^breezy-updates$", _("Ubuntu 5.10 Updates"), @@ -442,6 +538,11 @@ class SourceEntryMatcher: "Ubuntu 6.04 'Dapper Drake'", ubuntu_comps, ubuntu_comps_descr, SOURCE_SYSTEM)) + self.dist_list.append(self.MatchDist(".*archive.ubuntu.com/ubuntu", + "^dapper-backports$", + _("Ubuntu 6.04 Backports"), + ubuntu_comps, ubuntu_comps_descr, + SOURCE_BACKPORTS)) self.dist_list.append(self.MatchDist(".*archive.ubuntu.com/ubuntu", "^dapper-updates$", _("Ubuntu 6.04 Updates"), -- cgit v1.2.3 From 629ab77bfdd4979cb6da87a0e20c5b131906c977 Mon Sep 17 00:00:00 2001 From: Sebastian Heinlein Date: Fri, 24 Feb 2006 02:18:49 +0100 Subject: * Rendering of channel sources: - add a small white space around each line - move the rendering to its own method and aptsources so that it can be reused in the dialog_sources_list - Tag debian sources - Do not show the components of updates, security-updates and backports * Channel handling - Bring not yet used methods for removing and disabling components in position - Add support for automatically updated updates and backports * General - comment out debug outputs - fix the plural gettext in the dialog_sources_list - fix d'n'd and mime type opening - was a bug in the renderer - add more TODO --- SoftwareProperties/SoftwareProperties.py | 15 ++- SoftwareProperties/aptsources.py | 156 ++++++++++++++++++++++++------ SoftwareProperties/dialog_sources_list.py | 19 ++-- TODO | 5 +- 4 files changed, 144 insertions(+), 51 deletions(-) (limited to 'SoftwareProperties') diff --git a/SoftwareProperties/SoftwareProperties.py b/SoftwareProperties/SoftwareProperties.py index 0209825d..f6977275 100644 --- a/SoftwareProperties/SoftwareProperties.py +++ b/SoftwareProperties/SoftwareProperties.py @@ -225,13 +225,15 @@ class SoftwareProperties(SimpleGladeApp): self.treeview_sources.set_model(self.source_store) cell_desc = gtk.CellRendererText() - #cell_desc.set_property("xpad", 10) - #cell_desc.set_property("ypad", 10) + cell_desc.set_property("xpad", 2) + cell_desc.set_property("ypad", 2) col_desc = gtk.TreeViewColumn(_("Software Channel"), cell_desc, markup=COLUMN_DESC) - col_desc.set_max_width(500) + col_desc.set_max_width(1000) cell_toggle = gtk.CellRendererToggle() + cell_toggle.set_property("xpad", 2) + cell_toggle.set_property("ypad", 2) cell_toggle.connect('toggled', self.on_channel_toggled) col_active = gtk.TreeViewColumn(_("Active"), cell_toggle, active=COLUMN_ACTIVE) @@ -265,12 +267,7 @@ class SoftwareProperties(SimpleGladeApp): for source in self.sourceslist.list: if source.invalid: continue - (nice_type, nice_dist, nice_comps, special) = self.matcher.match(source) - print "match: %s %s" % (source.dist, special) - - contents = "%s%s" % (nice_dist, nice_comps) - if source.type == "deb-src": - contents = "%s - %s %s" % (nice_dist, nice_type, nice_comps) + contents = self.sourceslist.render_source(source) self.source_store.append([not source.disabled, contents, source]) def reload_keyslist(self): diff --git a/SoftwareProperties/aptsources.py b/SoftwareProperties/aptsources.py index 5f9c6d24..604af097 100644 --- a/SoftwareProperties/aptsources.py +++ b/SoftwareProperties/aptsources.py @@ -236,6 +236,81 @@ class SourcesList: line = line + "\n" self.list.insert(pos, SourceEntry(line)) + def disable_components(self, comps, source_entry): + """Disable components of a source""" + comps_remove = set(comps) & set(source_entry.comps) + if len(comps_remove) >= len(source_entry.comps): + # disable the whole source + source_entry.disabled = True + elif len(comps_remove) > 0: + # Remove the sections from the original source + comps_new = set(source_entry.comps) - comps_remove + comps_write="" + for comp in comps_new: + comps_write += " %s" % comp + line = "%s %s %s %s" % (source.type, source.uri, source.dist, + comps_write) + if source.comment: + line += "# %s" % source.comment + line += "\n" + index = self.list.index(source_entry) + file = self.list[index].file + self.list[index] = SourceEntry(line, file) + + # Add a disabled line with the disabled comps after the + # original line + comps_write="" + for comp in comps_remove: + comps_write = " %s" % comp + line_disabled = "#%s %s %s %s" % (source.type, source.uri, source.dist, + comps_remove) + if source.comment: + line_disabled += "# %s" % source.comment + line_disabled += "\n" + self.list.insert[index+1](SourceEntry(line_disabled, file)) + + def remove_components(self, comps, source_entry): + """ Remove components of a source""" + # The components that need to be removed from the source + comps_remove = set(comps) & set(source_entry.comps) + if len(comps_remove) >= len(source_entry.comps): + # Delete the whole source if there are no comps left + self.list.remove(source_entry) + elif len(comps_remove) > 0: + # Remove the sections from the original source + comps_new = set(source_entry.comps) - comps_remove + comps_write = "" + for comp in comps_new: + comps_write += " %s" % comp + line = "%s %s %s %s" % (source.type, source.uri, source.dist, + comps_write) + if source.comment: + line += "# %s" % source.comment + line += "\n" + index = self.list.index(source_entry) + file = self.list[index].file + self.list[index] = SourceEntry(line, file) + + def render_source(self, source): + """Render a nice output to show the source in a treeview""" + (nice_type, nice_dist, nice_comps, special) = self.matcher.match(source) + + if special in (SOURCE_UPDATES, SOURCE_BACKPORTS, SOURCE_SECURITY): + contents = "%s" % nice_dist + elif special == SOURCE_SYSTEM: + contents = "%s" % nice_dist + if source.type in ("deb-src", "rpm-src"): + contents += " (%s)" % nice_type + for comp in nice_comps: + contents += "\n%s" % comp + else: + contents = "%s" % nice_dist + if source.type in ("deb-src", "rpm-src"): + contents += " (%s)" % nice_type + for comp in nice_comps: + contents += "%s" % comp + return contents + def remove(self, source_entry): self.list.remove(source_entry) @@ -298,7 +373,7 @@ class SourcesList: if source.invalid: continue (nice_type, nice_dist, nice_comps, special) = self.matcher.match(source) - print "match: %s %s" % (source.dist, special) + #print "match: %s %s" % (source.dist, special) # Collect the components of an activated system dist if special == SOURCE_SYSTEM and source.disabled != True: @@ -316,19 +391,18 @@ class SourcesList: elif special == SOURCE_BACKPORTS: self.sources_backports.append(source) - - print "\nSystem Compos: %s " % self.system_comps + #print "\nSystem Compos: %s " % self.system_comps # Check if each security source contains all components of # the same dist - self.add_updates(self.sources_security) - self.add_updates(self.sources_updates) - self.add_updates(self.sources_backports) + self.check_updates(self.sources_security) + self.check_updates(self.sources_updates) + self.check_updates(self.sources_backports) - def add_updates(self, updates): + def check_updates(self, updates): modified = False for source in updates: - print "SecSource: %s" % source.dist + #print "SecSource: %s" % source.dist # Skip the "-security" and "-updates" from the dist i = source.dist.find("-") dist = source.dist[:i] @@ -338,17 +412,28 @@ class SourcesList: comps_sec = set(source.comps) # Are there components without updates? comps_endangered = comps_sys - comps_sec - print "In Danger: %s " % comps_endangered + #print "In Danger: %s " % comps_endangered if len(comps_endangered) > 0: # convert the set into a list - comps_new=[] - for comp in comps_endangered: - comps_new.append(comp) - # add a security source with the additional components - print "Adding updates for %s - %s" % (source.dist, comps_new) - self.add(source.type, source.uri, source.dist, comps_new, - source.comment) + comps_write="" + for comp in comps_sys: + comps_write += " %s" % comp + # add all system components to the securtiy line + line = "%s %s %s %s" % (source.type, source.uri, source.dist, + comps_write) + if source.comment: + line += "# %s" % source.comment + line += "\n" + index = self.list.index(source) + file = self.list[index].file + self.list[index] = SourceEntry(line, file) modified = True + else: + # FIXME: What to do if there are no system sources? + # To disable the security updates would be the best + # option, but what about people with a local mirror + # that fetch sec updates from the ubuntu servers + pass return modified # templates for the add dialog @@ -562,43 +647,52 @@ class SourceEntryMatcher: self.dist_list.append(self.MatchDist(".*debian.org/debian", "^sarge$", _("Debian 3.1 'Sarge'"), - debian_comps, debian_comps_descr)) + debian_comps, debian_comps_descr, + SOURCE_SYSTEM)) self.dist_list.append(self.MatchDist(".*debian.org/debian", "^woody$", _("Debian 3.0 'Woody'"), - debian_comps, debian_comps_descr)) + debian_comps, debian_comps_descr, + SOURCE_SYSTEM)) # securtiy self.dist_list.append(self.MatchDist(".*security.debian.org", "^stable.*$", _("Debian Stable Security Updates"), - debian_comps, debian_comps_descr)) + debian_comps, debian_comps_descr, + SOURCE_SECURITY)) # dists by status self.dist_list.append(self.MatchDist(".*debian.org/debian", "^stable$", _("Debian Stable"), - debian_comps, debian_comps_descr)) + debian_comps, debian_comps_descr, + SOURCE_SYSTEM)) self.dist_list.append(self.MatchDist(".*debian.org/debian", "^testing$", _("Debian Testing"), - debian_comps, debian_comps_descr)) + debian_comps, debian_comps_descr, + SOURCE_SYSTEM)) self.dist_list.append(self.MatchDist(".*debian.org/debian", "^unstable$", _("Debian Unstable 'Sid'"), - debian_comps, debian_comps_descr)) + debian_comps, debian_comps_descr, + SOURCE_SYSTEM)) # non-us self.dist_list.append(self.MatchDist(".*debian.org/debian-non-US", "^stable.*$", _("Debian Non-US (Stable)"), - debian_comps, debian_comps_descr)) + debian_comps, debian_comps_descr, + SOURCE_SYSTEM)) self.dist_list.append(self.MatchDist(".*debian.org/debian-non-US", "^testing.*$", _("Debian Non-US (Testing)"), - debian_comps, debian_comps_descr)) + debian_comps, debian_comps_descr, + SOURCE_SYSTEM)) self.dist_list.append(self.MatchDist(".*debian.org/debian-non-US", "^unstable.*$", _("Debian Non-US (Unstable)"), - debian_comps, debian_comps_descr)) + debian_comps, debian_comps_descr, + SOURCE_SYSTEM)) def match(self,source): _ = gettext.gettext @@ -619,24 +713,24 @@ class SourceEntryMatcher: type_description = _(t.description) break + comp_descriptions = [] 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 = "" + comp_descriptions = [] special = d.special 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] + comp_descriptions.append(d.comps_descriptions[i]) found = True if found == False: - comp_description = comp_description+" "+c + comp_descriptions.append(c) break - - - return (type_description, dist_description, comp_description, special) + + return (type_description, dist_description, comp_descriptions, special) # some simple tests diff --git a/SoftwareProperties/dialog_sources_list.py b/SoftwareProperties/dialog_sources_list.py index 9159d01f..a09542c8 100644 --- a/SoftwareProperties/dialog_sources_list.py +++ b/SoftwareProperties/dialog_sources_list.py @@ -39,6 +39,8 @@ class AddSourcesList: self.store = gtk.ListStore(gobject.TYPE_STRING) self.treeview.set_model(self.store) cell = gtk.CellRendererText() + cell.set_property("xpad", 2) + cell.set_property("ypad", 2) column = gtk.TreeViewColumn("Software Channel", cell, markup=0) column.set_max_width(500) self.treeview.append_column(column) @@ -49,35 +51,31 @@ class AddSourcesList: except: self.error() return - self.matcher = SourceEntryMatcher() # show the found channels or an error message if len(self.sources.list) > 0: self.button_close.hide() - found = False + counter = 0 for source in self.sources.list: if source.invalid or source.disabled: continue - found = True - (a_type, dist, comps) = self.matcher.match(source) - - line = "%s (%s)%s" %\ - (dist, a_type, comps) + counter = counter +1 + line = self.sources.render_source(source) self.store.append([line]) - if found == False: + if counter == 0: self.error() return header = gettext.ngettext("Add the following software channel?", "Add the following software channels?", - len(self.sources.list)) + counter) body = _("You can install software from a channel. Use "\ "trusted channels, only.") self.label.set_markup("%s\n\n%s" % (header, body)) self.button_add.set_use_underline(True) self.button_add.set_label(gettext.ngettext("_Add Channel", "_Add Channels", - len(self.sources.list))) + counter)) else: self.error() return @@ -118,5 +116,6 @@ class AddSourcesList: class SingleSourcesList(SourcesList): def __init__(self, file): + self.matcher = SourceEntryMatcher() self.list = [] self.load(file) diff --git a/TODO b/TODO index 2a1d3928..4f225357 100644 --- a/TODO +++ b/TODO @@ -3,4 +3,7 @@ - add download size to treeview - add /etc/apt/software-properties.d dir where the user can install matchers and templates -- handle cases like "deb http://bla/ dist sec1 sec2 # comment" \ No newline at end of file +- handle cases like "deb http://bla/ dist sec1 sec2 # comment" +- rework the add channel/cdrom dialogs +- d'n'd for key files +- use one line per section and not one per channel in the treeview -- cgit v1.2.3 From 52c686391e543bbc1084ec15f40abe8e58b1d514 Mon Sep 17 00:00:00 2001 From: Sebastian Heinlein Date: Fri, 24 Feb 2006 18:16:52 +0100 Subject: * Remove all obsolete backup files before backup --- SoftwareProperties/SoftwareProperties.py | 1 + SoftwareProperties/aptsources.py | 12 ++++++++++++ 2 files changed, 13 insertions(+) (limited to 'SoftwareProperties') diff --git a/SoftwareProperties/SoftwareProperties.py b/SoftwareProperties/SoftwareProperties.py index f6977275..250e2c1d 100644 --- a/SoftwareProperties/SoftwareProperties.py +++ b/SoftwareProperties/SoftwareProperties.py @@ -377,6 +377,7 @@ class SoftwareProperties(SimpleGladeApp): def save_sourceslist(self): #location = "/etc/apt/sources.list" #shutil.copy(location, location + ".save") + self.sourceslist.clearBackup(".save") self.sourceslist.backup(".save") self.sourceslist.save() diff --git a/SoftwareProperties/aptsources.py b/SoftwareProperties/aptsources.py index 604af097..397ebb38 100644 --- a/SoftwareProperties/aptsources.py +++ b/SoftwareProperties/aptsources.py @@ -314,6 +314,18 @@ class SourcesList: def remove(self, source_entry): self.list.remove(source_entry) + def clearBackup(self, backup_ext): + " remove backuped sources.list files based on the backup extension " + dir = apt_pkg.Config.FindDir("Dir::Etc") + file = apt_pkg.Config.Find("Dir::Etc::sourcelist") + if os.path.exists(dir+file+backup_ext): + os.remove(dir+file+backup_ext) + # now sources.list.d + partsdir = apt_pkg.Config.FindDir("Dir::Etc::sourceparts") + for file in glob.glob("%s/*.list" % partsdir): + if os.path.exists(file+backup_ext): + os.remove(file+backup_ext) + def restoreBackup(self, backup_ext): " restore sources.list files based on the backup extension " dir = apt_pkg.Config.FindDir("Dir::Etc") -- cgit v1.2.3 From 9184e9d648fb8ff3f8a437817cb67d5cf17e2010 Mon Sep 17 00:00:00 2001 From: Sebastian Heinlein Date: Sun, 26 Feb 2006 09:26:33 +0100 Subject: * Use the dist name from lsbrelease in the add channel dialog --- SoftwareProperties/aptsources.py | 4 +++- SoftwareProperties/dialog_add.py | 6 ++++++ UpdateManager/Common/DistInfo.py | 5 ++++- data/SoftwarePropertiesDialogs.glade | 6 +++--- 4 files changed, 16 insertions(+), 5 deletions(-) (limited to 'SoftwareProperties') diff --git a/SoftwareProperties/aptsources.py b/SoftwareProperties/aptsources.py index 397ebb38..532600fd 100644 --- a/SoftwareProperties/aptsources.py +++ b/SoftwareProperties/aptsources.py @@ -450,7 +450,7 @@ class SourcesList: # templates for the add dialog class SourceEntryTemplate(SourceEntry): - def __init__(self,a_type,uri,dist,description,comps): + def __init__(self, a_type, uri, dist, description, comps): self.comps = [] self.comps_descriptions = [] self.type = a_type @@ -472,6 +472,8 @@ class SourceEntryTemplates: dinfo = DistInfo (base_dir=datadir+"channels/") + self.dist = dinfo.dist + for suite in dinfo.suites: comps = [] for comp in suite.components: diff --git a/SoftwareProperties/dialog_add.py b/SoftwareProperties/dialog_add.py index effd9f24..8ccd2080 100644 --- a/SoftwareProperties/dialog_add.py +++ b/SoftwareProperties/dialog_add.py @@ -26,6 +26,7 @@ import os import gobject import gtk import gtk.glade +from gettext import gettext as _ import aptsources @@ -52,6 +53,11 @@ class dialog_add: self.combo.pack_start(cell, True) self.combo.add_attribute(cell, 'text', 0) self.fill_combo(self.combo) + self.label_dist = self.gladexml.get_widget("label_dist") + if self.templatelist.dist != "": + # TRANSLATORS: %s is the distribution name, eg. Ubuntu or Debian + self.label_dist.set_markup("%s" % \ + _("%s channels" % self.templatelist.dist)) # Setup the custom channel widgets self.entry = self.gladexml.get_widget("entry_source_line") diff --git a/UpdateManager/Common/DistInfo.py b/UpdateManager/Common/DistInfo.py index df244a51..102b981c 100644 --- a/UpdateManager/Common/DistInfo.py +++ b/UpdateManager/Common/DistInfo.py @@ -22,6 +22,7 @@ import os import gettext +from os import getenv import ConfigParser _ = gettext.gettext @@ -51,6 +52,8 @@ class DistInfo: pipe.close() del pipe + self.dist = dist + dist_fname = "%s/%s.info" % (base_dir, dist) dist_file = open (dist_fname) if not dist_file: @@ -100,7 +103,7 @@ class DistInfo: if __name__ == "__main__": - d = DistInfo ("Debian", "../distribution-data") + d = DistInfo ("Debian", "../../channels") print d.changelogs_uri for suite in d.suites: print suite.name diff --git a/data/SoftwarePropertiesDialogs.glade b/data/SoftwarePropertiesDialogs.glade index 3e4be82f..175d152b 100644 --- a/data/SoftwarePropertiesDialogs.glade +++ b/data/SoftwarePropertiesDialogs.glade @@ -92,9 +92,9 @@ - + True - <b>Official Ubuntu Channel</b> + False True GTK_JUSTIFY_LEFT @@ -247,7 +247,7 @@ True - <b>Custom Channel</b> + <b>Custom channel</b> False True GTK_JUSTIFY_LEFT -- cgit v1.2.3 From 41b33ac46f0226b756c8547513404d62449715bf Mon Sep 17 00:00:00 2001 From: Sebastian Heinlein Date: Sun, 26 Feb 2006 13:26:11 +0100 Subject: * Add a button revert and make the channel list instant apply * Reorder the buttons on the key view to correspond with the channel view --- SoftwareProperties/SoftwareProperties.py | 65 ++++++-- data/SoftwareProperties.glade | 274 +++++++++++++++++-------------- 2 files changed, 201 insertions(+), 138 deletions(-) (limited to 'SoftwareProperties') diff --git a/SoftwareProperties/SoftwareProperties.py b/SoftwareProperties/SoftwareProperties.py index 250e2c1d..f7f7f6f2 100644 --- a/SoftwareProperties/SoftwareProperties.py +++ b/SoftwareProperties/SoftwareProperties.py @@ -91,6 +91,7 @@ class SoftwareProperties(SimpleGladeApp): self.init_sourceslist() self.reload_sourceslist() + self.button_revert.set_sensitive(False) # internet update setings @@ -179,6 +180,10 @@ class SoftwareProperties(SimpleGladeApp): else: self.checkbutton_unattended.set_active(False) + # Backup the source list + self.sourceslist.clearBackup(".save") + self.sourceslist.backup(".save") + # apt-key stuff self.apt_key = apt_key() self.init_keyslist() @@ -204,8 +209,7 @@ class SoftwareProperties(SimpleGladeApp): file) res = dialog.run() if res == gtk.RESPONSE_OK: - self.reload_sourceslist() - self.modified = True + self.modified_sourceslist() def on_sources_drag_data_received(self, widget, context, x, y, selection, target_type, timestamp): @@ -244,13 +248,27 @@ class SoftwareProperties(SimpleGladeApp): self.sourceslist = aptsources.SourcesList() self.matcher = aptsources.SourceEntryMatcher() + def on_channel_activate(self, treeview, path, column): + """Open the edit dialog if a channel was double clicked""" + self.on_edit_clicked(treeview) + + def on_treeview_sources_cursor_changed(self, treeview): + """Enable the buttons remove and edit if a channel is selected""" + sel = self.treeview_sources.get_selection() + (model, iter) = sel.get_selected() + if iter: + self.button_edit.set_sensitive(True) + self.button_remove.set_sensitive(True) + else: + self.button_edit.set_sensitive(False) + self.button_remove.set_sensitive(False) + def on_channel_toggled(self, cell_toggle, path): """Enable or disable the selected channel""" iter = self.source_store.get_iter((int(path),)) source_entry = self.source_store.get_value(iter, LIST_ENTRY_OBJ) source_entry.disabled = not source_entry.disabled - self.reload_sourceslist() - self.modified = True + self.modified_sourceslist() def init_keyslist(self): self.keys_store = gtk.ListStore(str) @@ -261,6 +279,21 @@ class SoftwareProperties(SimpleGladeApp): keys_col = gtk.TreeViewColumn("Key", tr, text=0) self.treeview2.append_column(keys_col) + def on_button_revert_clicked(self, button): + """Restore the source list from the startup of the dialog""" + self.sourceslist.restoreBackup(".save") + self.sourceslist.clearBackup(".save") + self.sourceslist.backup(".save") + self.sourceslist.refresh() + self.reload_sourceslist() + self.button_revert.set_sensitive(False) + + def modified_sourceslist(self): + """The sources list was changed and now needs to be saved and reloaded""" + self.button_revert.set_sensitive(True) + self.save_sourceslist() + self.reload_sourceslist() + def reload_sourceslist(self): self.source_store.clear() self.sourceslist.check_for_endangered_dists() @@ -377,18 +410,17 @@ class SoftwareProperties(SimpleGladeApp): def save_sourceslist(self): #location = "/etc/apt/sources.list" #shutil.copy(location, location + ".save") - self.sourceslist.clearBackup(".save") - self.sourceslist.backup(".save") self.sourceslist.save() - + def on_add_clicked(self, widget): + """Open a dialog to add new channels""" dialog = dialog_add.dialog_add(self.window_main, self.sourceslist, self.datadir) if dialog.run() == gtk.RESPONSE_OK: - self.reload_sourceslist() - self.modified = True - + self.modified_sourceslist() + def on_edit_clicked(self, widget): + """Open a dialog to edit the currently selected dialog""" sel = self.treeview_sources.get_selection() (model, iter) = sel.get_selected() if not iter: @@ -397,17 +429,17 @@ class SoftwareProperties(SimpleGladeApp): dialog = dialog_edit.dialog_edit(self.window_main, self.sourceslist, source_entry, self.datadir) if dialog.run() == gtk.RESPONSE_OK: - self.reload_sourceslist() - self.modified = True - + self.modified_sourceslist() + def on_remove_clicked(self, widget): sel = self.treeview_sources.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 + self.modified_sourceslist() + self.button_edit.set_sensitive(False) + self.button_remove.set_sensitive(False) def add_key_clicked(self, widget): chooser = gtk.FileChooserDialog(title=_("Import key"), @@ -492,8 +524,7 @@ class SoftwareProperties(SimpleGladeApp): if line != "": full_path = "%s%s" % (apt_pkg.Config.FindDir("Dir::Etc"),saved_entry) self.sourceslist.list.append(aptsources.SourceEntry(line,full_path)) - self.reload_sourceslist() - self.modified = True + self.modified_sourceslist() # FIXME: move this into a different file diff --git a/data/SoftwareProperties.glade b/data/SoftwareProperties.glade index 27f53404..9a5edbeb 100644 --- a/data/SoftwareProperties.glade +++ b/data/SoftwareProperties.glade @@ -5,7 +5,6 @@ 6 - 580 400 True Software Preferences @@ -93,6 +92,8 @@ False False False + + @@ -107,135 +108,167 @@ True False - 6 + 12 - + True - True - True - gtk-add - True - GTK_RELIEF_NORMAL - True - - - - 0 - False - False - - - - - - True - True - True - gtk-remove - True - GTK_RELIEF_NORMAL - True - - - - 0 - False - False - - - - - - True - True - True - gtk-edit - True - GTK_RELIEF_NORMAL - True - - - - 0 - False - False - - + False + 6 - - - True - True - True - GTK_RELIEF_NORMAL - True - + + + True + True + True + gtk-add + True + GTK_RELIEF_NORMAL + True + + + + 0 + False + False + + - + True - 0.5 - 0.5 - 0 - 0 - 0 - 0 - 0 - 0 + True + True + GTK_RELIEF_NORMAL + True + - + True - False - 2 + 0.5 + 0.5 + 0 + 0 + 0 + 0 + 0 + 0 - + True - gtk-cdrom - 4 - 0.5 - 0.5 - 0 - 0 + False + 2 + + + + True + gtk-cdrom + 4 + 0.5 + 0.5 + 0 + 0 + + + 0 + False + False + + + + + + True + Add _Cdrom + True + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + - - 0 - False - False - - - - - - True - Add _Cdrom - True - False - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - False - False - + + 0 + False + False + + + + + + True + False + True + True + gtk-remove + True + GTK_RELIEF_NORMAL + True + + + + 0 + False + False + + + + + + True + False + True + True + gtk-edit + True + GTK_RELIEF_NORMAL + True + + + + 0 + False + False + + + 0 + True + True + + + + + + True + True + gtk-revert-to-saved + True + GTK_RELIEF_NORMAL + True + + 0 False @@ -608,43 +641,42 @@ 0 False False + GTK_PACK_END - + True + Import the public key from a trusted software provider True - gtk-remove - True + _Import Key File + True GTK_RELIEF_NORMAL True - + 0 False False - GTK_PACK_END - + True - Import the public key from a trusted software provider True - _Import Key File - True + gtk-remove + True GTK_RELIEF_NORMAL True - + 0 False False - GTK_PACK_END -- cgit v1.2.3 From a47225de2eb2809aec10b2d7c260963f0ab0a91b Mon Sep 17 00:00:00 2001 From: Sebastian Heinlein Date: Sun, 26 Feb 2006 14:21:08 +0100 Subject: * Only enable the button add in the dialog add channel if a comp is selected --- SoftwareProperties/dialog_add.py | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) (limited to 'SoftwareProperties') diff --git a/SoftwareProperties/dialog_add.py b/SoftwareProperties/dialog_add.py index 8ccd2080..a1ac713b 100644 --- a/SoftwareProperties/dialog_add.py +++ b/SoftwareProperties/dialog_add.py @@ -45,7 +45,9 @@ class dialog_add: self.main = widget = self.gladexml.get_widget("dialog_add") self.main.set_transient_for(self.parent) - + + self.vbox = self.gladexml.get_widget("vbox_comps") + # Setup the official channel widgets self.combo = self.gladexml.get_widget("combobox_what") self.gladexml.signal_connect("on_combobox_what_changed", self.on_combobox_what_changed, None) @@ -102,7 +104,7 @@ class dialog_add: for check in self.comps: check.set_sensitive(state) self.official = state - self.button_add.set_sensitive(state) + self.count_comps() def fill_combo(self,combo): liststore = gtk.ListStore(gobject.TYPE_STRING,gobject.TYPE_PYOBJECT) @@ -113,8 +115,7 @@ class dialog_add: 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) + self.vbox.foreach(lambda widget,vbox: self.vbox.remove(widget), self.vbox) liststore = combobox.get_model() a_iter = liststore.iter_nth_child(None, combobox.get_active()) (name, template) = liststore.get(a_iter, 0,1) @@ -125,22 +126,31 @@ class dialog_add: checkbox = gtk.CheckButton(c.description) checkbox.set_active(c.on_by_default) checkbox.set_data("name",c.name) - vbox.pack_start(checkbox) + checkbox.connect("toggled", self.count_comps) + self.vbox.pack_start(checkbox) checkbox.show() self.comps.append(checkbox) + self.count_comps() def get_enabled_comps(self, checkbutton): if checkbutton.get_active(): self.selected_comps.append(checkbutton.get_data("name")) + def count_comps(self, *args): + button_add = self.gladexml.get_widget("button_add_channel") + self.selected_comps=[] + self.vbox.foreach(self.get_enabled_comps) + if len(self.selected_comps) > 0: + button_add.set_sensitive(True) + else: + button_add.set_sensitive(False) + def run(self): res = self.main.run() if res == gtk.RESPONSE_OK: # add repository if self.official == True: 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, -- cgit v1.2.3 From 97a21a72b7ae7e0cd0bba858655ae9110e96644d Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 27 Feb 2006 12:18:02 +0100 Subject: * SoftwareProperties/SoftwareProperties.py: - moved render_source() from aptsources.py here - if a endangered dist is added, show a revert button * channels/Ubuntu.info.in: - added security and updates --- SoftwareProperties/SoftwareProperties.py | 35 ++++++++++++++++++++++++++----- SoftwareProperties/aptsources.py | 28 +++++-------------------- SoftwareProperties/dialog_sources_list.py | 6 ++++-- SoftwareProperties/utils.py | 2 ++ channels/Ubuntu.info.in | 28 ++++++++++++------------- 5 files changed, 55 insertions(+), 44 deletions(-) (limited to 'SoftwareProperties') diff --git a/SoftwareProperties/SoftwareProperties.py b/SoftwareProperties/SoftwareProperties.py index f7f7f6f2..d5070240 100644 --- a/SoftwareProperties/SoftwareProperties.py +++ b/SoftwareProperties/SoftwareProperties.py @@ -88,10 +88,10 @@ class SoftwareProperties(SimpleGladeApp): if options and options.toplevel != None: toplevel = gtk.gdk.window_foreign_new(int(options.toplevel)) self.window_main.window.set_transient_for(toplevel) - + + self.button_revert.set_sensitive(False) self.init_sourceslist() self.reload_sourceslist() - self.button_revert.set_sensitive(False) # internet update setings @@ -203,8 +203,9 @@ class SoftwareProperties(SimpleGladeApp): def open_file(self, file): """Show an confirmation for adding the channels of the specified file""" - dialog = dialog_sources_list.AddSourcesList(self.window_main, + dialog = dialog_sources_list.AddSourcesList(self.window_main, self.sourceslist, + self.render_source, self.datadir, file) res = dialog.run() @@ -294,13 +295,37 @@ class SoftwareProperties(SimpleGladeApp): self.save_sourceslist() self.reload_sourceslist() + def render_source(self, source): + """Render a nice output to show the source in a treeview""" + (nice_type, nice_dist, nice_comps, special) = self.matcher.match(source) + + if special in (aptsources.SOURCE_UPDATES, + aptsources.SOURCE_BACKPORTS, + aptsources.SOURCE_SECURITY): + contents = "%s" % nice_dist + elif special == aptsources.SOURCE_SYSTEM: + contents = "%s" % nice_dist + if source.type in ("deb-src", "rpm-src"): + contents += " (%s)" % nice_type + for comp in nice_comps: + contents += "\n%s" % comp + else: + contents = "%s" % nice_dist + if source.type in ("deb-src", "rpm-src"): + contents += " (%s)" % nice_type + for comp in nice_comps: + contents += "%s" % comp + return contents + def reload_sourceslist(self): self.source_store.clear() - self.sourceslist.check_for_endangered_dists() + if self.sourceslist.check_for_endangered_dists(): + self.button_revert.set_sensitive(True) + self.save_sourceslist() for source in self.sourceslist.list: if source.invalid: continue - contents = self.sourceslist.render_source(source) + contents = self.render_source(source) self.source_store.append([not source.disabled, contents, source]) def reload_keyslist(self): diff --git a/SoftwareProperties/aptsources.py b/SoftwareProperties/aptsources.py index 532600fd..0340e211 100644 --- a/SoftwareProperties/aptsources.py +++ b/SoftwareProperties/aptsources.py @@ -291,26 +291,6 @@ class SourcesList: file = self.list[index].file self.list[index] = SourceEntry(line, file) - def render_source(self, source): - """Render a nice output to show the source in a treeview""" - (nice_type, nice_dist, nice_comps, special) = self.matcher.match(source) - - if special in (SOURCE_UPDATES, SOURCE_BACKPORTS, SOURCE_SECURITY): - contents = "%s" % nice_dist - elif special == SOURCE_SYSTEM: - contents = "%s" % nice_dist - if source.type in ("deb-src", "rpm-src"): - contents += " (%s)" % nice_type - for comp in nice_comps: - contents += "\n%s" % comp - else: - contents = "%s" % nice_dist - if source.type in ("deb-src", "rpm-src"): - contents += " (%s)" % nice_type - for comp in nice_comps: - contents += "%s" % comp - return contents - def remove(self, source_entry): self.list.remove(source_entry) @@ -407,9 +387,11 @@ class SourcesList: # Check if each security source contains all components of # the same dist - self.check_updates(self.sources_security) - self.check_updates(self.sources_updates) - self.check_updates(self.sources_backports) + res = False + res |= self.check_updates(self.sources_security) + res |= self.check_updates(self.sources_updates) + res |= self.check_updates(self.sources_backports) + return res def check_updates(self, updates): modified = False diff --git a/SoftwareProperties/dialog_sources_list.py b/SoftwareProperties/dialog_sources_list.py index a09542c8..d35b9b51 100644 --- a/SoftwareProperties/dialog_sources_list.py +++ b/SoftwareProperties/dialog_sources_list.py @@ -9,11 +9,13 @@ from aptsources import SourcesList, SourceEntryMatcher from gettext import gettext as _ import gettext import urllib +from utils import * class AddSourcesList: - def __init__(self, parent, sourceslist, datadir, file): + def __init__(self, parent, sourceslist, source_renderer, datadir, file): print file self.parent = parent + self.source_renderer = source_renderer self.sources_old = sourceslist self.file = self.format_uri(file) self.glade = gtk.glade.XML(os.path.join(datadir, @@ -60,7 +62,7 @@ class AddSourcesList: if source.invalid or source.disabled: continue counter = counter +1 - line = self.sources.render_source(source) + line = self.source_renderer(source) self.store.append([line]) if counter == 0: self.error() diff --git a/SoftwareProperties/utils.py b/SoftwareProperties/utils.py index cf9a3343..2886507f 100644 --- a/SoftwareProperties/utils.py +++ b/SoftwareProperties/utils.py @@ -1,5 +1,7 @@ import gtk + + def dialog_error(parent, primary, secondary): p = "%s" % primary dialog = gtk.MessageDialog(parent,gtk.DIALOG_MODAL, diff --git a/channels/Ubuntu.info.in b/channels/Ubuntu.info.in index 00ccbfe4..f3316390 100644 --- a/channels/Ubuntu.info.in +++ b/channels/Ubuntu.info.in @@ -17,10 +17,10 @@ Component: multiverse Enabled: 0 _CompDescription: Non-free (Multiverse) -Suite: breezy +Suite: dapper-security RepositoryType: deb -BaseURI: http://archive.ubuntu.com/ubuntu/ -_Description: Ubuntu 5.10 'Breezy Badger' +BaseURI: http://security.ubuntu.com/ubuntu/ +_Description: Ubuntu 6.04 Security Updates Component: main Enabled: 1 _CompDescription: Oficially supported @@ -34,10 +34,10 @@ Component: multiverse Enabled: 0 _CompDescription: Non-free (Multiverse) -Suite: breezy-security +Suite: dapper-updates RepositoryType: deb -BaseURI: http://security.ubuntu.com/ubuntu/ -_Description: Ubuntu 5.10 Security Updates +BaseURI: http://archive.ubuntu.com/ubuntu/ +_Description: Ubuntu 6.04 Updates Component: main Enabled: 1 _CompDescription: Oficially supported @@ -51,10 +51,10 @@ Component: multiverse Enabled: 0 _CompDescription: Non-free (Multiverse) -Suite: breezy-updates +Suite: breezy RepositoryType: deb BaseURI: http://archive.ubuntu.com/ubuntu/ -_Description: Ubuntu 5.10 Updates +_Description: Ubuntu 5.10 'Breezy Badger' Component: main Enabled: 1 _CompDescription: Oficially supported @@ -68,10 +68,10 @@ Component: multiverse Enabled: 0 _CompDescription: Non-free (Multiverse) -Suite: hoary +Suite: breezy-security RepositoryType: deb -BaseURI: http://archive.ubuntu.com/ubuntu/ -_Description: Ubuntu 5.04 'Hoary Hedgehog' +BaseURI: http://security.ubuntu.com/ubuntu/ +_Description: Ubuntu 5.10 Security Updates Component: main Enabled: 1 _CompDescription: Oficially supported @@ -85,10 +85,10 @@ Component: multiverse Enabled: 0 _CompDescription: Non-free (Multiverse) -Suite: hoary-security +Suite: breezy-updates RepositoryType: deb -BaseURI: http://security.ubuntu.com/ubuntu/ -_Description: Ubuntu 5.04 Security Updates +BaseURI: http://archive.ubuntu.com/ubuntu/ +_Description: Ubuntu 5.10 Updates Component: main Enabled: 1 _CompDescription: Oficially supported -- cgit v1.2.3 From 979d4cafb3d30920b95dfaf26e204bda408d4591 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 27 Feb 2006 15:16:55 +0100 Subject: * Typos --- DistUpgrade/DistUpgradeView.py | 6 +++--- SoftwareProperties/SoftwareProperties.py | 2 +- data/SoftwareProperties.glade | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'SoftwareProperties') diff --git a/DistUpgrade/DistUpgradeView.py b/DistUpgrade/DistUpgradeView.py index 4c9103ba..8e9a3d3f 100644 --- a/DistUpgrade/DistUpgradeView.py +++ b/DistUpgrade/DistUpgradeView.py @@ -65,9 +65,9 @@ class DistUpgradeView(object): def confirmRestart(self): " generic ask about the restart, can be overriden " summary = _("Reboot required") - msg = _("The upgrade is finished now. " - "A reboot is required to " - "now, do you want to do this " + msg = _("The upgrade is finished and " + "a reboot is required. " + "Do you want to do this " "now?") return self.askYesNoQuestion(summary, msg) def error(self, summary, msg, extended_msg=None): diff --git a/SoftwareProperties/SoftwareProperties.py b/SoftwareProperties/SoftwareProperties.py index d5070240..99ec292f 100644 --- a/SoftwareProperties/SoftwareProperties.py +++ b/SoftwareProperties/SoftwareProperties.py @@ -534,7 +534,7 @@ class SoftwareProperties(SimpleGladeApp): type=gtk.MESSAGE_ERROR, buttons=gtk.BUTTONS_OK, message_format=None) - dialog.set_markup(_("Error scaning the CD\n\n%s"%msg)) + dialog.set_markup(_("Error scanning the CD\n\n%s"%msg)) res = dialog.run() dialog.destroy() return diff --git a/data/SoftwareProperties.glade b/data/SoftwareProperties.glade index 9a5edbeb..5e5c2b7a 100644 --- a/data/SoftwareProperties.glade +++ b/data/SoftwareProperties.glade @@ -424,7 +424,7 @@ True True - _Download updates in the backgound, but do not install them + _Download updates in the background, but do not install them True GTK_RELIEF_NORMAL True -- cgit v1.2.3 From 77b2f46a4079c35ca7a5fc4ff2bb80d57e3ba024 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 27 Feb 2006 16:02:35 +0100 Subject: * show the already enabled components for a given dist if "add" is clicked --- SoftwareProperties/aptsources.py | 2 +- SoftwareProperties/dialog_add.py | 19 +++++++++++++++++-- 2 files changed, 18 insertions(+), 3 deletions(-) (limited to 'SoftwareProperties') diff --git a/SoftwareProperties/aptsources.py b/SoftwareProperties/aptsources.py index 0340e211..0546ef0a 100644 --- a/SoftwareProperties/aptsources.py +++ b/SoftwareProperties/aptsources.py @@ -448,7 +448,7 @@ class SourceCompTemplate: self.on_by_default = on_by_default class SourceEntryTemplates: - def __init__(self,datadir): + def __init__(self, datadir): _ = gettext.gettext self.templates = [] diff --git a/SoftwareProperties/dialog_add.py b/SoftwareProperties/dialog_add.py index a1ac713b..05737769 100644 --- a/SoftwareProperties/dialog_add.py +++ b/SoftwareProperties/dialog_add.py @@ -120,11 +120,26 @@ class dialog_add: a_iter = liststore.iter_nth_child(None, combobox.get_active()) (name, template) = liststore.get(a_iter, 0,1) self.selected = template + + # figure what is currently active in the sources.list + already_enabled_comps = [] + for entry in self.sourceslist: + if entry.disabled or entry.invalid or entry.type != "deb": + continue + if template.dist == entry.dist and \ + self.sourceslist.is_mirror(template.uri, entry.uri): + already_enabled_comps = entry.comps + comps = template.comps self.comps=[] for c in comps: checkbox = gtk.CheckButton(c.description) - checkbox.set_active(c.on_by_default) + # show what should be enabled by default if the source was not found + # else show the already enabled ones + if len(already_enabled_comps) == 0: + checkbox.set_active(c.on_by_default) + else: + checkbox.set_active(c.name in already_enabled_comps) checkbox.set_data("name",c.name) checkbox.connect("toggled", self.count_comps) self.vbox.pack_start(checkbox) @@ -150,7 +165,7 @@ class dialog_add: if res == gtk.RESPONSE_OK: # add repository if self.official == True: - self.selected_comps = [] + #self.selected_comps = [] self.sourceslist.add(self.selected.type, self.selected.uri, self.selected.dist, -- cgit v1.2.3 From 160dcc7d66fb94b95932b81787358d3a1b615412 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 27 Feb 2006 17:56:31 +0100 Subject: * don't hide the details for the security upgrades yet --- SoftwareProperties/SoftwareProperties.py | 20 +++++++++++++------- SoftwareProperties/aptsources.py | 4 ++-- debian/changelog | 4 +++- 3 files changed, 18 insertions(+), 10 deletions(-) (limited to 'SoftwareProperties') diff --git a/SoftwareProperties/SoftwareProperties.py b/SoftwareProperties/SoftwareProperties.py index 99ec292f..1c6963a0 100644 --- a/SoftwareProperties/SoftwareProperties.py +++ b/SoftwareProperties/SoftwareProperties.py @@ -299,11 +299,16 @@ class SoftwareProperties(SimpleGladeApp): """Render a nice output to show the source in a treeview""" (nice_type, nice_dist, nice_comps, special) = self.matcher.match(source) + # FIXME: add this back when it's more consistent + #if special in (aptsources.SOURCE_UPDATES, + # aptsources.SOURCE_BACKPORTS, + # aptsources.SOURCE_SECURITY): + # contents = "%s" % nice_dist + #elif special == aptsources.SOURCE_SYSTEM: if special in (aptsources.SOURCE_UPDATES, - aptsources.SOURCE_BACKPORTS, - aptsources.SOURCE_SECURITY): - contents = "%s" % nice_dist - elif special == aptsources.SOURCE_SYSTEM: + aptsources.SOURCE_BACKPORTS, + aptsources.SOURCE_SECURITY, + aptsources.SOURCE_SYSTEM): contents = "%s" % nice_dist if source.type in ("deb-src", "rpm-src"): contents += " (%s)" % nice_type @@ -319,9 +324,10 @@ class SoftwareProperties(SimpleGladeApp): def reload_sourceslist(self): self.source_store.clear() - if self.sourceslist.check_for_endangered_dists(): - self.button_revert.set_sensitive(True) - self.save_sourceslist() + # FIXME: this happens with way too much magic, we need to either + # ask the user or provide a different way to present this + # )maybe some sort of configuration is enough?) + self.sourceslist.check_for_endangered_dists() for source in self.sourceslist.list: if source.invalid: continue diff --git a/SoftwareProperties/aptsources.py b/SoftwareProperties/aptsources.py index 0546ef0a..820e6e77 100644 --- a/SoftwareProperties/aptsources.py +++ b/SoftwareProperties/aptsources.py @@ -362,7 +362,7 @@ class SourcesList: self.matcher = SourceEntryMatcher() for source in self.list: - if source.invalid: + if source.invalid or source.type != "deb": continue (nice_type, nice_dist, nice_comps, special) = self.matcher.match(source) #print "match: %s %s" % (source.dist, special) @@ -406,7 +406,7 @@ class SourcesList: comps_sec = set(source.comps) # Are there components without updates? comps_endangered = comps_sys - comps_sec - #print "In Danger: %s " % comps_endangered + #print "In Danger: %s - %s = %s " % (comps_sys, comps_sec, comps_endangered) if len(comps_endangered) > 0: # convert the set into a list comps_write="" diff --git a/debian/changelog b/debian/changelog index 50eb7a1c..e5c87e50 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,6 +1,8 @@ update-manager (0.42.2ubuntu6) dapper; urgency=low - * SoftwareProperties/*: fix some UI problems (thanks to Sebastian Heinlein) + * SoftwareProperties/: + - fix some UI problems (thanks to Sebastian Heinlein) + - add breezy-updates, breezy-security to the Add dialog * po/pt_BR.po: updated translation (thanks to Carlos Eduardo Pedroza Santiviago) * po/pt.po: updated Portugise translation (thanks to Rui Azevedo) -- cgit v1.2.3 From 4a1c03022c92d3c477c333c1592c888cf216b19d Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 27 Feb 2006 18:37:25 +0100 Subject: * UpdateManager/MetaRelease.py, DistUpgradeFetcher: - make the authentication work reliable * DistUpgrade/DistUpgradeViewGtk.py: - exit on fatal uncaught exceptions * SoftwareProperties/SoftwareProperties.py: - fix a indent error when adding gpg keys --- DistUpgrade/DistUpgradeViewGtk.py | 1 + SoftwareProperties/SoftwareProperties.py | 2 +- UpdateManager/DistUpgradeFetcher.py | 48 +++++++++++++++++++++++--------- UpdateManager/MetaRelease.py | 8 ++++-- 4 files changed, 43 insertions(+), 16 deletions(-) (limited to 'SoftwareProperties') diff --git a/DistUpgrade/DistUpgradeViewGtk.py b/DistUpgrade/DistUpgradeViewGtk.py index 7298b31e..2f7e3fed 100644 --- a/DistUpgrade/DistUpgradeViewGtk.py +++ b/DistUpgrade/DistUpgradeViewGtk.py @@ -230,6 +230,7 @@ class DistUpgradeViewGtk(DistUpgradeView,SimpleGladeApp): "files ~/dist-upgrade.log and ~/dist-upgrade-apt.log " "in your report. The upgrade aborts now. "), "\n".join(lines)) + sys.exit(1) def create_terminal(self, arg1,arg2,arg3,arg4): " helper to create a vte terminal " diff --git a/SoftwareProperties/SoftwareProperties.py b/SoftwareProperties/SoftwareProperties.py index 1c6963a0..0e892182 100644 --- a/SoftwareProperties/SoftwareProperties.py +++ b/SoftwareProperties/SoftwareProperties.py @@ -486,7 +486,7 @@ class SoftwareProperties(SimpleGladeApp): _("Error importing selected file"), _("The selected file may not be a GPG key file " \ "or it might be corrupt.")) - self.reload_keyslist() + self.reload_keyslist() def remove_key_clicked(self, widget): selection = self.treeview2.get_selection() diff --git a/UpdateManager/DistUpgradeFetcher.py b/UpdateManager/DistUpgradeFetcher.py index 7af32865..676f064b 100644 --- a/UpdateManager/DistUpgradeFetcher.py +++ b/UpdateManager/DistUpgradeFetcher.py @@ -91,7 +91,19 @@ class DistUpgradeFetcher(object): return False return True - def authenticate(self, file, signature, keyring='/etc/apt/trusted.gpg'): + def authenticate(self): + if self.new_dist.upgradeToolSig: + f = self.tmpdir+"/"+os.path.basename(self.new_dist.upgradeTool) + sig = self.tmpdir+"/"+os.path.basename(self.new_dist.upgradeToolSig) + print "authenticate '%s' against '%s' " % (f,sig) + if not self.gpgauthenticate(f, sig): + return False + + # we may return False here by default if we want to make a sig + # mandatory + return True + + def gpgauthenticate(self, file, signature, keyring='/etc/apt/trusted.gpg'): """ authenticated a file against a given signature, if no keyring is given use the apt default keyring """ @@ -101,6 +113,7 @@ class DistUpgradeFetcher(object): proc = gpg.run(['--verify', signature, file], create_fhs=['status','logger','stderr']) gpgres = proc.handles['status'].read() + proc.wait() if "VALIDSIG" in gpgres: return True return False @@ -140,23 +153,32 @@ class DistUpgradeFetcher(object): # now download the tarball with the upgrade script self.tmpdir = tmpdir = tempfile.mkdtemp() os.chdir(tmpdir) + + # turn debugging on here (if required) + #apt_pkg.Config.Set("Debug::Acquire::http","1") + + progress = GtkProgress.GtkFetchProgress(self.parent, + _("Downloading the upgrade " + "tool"), + _("The upgrade tool will " + "guide you through the " + "upgrade process.")) + fetcher = apt_pkg.GetAcquire(progress) + + if self.new_dist.upgradeToolSig != None: + uri = self.new_dist.upgradeToolSig + af = apt_pkg.GetPkgAcqFile(fetcher,uri, descr=_("Upgrade tool signature")) if self.new_dist.upgradeTool != None: - progress = GtkProgress.GtkFetchProgress(self.parent, - _("Downloading the upgrade " - "tool"), - _("The upgrade tool will " - "guide you through the " - "upgrade process.")) - fetcher = apt_pkg.GetAcquire(progress) self.uri = self.new_dist.upgradeTool af = apt_pkg.GetPkgAcqFile(fetcher,self.uri, descr=_("Upgrade tool")) if fetcher.Run() != fetcher.ResultContinue: return False return True + return False def runDistUpgrader(self): #print "runing: %s" % script - os.execv(script,[]) + os.execv(self.script,[]) def cleanup(self): # cleanup @@ -185,10 +207,10 @@ class DistUpgradeFetcher(object): print "verify failed" self.cleanup() return - #if not self.authenticate(distUpgradeTar, distUpgradeSig): - # print "authenticate failed" - # self.cleanup() - # return + if not self.authenticate(): + print "authenticate failed" + self.cleanup() + return self.runDistUpgrader() diff --git a/UpdateManager/MetaRelease.py b/UpdateManager/MetaRelease.py index cd56970f..fde705bb 100644 --- a/UpdateManager/MetaRelease.py +++ b/UpdateManager/MetaRelease.py @@ -38,12 +38,13 @@ class Dist(object): self.supported = supported self.releaseNotesURI = None self.upgradeTool = None + self.upgradeToolSig = None class MetaRelease(gobject.GObject): # some constants - #METARELEASE_URI = "http://changelogs.ubuntu.com/meta-release" - METARELEASE_URI = "http://people.ubuntu.com/~mvo/dist-upgrader/meta-release-test.save" + METARELEASE_URI = "http://changelogs.ubuntu.com/meta-release" + #METARELEASE_URI = "http://people.ubuntu.com/~mvo/dist-upgrader/meta-release-test2" METARELEASE_FILE = "/var/lib/update-manager/meta-release" __gsignals__ = { @@ -73,6 +74,7 @@ class MetaRelease(gobject.GObject): if res != 0: sys.stderr.write("lsb_release returned exitcode: %i\n" % res) dist = string.strip(p.stdout.readline()) + #dist = "breezy" return dist def check(self): @@ -107,6 +109,8 @@ class MetaRelease(gobject.GObject): dist.releaseNotesURI = index_tag.Section["ReleaseNotes"] if index_tag.Section.has_key("UpgradeTool"): dist.upgradeTool = index_tag.Section["UpgradeTool"] + if index_tag.Section.has_key("UpgradeToolSignature"): + dist.upgradeToolSig = index_tag.Section["UpgradeToolSignature"] dists.append(dist) if name == current_dist_name: current_dist = dist -- cgit v1.2.3 From 67389517a2f4c58ee03b3ba6ee540df4f8f073f7 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 27 Feb 2006 19:27:51 +0100 Subject: * fix the setting of the SoftwareProperties.modified flag (important for the calling apps like synaptic ) --- SoftwareProperties/SoftwareProperties.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'SoftwareProperties') diff --git a/SoftwareProperties/SoftwareProperties.py b/SoftwareProperties/SoftwareProperties.py index 0e892182..d3fef36a 100644 --- a/SoftwareProperties/SoftwareProperties.py +++ b/SoftwareProperties/SoftwareProperties.py @@ -288,12 +288,14 @@ class SoftwareProperties(SimpleGladeApp): self.sourceslist.refresh() self.reload_sourceslist() self.button_revert.set_sensitive(False) + self.modified = False def modified_sourceslist(self): """The sources list was changed and now needs to be saved and reloaded""" self.button_revert.set_sensitive(True) self.save_sourceslist() self.reload_sourceslist() + self.modified = True def render_source(self, source): """Render a nice output to show the source in a treeview""" -- cgit v1.2.3