summaryrefslogtreecommitdiff
path: root/UpdateManager/Common
diff options
context:
space:
mode:
Diffstat (limited to 'UpdateManager/Common')
-rw-r--r--UpdateManager/Common/DistInfo.py35
-rw-r--r--UpdateManager/Common/aptsources.py169
-rw-r--r--UpdateManager/Common/utils.py19
3 files changed, 117 insertions, 106 deletions
diff --git a/UpdateManager/Common/DistInfo.py b/UpdateManager/Common/DistInfo.py
index 79d5356c..57621f52 100644
--- a/UpdateManager/Common/DistInfo.py
+++ b/UpdateManager/Common/DistInfo.py
@@ -24,8 +24,9 @@ import os
import gettext
from os import getenv
import ConfigParser
+import string
-_ = gettext.gettext
+from gettext import gettext as _
class Suite:
def __init__(self):
@@ -38,6 +39,7 @@ class Suite:
self.components = {}
self.children = []
self.match_uri = None
+ self.valid_mirrors = []
self.distribution = None
self.available = True
@@ -46,7 +48,6 @@ class Component:
self.name = ""
self.description = ""
self.description_long = ""
- self.enabled = None
class DistInfo:
def __init__(self,
@@ -83,7 +84,7 @@ class DistInfo:
if suite:
if component:
suite.components["%s" % component.name] = \
- (component.description, component.enabled,
+ (component.description,
component.description_long)
component = None
self.suites.append (suite)
@@ -98,6 +99,13 @@ class DistInfo:
for nanny in self.suites:
if nanny.name == value:
nanny.children.append(suite)
+ # reuse some properties of the parent suite
+ if suite.match_uri == None:
+ suite.match_uri = nanny.match_uri
+ if suite.valid_mirrors == None:
+ suite.valid_mirrors = nanny.valid_mirrors
+ if suite.base_uri == None:
+ suite.base_uri = nanny.base_uri
elif field == 'Available':
suite.available = value
elif field == 'RepositoryType':
@@ -107,17 +115,24 @@ class DistInfo:
suite.match_uri = value
elif field == 'MatchURI':
suite.match_uri = value
+ elif field == 'MirrorsFile':
+ if os.path.exists(value):
+ suite.valid_mirrors = filter(lambda s:
+ ((s != "") and
+ (not s.startswith("#"))),
+ map(string.strip,
+ open(value)))
+ else:
+ print "WARNING: can't read '%s'" % value
elif field == 'Description':
suite.description = _(value)
elif field == 'Component':
if component:
suite.components["%s" % component.name] = \
- (component.description, component.enabled,
+ (component.description,
component.description_long)
component = Component ()
component.name = value
- elif field == 'Enabled':
- component.enabled = bool(int(value))
elif field == 'CompDescription':
component.description = _(value)
elif field == 'CompDescriptionLong':
@@ -125,7 +140,7 @@ class DistInfo:
if suite:
if component:
suite.components["%s" % component.name] = \
- (component.description, component.enabled,
+ (component.description,
component.description_long)
component = None
self.suites.append (suite)
@@ -133,17 +148,17 @@ class DistInfo:
if __name__ == "__main__":
- d = DistInfo ("Ubuntu", "../../channels")
+ d = DistInfo ("Ubuntu", "../../data/channels")
print d.changelogs_uri
for suite in d.suites:
print "\nSuite: %s" % suite.name
print "Desc: %s" % suite.description
print "BaseURI: %s" % suite.base_uri
print "MatchURI: %s" % suite.match_uri
+ print "Mirrors: %s" % suite.valid_mirrors
for component in suite.components:
print " %s - %s - %s - %s" % (component,
suite.components[component][0],
- suite.components[component][1],
- suite.components[component][2])
+ suite.components[component][1])
for child in suite.children:
print " %s" % child.description
diff --git a/UpdateManager/Common/aptsources.py b/UpdateManager/Common/aptsources.py
index 09673376..34b5b967 100644
--- a/UpdateManager/Common/aptsources.py
+++ b/UpdateManager/Common/aptsources.py
@@ -72,28 +72,26 @@ def uniq(s):
""" simple and efficient way to return uniq list """
return list(set(s))
-
-
-# actual source.list entries
class SourceEntry:
-
+ """ single sources.list entry """
def __init__(self, line,file=None):
- self.invalid = False
- self.disabled = False
- self.type = ""
- self.uri = ""
- self.dist = ""
- self.comps = []
- self.comment = ""
- self.line = line
- if file == None:
+ self.invalid = False # is the source entry valid
+ self.disabled = False # is it disabled ('#' in front)
+ self.type = "" # what type (deb, deb-src)
+ self.uri = "" # base-uri
+ self.dist = "" # distribution (dapper, edgy, etc)
+ self.comps = [] # list of available componetns (may empty)
+ self.comment = "" # (optional) comment
+ self.line = line # the original sources.list line
+ if file == None:
file = apt_pkg.Config.FindDir("Dir::Etc")+apt_pkg.Config.Find("Dir::Etc::sourcelist")
- self.file = file
+ self.file = file # the file that the entry is located in
self.parse(line)
- self.template = None
+ self.template = None # type DistInfo.Suite
self.children = []
- def __eq__(self, other):
+ def __eq__(self, other):
+ """ equal operator for two sources.list entries """
return (self.disabled == other.disabled and
self.type == other.type and
self.uri == other.uri and
@@ -101,8 +99,9 @@ class SourceEntry:
self.comps == other.comps)
- # works mostely like split but takes [] into account
def mysplit(self, line):
+ """ a split() implementation that understands the sources.list
+ format better and takes [] into account (for e.g. cdroms) """
line = string.strip(line)
pieces = []
tmp = ""
@@ -129,9 +128,9 @@ class SourceEntry:
pieces.append(tmp)
return pieces
-
- # parse a given source line and split it into the fields we need
def parse(self,line):
+ """ parse a given sources.list (textual) line and break it up
+ into the field we have """
line = string.strip(self.line)
#print line
# check if the source is enabled/disabled
@@ -177,11 +176,8 @@ class SourceEntry:
else:
self.comps = []
- #print self.__dict__
-
-
- # set enabled/disabled
def set_enabled(self, new_value):
+ """ set a line to enabled or disabled """
self.disabled = not new_value
# enable, remove all "#" from the start of the line
if new_value == True:
@@ -214,15 +210,17 @@ class SourceEntry:
line += "\n"
return line
-# the SourceList file as a class
class NullMatcher(object):
+ """ a Matcher that does nothing """
def match(self, s):
return True
class SourcesList:
- def __init__(self, withMatcher=True,
+ """ represents the full sources.list + sources.list.d file """
+ def __init__(self,
+ withMatcher=True,
matcherPath="/usr/share/update-manager/channels/"):
- self.list = [] # of Type SourceEntries
+ self.list = [] # the actual SourceEntries Type
if withMatcher:
self.matcher = SourceEntryMatcher(matcherPath)
else:
@@ -230,6 +228,7 @@ class SourcesList:
self.refresh()
def refresh(self):
+ """ update the list of known entries """
self.list = []
# read sources.list
dir = apt_pkg.Config.FindDir("Dir::Etc")
@@ -245,6 +244,8 @@ class SourcesList:
self.matcher.match(source)
def __iter__(self):
+ """ simple iterator to go over self.list, returns SourceEntry
+ types """
for entry in self.list:
yield entry
raise StopIteration
@@ -298,6 +299,7 @@ class SourcesList:
return new_entry
def remove(self, source_entry):
+ """ remove the specified entry from the sources.list """
self.list.remove(source_entry)
def restoreBackup(self, backup_ext):
@@ -370,56 +372,6 @@ class SourcesList:
#print self.parents
return (parents, used_child_templates)
-# templates for the add dialog
-class SourceEntryTemplate(SourceEntry):
- def __init__(self,a_type,uri,dist,description,comps):
- self.comps_descriptions = []
- self.type = a_type
- self.uri = uri
- self.dist = dist
- self.description = description
- self.comps = comps
-
- def matches(self,source_entry):
- """ check if a given source_entry matches this one """
- if (self.type != source_entry.type):
- return False
- if (self.dist != source_entry.dist):
- return False
- if not is_mirror(self.uri,source_entry.uri):
- return False
- for e_comp in source_entry.comps:
- for t_comp in self.comps:
- if e_comp == t_comp.name: break
- else:
- return False
- return True
-
-class SourceCompTemplate:
- def __init__(self, name, description, on_by_default):
- self.name = name
- self.description = description
- self.on_by_default = on_by_default
-
-class SourceEntryTemplates:
-
- def __init__(self,datadir):
- _ = gettext.gettext
- self.templates = []
-
- dinfo = DistInfo (base_dir=datadir+"channels/")
-
- for suite in dinfo.suites:
- comps = []
- for comp in suite.components:
- comps.append(SourceCompTemplate(comp.name, _(comp.description),
- comp.enabled))
- self.templates.append (SourceEntryTemplate(suite.repository_type,
- suite.base_uri,
- suite.name,
- suite.description,
- comps))
-
# matcher class to make a source entry look nice
# lots of predefined matchers to make it i18n/gettext friendly
class SourceEntryMatcher:
@@ -444,7 +396,7 @@ class SourceEntryMatcher:
f = os.path.basename(f)
i = f.find(".info")
f = f[0:i]
- dist = DistInfo(f)
+ dist = DistInfo(f,base_dir=matcherPath)
for suite in dist.suites:
if suite.match_uri != None:
self.templates.append(suite)
@@ -455,12 +407,17 @@ class SourceEntryMatcher:
_ = gettext.gettext
found = False
for template in self.templates:
- #print "'%s'" %source.uri
- if re.search(template.match_uri, source.uri) and \
- re.match(template.match_name, source.dist):
+ if (re.search(template.match_uri, source.uri) and
+ re.match(template.match_name, source.dist)):
found = True
source.template = template
break
+ for mirror in template.valid_mirrors:
+ if (is_mirror(mirror,source.uri) and
+ re.match(template.match_name, source.dist)):
+ found = True
+ source.template = template
+ break
return found
class Distribution:
@@ -568,7 +525,6 @@ class Distribution:
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)
@@ -644,27 +600,37 @@ class Distribution:
sourceslist: an aptsource.sources_list
comp: the component that should be enabled
"""
- def add_component_only_once(source, workpile):
+ 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 not (workpile.has_key(source.uri) and\
- source.dist in workpile[source.uri]):
- if comp not in source.comps:
- source.comps.append(comp)
- if workpile.has_key(source.uri):
- workpile[source.uri].append(source.dist)
- else:
- workpile[source.uri] = [source.dist]
+ # if we don't that distro, just reutnr (can happen for e.g.
+ # dapper-update only in deb-src
+ if not comps_per_dist.has_key(source.dist):
+ return
+ # if we have seen this component already for this distro,
+ # return (nothing to do
+ if comp in comps_per_dist[source.dist]:
+ return
+ # add it
+ source.comps.append(comp)
+ comps_per_dist[source.dist].add(comp)
sources = []
sources.extend(self.main_sources)
sources.extend(self.child_sources)
sources.extend(self.source_code_sources)
- # store repos to which the new component has been added
- workpile = {}
+ # store what comps are enabled already per distro (where distro is
+ # e.g. "dapper", "dapper-updates")
+ comps_per_dist = {}
+ for s in sources:
+ if s.type != "deb":
+ continue
+ if not comps_per_dist.has_key(s.dist):
+ comps_per_dist[s.dist] = set()
+ map(comps_per_dist[s.dist].add, s.comps)
# check if there is a main source at all
if len(self.main_sources) < 1:
# create a new main source
@@ -672,12 +638,20 @@ class Distribution:
else:
# add the comp to all main, child and source code sources
for source in sources:
- add_component_only_once(source, workpile)
+ add_component_only_once(source, comps_per_dist)
+ # now do the same for source dists
if self.get_source_code == True:
- for source in self.source_code_sources:
- if comp not in source.comps:
- add_component_only_once(source, workpile)
+ comps_per_dist = {}
+ for s in self.source_code_sources:
+ if s.type != "deb-src":
+ continue
+ if not comps_per_dist.has_key(s.dist):
+ comps_per_dist[s.dist] = set()
+ map(comps_per_dist[s.dist].add, s.comps)
+ for source in self.source_code_sources:
+ if comp not in source.comps:
+ add_component_only_once(source, comps_per_dist)
def disable_component(self, sourceslist, comp):
@@ -715,3 +689,6 @@ if __name__ == "__main__":
print is_mirror("http://archive.ubuntu.com/ubuntu",
"http://de.archive.ubuntu.com/ubuntu/")
+ print is_mirror("http://archive.ubuntu.com/ubuntu/",
+ "http://de.archive.ubuntu.com/ubuntu")
+
diff --git a/UpdateManager/Common/utils.py b/UpdateManager/Common/utils.py
index 099cbfed..1fcd022f 100644
--- a/UpdateManager/Common/utils.py
+++ b/UpdateManager/Common/utils.py
@@ -1,4 +1,6 @@
import gtk
+from gettext import gettext as _
+import locale
def str_to_bool(str):
if str == "0" or str.upper() == "FALSE":
@@ -21,3 +23,20 @@ def error(parent, summary, message):
res = d.run()
d.destroy()
return
+
+def humanize_size(bytes):
+ """
+ Convert a given size in bytes to a nicer better readable unit
+ """
+ if bytes == 0:
+ # TRANSLATORS: download size is 0
+ return _("None")
+ elif bytes < 1024:
+ # TRANSLATORS: download size of very small updates
+ return _("1 KB")
+ elif bytes < 1024 * 1024:
+ # TRANSLATORS: download size of small updates, e.g. "250 KB"
+ return locale.format(_("%.0f KB"), bytes/1024)
+ else:
+ # TRANSLATORS: download size of updates, e.g. "2.3 MB"
+ return locale.format(_("%.1f MB"), bytes / 1024 / 1024)