1
# aptsource.py.in - parse sources.list
3
# Copyright (c) 2004 Canonical
6
# Author: Michiel Sikkes <michiel@eyesopened.nl>
7
# Michael Vogt <mvo@debian.org>
9
# This program is free software; you can redistribute it and/or
10
# modify it under the terms of the GNU General Public License as
11
# published by the Free Software Foundation; either version 2 of the
12
# License, or (at your option) any later version.
14
# This program is distributed in the hope that it will be useful,
15
# but WITHOUT ANY WARRANTY; without even the implied warranty of
16
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
# GNU General Public License for more details.
19
# You should have received a copy of the GNU General Public License
20
# along with this program; if not, write to the Free Software
21
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
28
# actual source.list entries
31
# works mostely like split but takes [] into account
32
def mysplit(self, line):
33
line = string.strip(line)
36
# we are inside a [..] block
39
for i in range(len(line)):
46
elif space_found and not line[i].isspace(): # we skip one or more space
50
elif line[i].isspace() and not p_found: # found a whitespace
60
# parse a given source line and split it into the fields we need
62
line = string.strip(self.line)
64
# check if the source is enabled/disabled
65
if line == "" or line == "#":
70
pieces = string.split(line[1:])
71
# if it looks not like a disabled deb line return
72
if not (pieces[0] == "deb" or pieces[0] == "deb-src"):
77
# check for another "#" in the line (this is treated as a comment)
80
self.comment = line[i+1:]
82
# source is ok, split it and see what we have
83
pieces = self.mysplit(line)
84
# Type, deb or deb-src
85
self.type = string.strip(pieces[0])
87
self.uri = string.strip(pieces[1])
88
# distro and components (optional)
90
self.dist = string.strip(pieces[2])
93
self.comps = pieces[3:]
100
# set enabled/disabled
101
def set_enabled(self, new_value):
102
self.disabled = not new_value
103
# enable, remove all "#" from the start of the line
104
if new_value == True:
106
self.line = string.lstrip(self.line)
107
while self.line[i] == "#":
109
self.line = self.line[i:]
111
# disabled, add a "#"
112
if string.strip(self.line)[0] != "#":
113
self.line = "#" + self.line
116
def __init__(self, line):
118
self.disabled = False
133
""" simple (and not efficient) way to return uniq list """
141
# the SourceList file as a class
143
def __init__(self, file):
144
self.list = [] # of Type SourceEntries
147
def is_mirror(self, add_uri, orig_uri):
148
"""check if the given add_url is idential or a mirror of orig_uri
149
e.g. add_uri = archive.ubuntu.com
150
orig_uri = de.archive.ubuntu.com
153
# remove traling spaces and "/"
154
add_uri = add_uri.rstrip("/ ")
155
orig_uri = orig_uri.rstrip("/ ")
157
if add_uri == orig_uri:
160
# add uri is a master site and orig_uri has the from "XX.mastersite"
161
# (e.g. de.archive.ubuntu.com)
163
add_srv = add_uri.split("//")[1]
164
orig_srv = orig_uri.split("//")[1]
165
#print "%s == %s " % (add_srv, orig_srv)
166
except IndexError: # ok, somethings wrong here
169
if add_srv == orig_srv[3:]:
174
def add(self, type, uri, dist, comps, comment="", pos=-1):
175
# if there is a repo with the same (type, uri, dist) just add the
178
if i.type == type and self.is_mirror(uri,i.uri) and i.dist == dist:
179
comps = uniq(i.comps + comps)
182
# set to the old position and preserve comment
184
pos = self.list.index(i)
186
line = "%s %s %s" % (type,uri,dist)
188
line = line + " " + c;
190
line = "%s #%s\n" %(line,comment)
192
self.list.insert(pos, SourceEntry(line))
194
def remove(self, source_entry):
195
self.list.remove(source_entry)
199
lines = f.readlines()
201
source = SourceEntry(line)
202
self.list.append(source)
207
for source in self.list:
208
f.write(source.str())
212
# templates for the add dialog
213
class SourceEntryTemplate(SourceEntry):
214
def __init__(self,a_type,uri,dist,description,comps):
216
self.comps_descriptions = []
220
self.description = description
223
class SourceCompTemplate:
224
def __init__(self, name, description, on_by_default):
226
self.description = description
227
self.on_by_default = on_by_default
229
class SourceEntryTemplates:
234
# ubuntu components templates
236
ubuntu_comps.append(SourceCompTemplate("main",_("Officially supported"),True))
237
ubuntu_comps.append(SourceCompTemplate("restricted",_("Restricted copyright"),True))
238
ubuntu_comps.append(SourceCompTemplate("universe",_("Community maintained (Universe)"),False))
239
ubuntu_comps.append(SourceCompTemplate("multiverse",_("Non-free (Multiverse)"),False))
242
self.templates.append(SourceEntryTemplate("deb",
243
"http://archive.ubuntu.com/ubuntu/",
245
"Ubuntu 5.10 \"Breezy Badger\"",
247
self.templates.append(SourceEntryTemplate("deb",
248
"http://security.ubuntu.com/ubuntu/",
250
_("Ubuntu 5.10 Security Updates"),
252
self.templates.append(SourceEntryTemplate("deb",
253
"http://archive.ubuntu.com/ubuntu/",
255
_("Ubuntu 5.10 Updates"),
259
# matcher class to make a source entry look nice
260
# lots of predefined matchers to make it i18n/gettext friendly
261
class SourceEntryMatcher:
263
def __init__(self, a_type,a_descr):
265
self.description = a_descr
268
def __init__(self,a_uri,a_dist, a_descr,l_comps, l_comps_descr):
271
self.description = a_descr
273
self.comps_descriptions = l_comps_descr
278
self.type_list.append(self.MatchType("^deb$",_("Binary")))
279
self.type_list.append(self.MatchType("^deb-src$",_("Source")))
283
ubuntu_comps = ["^main$","^restricted$","^universe$","^multiverse$"]
284
ubuntu_comps_descr = [_("Officially supported"),
285
_("Restricted copyright"),
286
_("Community maintained (Universe)"),
287
_("Non-free (Multiverse)")]
289
self.dist_list.append(self.MatchDist("cdrom:\[Ubuntu.*4.10",
292
" Ubuntu 4.10 \"Warty Warthog\"",
293
ubuntu_comps, ubuntu_comps_descr))
294
self.dist_list.append(self.MatchDist("cdrom:\[Ubuntu.*5.04",
297
" Ubuntu 5.04 \"Hoary Hedgehog\"",
298
ubuntu_comps, ubuntu_comps_descr))
299
self.dist_list.append(self.MatchDist("cdrom:\[Ubuntu.*5.10",
302
" Ubuntu 5.10 \"Breezy Badger\"",
303
ubuntu_comps, ubuntu_comps_descr))
307
self.dist_list.append(self.MatchDist(".*archive.ubuntu.com/ubuntu",
309
"Ubuntu 4.10 \"Warty Warthog\"",
310
ubuntu_comps, ubuntu_comps_descr))
311
self.dist_list.append(self.MatchDist(".*archive.ubuntu.com/ubuntu",
313
"Ubuntu 5.04 \"Hoary Hedgehog\"",
314
ubuntu_comps, ubuntu_comps_descr))
315
self.dist_list.append(self.MatchDist(".*archive.ubuntu.com/ubuntu",
317
"Ubuntu 5.10 \"Breezy Badger\"",
318
ubuntu_comps, ubuntu_comps_descr))
320
self.dist_list.append(self.MatchDist(".*archive.ubuntu.com/ubuntu",
322
_("Ubuntu 5.04 Updates"),
323
ubuntu_comps, ubuntu_comps_descr))
324
self.dist_list.append(self.MatchDist(".*archive.ubuntu.com/ubuntu",
326
_("Ubuntu 5.10 Updates"),
327
ubuntu_comps, ubuntu_comps_descr))
330
self.dist_list.append(self.MatchDist(".*security.ubuntu.com/ubuntu",
332
_("Ubuntu 4.10 Security Updates"),
333
ubuntu_comps, ubuntu_comps_descr))
334
self.dist_list.append(self.MatchDist(".*security.ubuntu.com/ubuntu",
336
_("Ubuntu 5.04 Security Updates"),
337
ubuntu_comps, ubuntu_comps_descr))
338
self.dist_list.append(self.MatchDist(".*security.ubuntu.com/ubuntu",
340
_("Ubuntu 5.10 Security Updates"),
341
ubuntu_comps, ubuntu_comps_descr))
342
# security (normal archive uri)
343
self.dist_list.append(self.MatchDist(".*archive.ubuntu.com/ubuntu",
345
_("Ubuntu 4.10 Security Updates"),
346
ubuntu_comps, ubuntu_comps_descr))
347
self.dist_list.append(self.MatchDist(".*archive.ubuntu.com/ubuntu",
349
_("Ubuntu 5.04 Security Updates"),
350
ubuntu_comps, ubuntu_comps_descr))
351
self.dist_list.append(self.MatchDist(".*archive.ubuntu.com/ubuntu",
353
_("Ubuntu 5.10 Security Updates"),
354
ubuntu_comps, ubuntu_comps_descr))
358
debian_comps = ["^main$","^contrib$","^non-free$","^non-US$"]
359
debian_comps_descr = [_("Officially supported"),
360
_("Contributed software"),
361
_("Non-free software"),
362
_("US export restricted software")
366
self.dist_list.append(self.MatchDist(".*debian.org/debian",
368
"Debian 3.1 \"Sarge\"",
369
debian_comps, debian_comps_descr))
370
self.dist_list.append(self.MatchDist(".*debian.org/debian",
372
"Debian 3.0 \"Woody\"",
373
debian_comps, debian_comps_descr))
375
self.dist_list.append(self.MatchDist(".*security.debian.org",
377
_("Debian Stable Security Updates"),
378
debian_comps, debian_comps_descr))
380
self.dist_list.append(self.MatchDist(".*debian.org/debian",
383
debian_comps, debian_comps_descr))
384
self.dist_list.append(self.MatchDist(".*debian.org/debian",
387
debian_comps, debian_comps_descr))
388
self.dist_list.append(self.MatchDist(".*debian.org/debian",
390
"Debian Unstable \"Sid\"",
391
debian_comps, debian_comps_descr))
394
self.dist_list.append(self.MatchDist(".*debian.org/debian-non-US",
396
"Debian Non-US (Stable)",
397
debian_comps, debian_comps_descr))
398
self.dist_list.append(self.MatchDist(".*debian.org/debian-non-US",
400
"Debian Non-US (Testing)",
401
debian_comps, debian_comps_descr))
402
self.dist_list.append(self.MatchDist(".*debian.org/debian-non-US",
404
"Debian Non-US (Unstable)",
405
debian_comps, debian_comps_descr))
410
def match(self,source):
412
# some sane defaults first
413
type_description = source.type
414
dist_description = source.uri + " " + source.dist
415
comp_description = ""
416
for c in source.comps:
417
comp_description = comp_description + " " + c
419
for t in self.type_list:
420
if re.match(t.type, source.type):
421
type_description = _(t.description)
424
for d in self.dist_list:
425
#print "'%s'" %source.uri
426
if re.match(d.uri, source.uri) and re.match(d.dist,source.dist):
427
dist_description = d.description
428
comp_description = ""
429
for c in source.comps:
431
for i in range(len(d.comps)):
432
if re.match(d.comps[i], c):
433
comp_description = comp_description+"\n"+d.comps_descriptions[i]
436
comp_description = comp_description+" "+c
440
return (type_description,dist_description,comp_description)