summaryrefslogtreecommitdiff
path: root/aptsources/aptsources.py
diff options
context:
space:
mode:
Diffstat (limited to 'aptsources/aptsources.py')
-rw-r--r--aptsources/aptsources.py407
1 files changed, 4 insertions, 403 deletions
diff --git a/aptsources/aptsources.py b/aptsources/aptsources.py
index 457e13f2..0928a0e8 100644
--- a/aptsources/aptsources.py
+++ b/aptsources/aptsources.py
@@ -1,12 +1,12 @@
-# aptsource.py.in - parse sources.list
+# aptsource.py - Provide an abstraction of the sources.list
#
-# Copyright (c) 2004-2006 Canonical
+# Copyright (c) 2004-2007 Canonical Ltd.
# 2004 Michiel Sikkes
-# 2006 Sebastian Heinlein
+# 2006-2007 Sebastian Heinlein
#
# Author: Michiel Sikkes <michiel@eyesopened.nl>
# Michael Vogt <mvo@debian.org>
-# Sebastian Heinlein
+# Sebastian Heinlein <glatzor@ubuntu.com>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
@@ -407,405 +407,6 @@ class SourceEntryMatcher:
break
return found
-class Distribution:
- def __init__(self, id, codename, description, release):
- """ Container for distribution specific informations """
- # LSB information
- self.id = id
- self.codename = codename
- self.description = description
- self.release = release
-
- self.binary_type = "deb"
- self.source_type = "deb-src"
-
- def get_sources(self, sourceslist):
- """
- Find the corresponding template, main and child sources
- for the distribution
- """
-
- self.sourceslist = sourceslist
- # corresponding sources
- self.source_template = None
- self.child_sources = []
- self.main_sources = []
- self.disabled_sources = []
- self.cdrom_sources = []
- self.download_comps = []
- self.enabled_comps = []
- self.cdrom_comps = []
- self.used_media = []
- self.get_source_code = False
- self.source_code_sources = []
-
- # location of the sources
- self.default_server = ""
- self.main_server = ""
- self.nearest_server = ""
- self.used_servers = []
-
- # find the distro template
- for template in self.sourceslist.matcher.templates:
- if self.is_codename(template.name) and\
- template.distribution == self.id:
- #print "yeah! found a template for %s" % self.description
- #print template.description, template.base_uri, template.components
- self.source_template = template
- break
- if self.source_template == None:
- print "Error: could not find a distribution template"
- # FIXME: will go away - only for debugging issues
- sys.exit(1)
-
- # find main and child sources
- media = []
- comps = []
- cdrom_comps = []
- enabled_comps = []
- source_code = []
- for source in self.sourceslist.list:
- if source.invalid == False and\
- self.is_codename(source.dist) and\
- source.template and\
- self.is_codename(source.template.name):
- #print "yeah! found a distro repo: %s" % source.line
- # cdroms need do be handled differently
- if source.uri.startswith("cdrom:") and \
- source.disabled == False:
- self.cdrom_sources.append(source)
- cdrom_comps.extend(source.comps)
- elif source.uri.startswith("cdrom:") and \
- source.disabled == True:
- self.cdrom_sources.append(source)
- elif source.type == self.binary_type and \
- source.disabled == False:
- self.main_sources.append(source)
- comps.extend(source.comps)
- media.append(source.uri)
- elif source.type == self.binary_type and \
- source.disabled == True:
- self.disabled_sources.append(source)
- elif source.type == self.source_type and source.disabled == False:
- self.source_code_sources.append(source)
- elif source.type == self.source_type and source.disabled == True:
- self.disabled_sources.append(source)
- if source.invalid == False and\
- source.template in self.source_template.children:
- if source.disabled == False and source.type == self.binary_type:
- self.child_sources.append(source)
- elif source.disabled == False and source.type == self.source_type:
- self.source_code_sources.append(source)
- else:
- self.disabled_sources.append(source)
- self.download_comps = set(comps)
- self.cdrom_comps = set(cdrom_comps)
- enabled_comps.extend(comps)
- enabled_comps.extend(cdrom_comps)
- self.enabled_comps = set(enabled_comps)
- self.used_media = set(media)
-
- self.get_mirrors()
-
- def get_mirrors(self):
- """
- Provide a set of mirrors where you can get the distribution from
- """
- # the main server is stored in the template
- self.main_server = self.source_template.base_uri
-
- # other used servers
- for medium in self.used_media:
- if not medium.startswith("cdrom:"):
- # seems to be a network source
- self.used_servers.append(medium)
-
- if len(self.main_sources) == 0:
- self.default_server = self.main_server
- else:
- self.default_server = self.main_sources[0].uri
-
- def add_source(self, type=None,
- uri=None, dist=None, comps=None, comment=""):
- """
- Add distribution specific sources
- """
- if uri == None:
- # FIXME: Add support for the server selector
- uri = self.default_server
- if dist == None:
- dist = self.codename
- if comps == None:
- comps = list(self.enabled_comps)
- if type == None:
- type = self.binary_type
- new_source = self.sourceslist.add(type, uri, dist, comps, comment)
- # if source code is enabled add a deb-src line after the new
- # source
- if self.get_source_code == True and tpye == self.binary_type:
- self.sourceslist.add(self.source_type, uri, dist, comps, comment,
- file=new_source.file,
- pos=self.sourceslist.list.index(new_source)+1)
-
- def enable_component(self, comp):
- """
- Enable a component in all main, child and source code sources
- (excluding cdrom based sources)
-
- sourceslist: an aptsource.sources_list
- comp: the component that should be enabled
- """
- def add_component_only_once(source, comps_per_dist):
- """
- Check if we already added the component to the repository, since
- a repository could be splitted into different apt lines. If not
- add the component
- """
- # if we don't that distro, just reutnr (can happen for e.g.
- # dapper-update only in deb-src
- if not comps_per_dist.has_key(source.dist):
- return
- # if we have seen this component already for this distro,
- # return (nothing to do
- if comp in comps_per_dist[source.dist]:
- return
- # add it
- source.comps.append(comp)
- comps_per_dist[source.dist].add(comp)
-
- sources = []
- sources.extend(self.main_sources)
- sources.extend(self.child_sources)
- # store what comps are enabled already per distro (where distro is
- # e.g. "dapper", "dapper-updates")
- comps_per_dist = {}
- comps_per_sdist = {}
- for s in sources:
- if s.type == self.binary_type:
- if not comps_per_dist.has_key(s.dist):
- comps_per_dist[s.dist] = set()
- map(comps_per_dist[s.dist].add, s.comps)
- for s in self.source_code_sources:
- if s.type == self.source_type:
- if not comps_per_sdist.has_key(s.dist):
- comps_per_sdist[s.dist] = set()
- map(comps_per_sdist[s.dist].add, s.comps)
-
- # check if there is a main source at all
- if len(self.main_sources) < 1:
- # create a new main source
- self.add_source(comps=["%s"%comp])
- else:
- # add the comp to all main, child and source code sources
- for source in sources:
- add_component_only_once(source, comps_per_dist)
-
- # check if there is a main source code source at all
- if self.get_source_code == True:
- if len(self.source_code_sources) < 1:
- # create a new main source
- self.add_source(type=self.source_type, comps=["%s"%comp])
- else:
- # add the comp to all main, child and source code sources
- for source in self.source_code_sources:
- add_component_only_once(source, comps_per_sdist)
-
- def disable_component(self, comp):
- """
- Disable a component in all main, child and source code sources
- (excluding cdrom based sources)
- """
- sources = []
- sources.extend(self.main_sources)
- sources.extend(self.child_sources)
- sources.extend(self.source_code_sources)
- if comp in self.cdrom_comps:
- sources = []
- sources.extend(self.main_sources)
-
- for source in sources:
- if comp in source.comps:
- source.comps.remove(comp)
- if len(source.comps) < 1:
- self.sourceslist.remove(source)
-
- def change_server(self, uri):
- ''' Change the server of all distro specific sources to
- a given host '''
- sources = []
- seen = []
- self.default_server = uri
- sources.extend(self.main_sources)
- sources.extend(self.child_sources)
- sources.extend(self.source_code_sources)
- for source in sources:
- # Avoid creating duplicate entries
- source.uri = uri
- for comp in source.comps:
- if [source.uri, source.dist, comp] in seen:
- source.comps.remove(comp)
- else:
- seen.append([source.uri, source.dist, comp])
- if len(source.comps) < 1:
- self.sourceslist.remove(source)
-
- def is_codename(self, name):
- ''' Compare a given name with the release codename. '''
- if name == self.codename:
- return True
- else:
- return False
-
- def get_server_list(self):
- ''' Return a list of used and suggested servers '''
- # Store all available servers:
- # Name, URI, active
- mirrors = []
-
- mirrors.append([_("Main server"), self.main_server,
- len(self.used_servers) == 1 and
- self.used_servers[0] == self.main_server])
-
- if len(self.used_servers) == 1 and not re.match(self.used_servers[0],
- self.main_server):
- # Only one server is used
- server = self.used_servers[0]
- mirrors.append([server, server, True])
- elif len(self.used_servers) > 1:
- # More than one server is used. Since we don't handle this case
- # in the user interface we set "custom servers" to true and
- # append a list of all used servers
- mirrors.append([_("Custom servers"), None, True])
- for server in self.used_servers:
- if not [server, server, False] in mirrors:
- mirrors.append([server, server, False])
-
- return mirrors
-
- if len(self.used_servers) == 1 and not is_single_server(self.main_server):
- mirrors.append(["%s" % self.used_servers[0],
- self.used_servers[0], True])
- elif len(self.used_servers) > 1 or not is_single_server(self.main_server):
- mirrors.append([_("Custom servers"), None, True])
-
- return mirrors
-
-
-class DebianDistribution(Distribution):
- ''' Class to support specific Debian features '''
-
- def is_codename(self, name):
- ''' Compare a given name with the release codename and check if
- if it can be used as a synonym for a development releases '''
- if name == self.codename or self.release in ("testing", "unstable"):
- return True
- else:
- return False
-
-class UbuntuDistribution(Distribution):
- ''' Class to support specific Ubuntu features '''
- def get_mirrors(self):
- Distribution.get_mirrors(self)
- # get a list of country codes and real names
- self.countries = {}
- try:
- f = open("/usr/share/iso-codes/iso_3166.tab", "r")
- lines = f.readlines()
- for line in lines:
- parts = line.split("\t")
- self.countries[parts[0].lower()] = parts[1].strip()
- except:
- print "could not open file '%s'" % file
- else:
- f.close()
-
- # try to guess the nearest mirror from the locale
- self.country = None
- self.country_code = None
- locale = os.getenv("LANG", default="en.UK")
- a = locale.find("_")
- z = locale.find(".")
- if z == -1:
- z = len(locale)
- country_code = locale[a+1:z].lower()
- self.nearest_server = "http://%s.archive.ubuntu.com/ubuntu/" % \
- country_code
- if self.countries.has_key(country_code):
- self.country = self.countries[country_code]
- self.country_code = country_code
-
- def get_server_list(self):
- ''' Return a list of used and suggested servers '''
-
- def get_mirror_name(server):
- ''' Try to get a human readable name for the main mirror of a country'''
- country = None
- i = server.find("://")
- l = server.find(".archive.ubuntu.com")
- if i != -1 and l != -1:
- country = server[i+len("://"):l]
- if self.countries.has_key(country):
- # TRANSLATORS: %s is a country
- return _("Server for %s") % \
- gettext.dgettext("iso-3166",
- self.countries[country].rstrip()).rstrip()
- else:
- return("%s" % server)
-
- # Store all available servers:
- # Name, URI, active
- mirrors = []
- if len(self.used_servers) < 1 or \
- (len(self.used_servers) == 1 and \
- self.used_servers[0] == self.main_server):
- mirrors.append([_("Main server"), self.main_server, True])
- mirrors.append([get_mirror_name(self.nearest_server),
- self.nearest_server, False])
- elif len(self.used_servers) == 1 and not re.match(self.used_servers[0],
- self.main_server):
- mirrors.append([_("Main server"), self.main_server, False])
- # Only one server is used
- server = self.used_servers[0]
-
- # Append the nearest server if it's not already used
- if not re.match(server, self.nearest_server):
- mirrors.append([get_mirror_name(self.nearest_server),
- self.nearest_server, False])
- mirrors.append([get_mirror_name(server), server, True])
-
- elif len(self.used_servers) > 1:
- # More than one server is used. Since we don't handle this case
- # in the user interface we set "custom servers" to true and
- # append a list of all used servers
- mirrors.append([_("Main server"), self.main_server, False])
- mirrors.append([get_mirror_name(self.nearest_server),
- self.nearest_server, False])
- mirrors.append([_("Custom servers"), None, True])
- for server in self.used_servers:
- if re.match(server, self.nearest_server):
- continue
- elif not [get_mirror_name(server), server, False] in mirrors:
- mirrors.append([get_mirror_name(server), server, False])
-
- return mirrors
-
-def get_distro():
- ''' Check the currently used distribution and return the corresponding
- distriubtion class that supports distro specific features. '''
- lsb_info = []
- for lsb_option in ["-i", "-c", "-d", "-r"]:
- pipe = os.popen("lsb_release %s -s" % lsb_option)
- lsb_info.append(pipe.read().strip())
- del pipe
- (id, codename, description, release) = lsb_info
- if id == "Ubuntu":
- return UbuntuDistribution(id, codename, description,
- release)
- elif id == "Debian":
- return DebianDistribution(id, codename, description,
- release)
- else:
- return Distribution(id, codename, description, relase)
# some simple tests
if __name__ == "__main__":