#!/usr/bin/python # Mirror selector for smart package manager # # $Id: smart-mirror-select.py 6537 2005-08-08 18:52:50Z jh $ # # Copyright (c) Jaakko Heinonen # Licensed under the General Public License version 2 # # inspired by mirror-select.lua script for apt written by Panu Matilainen import os, sys import urllib2 from snack import * from smart import * import smart class MirrorEntry: def __init__(self, name, server, selected): self.name = name self.server = server self.selected = selected def __str__(self): return '[' + self.name + ', ' + self.server + ', ' \ + str(self.selected) + ']' class MirrorList: def __init__(self, url): lines = self.fetchList(url) self.list = self.parseList(lines) self.index = -1 def __iter__(self): return self def next(self): if(self.index == len(self.list) - 1): raise StopIteration else: self.index = self.index + 1 return self.list[self.index] def fetchList(self, url): f = urllib2.urlopen(url) return map(lambda s: s[:-1], f.readlines()) def popList(self, list): try: l = list.pop(0) except: raise "Corrupted mirror list" return l def parseList(self, list): entries = [] while True: e = { 'name': self.popList(list), 'sig': self.popList(list), 'mirrors': [] } while True: mirror = MirrorEntry(self.popList(list), self.popList(list), False) l = self.popList(list) if l[0:2] == "--": e['mirrors'].append(mirror) else: raise "Corrupted mirror list" if l == "----": entries.append(e) if len(list) == 0: return entries else: break def snackUI(self): ct = CheckboxTree(12, scroll = 1) bindex = 0 for m in self.list: ct.append(m['name']) for me in m['mirrors']: ct.addItem(me.name, (bindex, snackArgs['append']), me, me.selected) bindex = bindex + 1 screen = SnackScreen() bb = ButtonBar(screen, (("Ok", "ok"), ("Cancel", "cancel"))) g = GridForm(screen, "Please select mirrors", 1, 2) g.add(ct, 0, 0) g.add(bb, 0, 1, growx = 1) result = g.runOnce() screen.finish() if bb.buttonPressed(result) == "ok": for me in ct.getSelection(): me.selected = True return True else: return False """ XXX: Works only with one component """ def getUrlComponent(self, s): a = string.split(s) if len(a) >= 3: url = a[0] + "/" + a[1] component = a[2] return (url, component) else: raise "Incorrectly formed mirror entry" def mirrorsToSmart(self, ctrl, mirrors, alias, name, verbose = True): first = None for me in filter(lambda x: x.selected, mirrors): url, component = self.getUrlComponent(me.server) if not first: first = url channel = { 'alias': alias, 'type': "apt-rpm", 'name': name, 'baseurl': url, 'components': component } sysconf.set(("channels", alias), channel) if verbose: print name + ":" else: sysconf.add(("mirrors", first), url, unique=True) if verbose: print " " + me.name def toSmart(self): PREFIX="mirror-selector-" repo = 0 # initialize smart Control object ctrl = smart.init() sysconf.remove("mirrors") for m in self: alias = PREFIX + str(repo) sysconf.remove(("channels", alias)) self.mirrorsToSmart(ctrl, m['mirrors'], alias, m['name']) repo = repo + 1 ctrl.saveSysConf() def main(argv): if argv and argv[0]: url = argv[0] else: ctrl = smart.init() smart.initDistro(ctrl) url = sysconf.get("mirror-select-url") del ctrl if not url: print "No mirror list URL defined." sys.exit(1) try: mirrors = MirrorList(url) except IOError, (error): print "Couldn't retrieve mirror list: %s" % error sys.exit(1) if mirrors.snackUI(): mirrors.toSmart() if __name__ == "__main__": main(sys.argv[1:])