home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2006 November (DVD) / PCWELT_11_2006.ISO / casper / filesystem.squashfs / usr / lib / python2.4 / site-packages / UpdateManager / Common / aptsources.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2006-08-31  |  18.2 KB  |  671 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.4)
  3.  
  4. import string
  5. import gettext
  6. import re
  7. import apt_pkg
  8. import glob
  9. import shutil
  10. import time
  11. import os.path as os
  12. from UpdateManager.Common.DistInfo import DistInfo
  13.  
  14. def is_mirror(master_uri, compare_uri):
  15.     '''check if the given add_url is idential or a mirror of orig_uri
  16.     e.g. master_uri = archive.ubuntu.com
  17.       compare_uri = de.archive.ubuntu.com
  18.       -> True
  19.   '''
  20.     compare_uri = compare_uri.rstrip('/ ')
  21.     master_uri = master_uri.rstrip('/ ')
  22.     if compare_uri == master_uri:
  23.         return True
  24.     
  25.     
  26.     try:
  27.         compare_srv = compare_uri.split('//')[1]
  28.         master_srv = master_uri.split('//')[1]
  29.     except IndexError:
  30.         return False
  31.  
  32.     if '.' in compare_srv and compare_srv[compare_srv.index('.') + 1:] == master_srv:
  33.         return True
  34.     
  35.     return False
  36.  
  37.  
  38. def uniq(s):
  39.     ''' simple and efficient way to return uniq list '''
  40.     return list(set(s))
  41.  
  42.  
  43. class SourceEntry:
  44.     
  45.     def __init__(self, line, file = None):
  46.         self.invalid = False
  47.         self.disabled = False
  48.         self.type = ''
  49.         self.uri = ''
  50.         self.dist = ''
  51.         self.comps = []
  52.         self.comment = ''
  53.         self.line = line
  54.         if file == None:
  55.             file = apt_pkg.Config.FindDir('Dir::Etc') + apt_pkg.Config.Find('Dir::Etc::sourcelist')
  56.         
  57.         self.file = file
  58.         self.parse(line)
  59.         self.template = None
  60.         self.children = []
  61.  
  62.     
  63.     def mysplit(self, line):
  64.         line = string.strip(line)
  65.         pieces = []
  66.         tmp = ''
  67.         p_found = False
  68.         space_found = False
  69.         for i in range(len(line)):
  70.             if line[i] == '[':
  71.                 p_found = True
  72.                 tmp += line[i]
  73.                 continue
  74.             if line[i] == ']':
  75.                 p_found = False
  76.                 tmp += line[i]
  77.                 continue
  78.             if space_found and not line[i].isspace():
  79.                 space_found = False
  80.                 pieces.append(tmp)
  81.                 tmp = line[i]
  82.                 continue
  83.             if line[i].isspace() and not p_found:
  84.                 space_found = True
  85.                 continue
  86.             tmp += line[i]
  87.         
  88.         if len(tmp) > 0:
  89.             pieces.append(tmp)
  90.         
  91.         return pieces
  92.  
  93.     
  94.     def parse(self, line):
  95.         line = string.strip(self.line)
  96.         if line == '' or line == '#':
  97.             self.invalid = True
  98.             return None
  99.         
  100.         if line[0] == '#':
  101.             self.disabled = True
  102.             pieces = string.split(line[1:])
  103.             if not pieces[0] == 'deb' or pieces[0] == 'deb-src':
  104.                 self.invalid = True
  105.                 return None
  106.             else:
  107.                 line = line[1:]
  108.         
  109.         i = line.find('#')
  110.         if i > 0:
  111.             self.comment = line[i + 1:]
  112.             line = line[:i]
  113.         
  114.         pieces = self.mysplit(line)
  115.         if len(pieces) < 3:
  116.             self.invalid = True
  117.             return None
  118.         
  119.         self.type = string.strip(pieces[0])
  120.         if self.type not in ('deb', 'deb-src'):
  121.             self.invalid = True
  122.             return None
  123.         
  124.         self.uri = string.strip(pieces[1])
  125.         if len(self.uri) < 1:
  126.             self.invalid = True
  127.         
  128.         self.dist = string.strip(pieces[2])
  129.         if len(pieces) > 3:
  130.             self.comps = pieces[3:]
  131.         else:
  132.             self.comps = []
  133.  
  134.     
  135.     def set_enabled(self, new_value):
  136.         self.disabled = not new_value
  137.         if new_value == True:
  138.             i = 0
  139.             self.line = string.lstrip(self.line)
  140.             while self.line[i] == '#':
  141.                 i += 1
  142.             self.line = self.line[i:]
  143.         elif string.strip(self.line)[0] != '#':
  144.             self.line = '#' + self.line
  145.         
  146.  
  147.     
  148.     def __str__(self):
  149.         ''' debug helper '''
  150.         return self.str().strip()
  151.  
  152.     
  153.     def str(self):
  154.         ''' return the current line as string '''
  155.         if self.invalid:
  156.             return self.line
  157.         
  158.         line = ''
  159.         if self.disabled:
  160.             line = '# '
  161.         
  162.         line += '%s %s %s' % (self.type, self.uri, self.dist)
  163.         if len(self.comps) > 0:
  164.             line += ' ' + ' '.join(self.comps)
  165.         
  166.         if self.comment != '':
  167.             line += ' #' + self.comment
  168.         
  169.         line += '\n'
  170.         return line
  171.  
  172.  
  173.  
  174. class NullMatcher(object):
  175.     
  176.     def match(self, s):
  177.         return True
  178.  
  179.  
  180.  
  181. class SourcesList:
  182.     
  183.     def __init__(self, withMatcher = True):
  184.         self.list = []
  185.         if withMatcher:
  186.             self.matcher = SourceEntryMatcher()
  187.         else:
  188.             self.matcher = NullMatcher()
  189.         self.refresh()
  190.  
  191.     
  192.     def refresh(self):
  193.         self.list = []
  194.         dir = apt_pkg.Config.FindDir('Dir::Etc')
  195.         file = apt_pkg.Config.Find('Dir::Etc::sourcelist')
  196.         self.load(dir + file)
  197.         partsdir = apt_pkg.Config.FindDir('Dir::Etc::sourceparts')
  198.         for file in glob.glob('%s/*.list' % partsdir):
  199.             self.load(file)
  200.         
  201.         for source in self.list:
  202.             if source.invalid == False:
  203.                 self.matcher.match(source)
  204.                 continue
  205.         
  206.  
  207.     
  208.     def __iter__(self):
  209.         for entry in self.list:
  210.             yield entry
  211.         
  212.         raise StopIteration
  213.  
  214.     
  215.     def add(self, type, uri, dist, comps, comment = '', pos = -1, file = None):
  216.         '''
  217.     Add a new source to the sources.list.
  218.     The method will search for existing matching repos and will try to 
  219.     reuse them as far as possible
  220.     '''
  221.         for source in self.list:
  222.             if source.disabled == False and source.invalid == False and source.type == type and uri == source.uri and source.dist == dist:
  223.                 comps = uniq(source.comps + comps)
  224.                 source.comps = comps
  225.                 return source
  226.                 continue
  227.             if source.disabled == True and source.invalid == False and source.type == type and uri == source.uri and source.dist == dist and len(set(source.comps) & set(comps)) == len(comps):
  228.                 source.disabled = False
  229.                 return source
  230.                 continue
  231.         
  232.         line = '%s %s %s' % (type, uri, dist)
  233.         for c in comps:
  234.             line = line + ' ' + c
  235.         
  236.         if comment != '':
  237.             line = '%s #%s\n' % (line, comment)
  238.         
  239.         line = line + '\n'
  240.         new_entry = SourceEntry(line)
  241.         if file != None:
  242.             new_entry.file = file
  243.         
  244.         self.matcher.match(new_entry)
  245.         self.list.insert(pos, new_entry)
  246.         return new_entry
  247.  
  248.     
  249.     def remove(self, source_entry):
  250.         self.list.remove(source_entry)
  251.  
  252.     
  253.     def restoreBackup(self, backup_ext):
  254.         ''' restore sources.list files based on the backup extension '''
  255.         dir = apt_pkg.Config.FindDir('Dir::Etc')
  256.         file = apt_pkg.Config.Find('Dir::Etc::sourcelist')
  257.         if os.path.exists(dir + file + backup_ext):
  258.             shutil.copy(dir + file + backup_ext, dir + file)
  259.         
  260.         partsdir = apt_pkg.Config.FindDir('Dir::Etc::sourceparts')
  261.         for file in glob.glob('%s/*.list' % partsdir):
  262.             if os.path.exists(file + backup_ext):
  263.                 shutil.copy(file + backup_ext, file)
  264.                 continue
  265.         
  266.  
  267.     
  268.     def backup(self, backup_ext = None):
  269.         ''' make a backup of the current source files, if no backup extension
  270.         is given, the current date/time is used (and returned) '''
  271.         already_backuped = set()
  272.         if backup_ext == None:
  273.             backup_ext = time.strftime('%y%m%d.%H%M')
  274.         
  275.         for source in self.list:
  276.             if source.file not in already_backuped:
  277.                 shutil.copy(source.file, '%s%s' % (source.file, backup_ext))
  278.                 continue
  279.         
  280.         return backup_ext
  281.  
  282.     
  283.     def load(self, file):
  284.         ''' (re)load the current sources '''
  285.         
  286.         try:
  287.             f = open(file, 'r')
  288.             lines = f.readlines()
  289.             for line in lines:
  290.                 source = SourceEntry(line, file)
  291.                 self.list.append(source)
  292.         except:
  293.             print "could not open file '%s'" % file
  294.  
  295.         f.close()
  296.  
  297.     
  298.     def save(self):
  299.         ''' save the current sources '''
  300.         files = { }
  301.         for source in self.list:
  302.             if not files.has_key(source.file):
  303.                 files[source.file] = open(source.file, 'w')
  304.             
  305.             files[source.file].write(source.str())
  306.         
  307.         for f in files:
  308.             files[f].close()
  309.         
  310.  
  311.     
  312.     def check_for_relations(self, sources_list):
  313.         '''get all parent and child channels in the sources list'''
  314.         parents = []
  315.         used_child_templates = { }
  316.         for source in sources_list:
  317.             if source.template == None:
  318.                 continue
  319.             
  320.             if source.template.child == True:
  321.                 key = source.template
  322.                 if not used_child_templates.has_key(key):
  323.                     used_child_templates[key] = []
  324.                 
  325.                 temp = used_child_templates[key]
  326.                 temp.append(source)
  327.                 continue
  328.             if len(source.template.children) > 0:
  329.                 parents.append(source)
  330.                 continue
  331.         
  332.         return (parents, used_child_templates)
  333.  
  334.  
  335.  
  336. class SourceEntryTemplate(SourceEntry):
  337.     
  338.     def __init__(self, a_type, uri, dist, description, comps):
  339.         self.comps_descriptions = []
  340.         self.type = a_type
  341.         self.uri = uri
  342.         self.dist = dist
  343.         self.description = description
  344.         self.comps = comps
  345.  
  346.     
  347.     def matches(self, source_entry):
  348.         ''' check if a given source_entry matches this one '''
  349.         if self.type != source_entry.type:
  350.             return False
  351.         
  352.         if self.dist != source_entry.dist:
  353.             return False
  354.         
  355.         if not is_mirror(self.uri, source_entry.uri):
  356.             return False
  357.         
  358.         for e_comp in source_entry.comps:
  359.             for t_comp in self.comps:
  360.                 if e_comp == t_comp.name:
  361.                     break
  362.                     continue
  363.             else:
  364.                 return False
  365.         
  366.         return True
  367.  
  368.  
  369.  
  370. class SourceCompTemplate:
  371.     
  372.     def __init__(self, name, description, on_by_default):
  373.         self.name = name
  374.         self.description = description
  375.         self.on_by_default = on_by_default
  376.  
  377.  
  378.  
  379. class SourceEntryTemplates:
  380.     
  381.     def __init__(self, datadir):
  382.         _ = gettext.gettext
  383.         self.templates = []
  384.         dinfo = DistInfo(base_dir = datadir + 'channels/')
  385.         for suite in dinfo.suites:
  386.             comps = []
  387.             for comp in suite.components:
  388.                 comps.append(SourceCompTemplate(comp.name, _(comp.description), comp.enabled))
  389.             
  390.             self.templates.append(SourceEntryTemplate(suite.repository_type, suite.base_uri, suite.name, suite.description, comps))
  391.         
  392.  
  393.  
  394.  
  395. class SourceEntryMatcher:
  396.     
  397.     class MatchType:
  398.         
  399.         def __init__(self, a_type, a_descr):
  400.             self.type = a_type
  401.             self.description = a_descr
  402.  
  403.  
  404.     
  405.     class MatchDist:
  406.         
  407.         def __init__(self, a_uri, a_dist, a_descr, l_comps, l_comps_descr):
  408.             self.uri = a_uri
  409.             self.dist = a_dist
  410.             self.description = a_descr
  411.             self.comps = l_comps
  412.             self.comps_descriptions = l_comps_descr
  413.  
  414.  
  415.     
  416.     def __init__(self):
  417.         self.templates = []
  418.         spec_files = glob.glob('/usr/share/update-manager/channels/*.info')
  419.         for f in spec_files:
  420.             f = os.path.basename(f)
  421.             i = f.find('.info')
  422.             f = f[0:i]
  423.             dist = DistInfo(f)
  424.             for suite in dist.suites:
  425.                 if suite.match_uri != None:
  426.                     self.templates.append(suite)
  427.                     continue
  428.             
  429.         
  430.  
  431.     
  432.     def match(self, source):
  433.         '''Add a matching template to the source'''
  434.         _ = gettext.gettext
  435.         found = False
  436.         for template in self.templates:
  437.             if re.search(template.match_uri, source.uri) and re.match(template.match_name, source.dist):
  438.                 found = True
  439.                 source.template = template
  440.                 break
  441.                 continue
  442.         
  443.         return found
  444.  
  445.  
  446.  
  447. class Distribution:
  448.     
  449.     def __init__(self):
  450.         '''"
  451.     Container for distribution specific informations
  452.     '''
  453.         self.id = ''
  454.         self.codename = ''
  455.         self.description = ''
  456.         self.release = ''
  457.         lsb_info = []
  458.         for lsb_option in [
  459.             '-i',
  460.             '-c',
  461.             '-d',
  462.             '-r']:
  463.             pipe = os.popen('lsb_release %s -s' % lsb_option)
  464.             lsb_info.append(pipe.read().strip())
  465.             del pipe
  466.         
  467.         (self.id, self.codename, self.description, self.release) = lsb_info
  468.         self.countries = { }
  469.         
  470.         try:
  471.             f = open('/usr/share/iso-codes/iso_3166.tab', 'r')
  472.             lines = f.readlines()
  473.             for line in lines:
  474.                 parts = line.split('\t')
  475.                 self.countries[parts[0].lower()] = parts[1]
  476.         except:
  477.             print "could not open file '%s'" % file
  478.  
  479.         f.close()
  480.  
  481.     
  482.     def get_sources(self, sources_list):
  483.         '''
  484.     Find the corresponding template, main and child sources 
  485.     for the distribution 
  486.     '''
  487.         self.source_template = None
  488.         self.child_sources = []
  489.         self.main_sources = []
  490.         self.disabled_sources = []
  491.         self.cdrom_sources = []
  492.         self.download_comps = []
  493.         self.enabled_comps = []
  494.         self.cdrom_comps = []
  495.         self.used_media = []
  496.         self.get_source_code = False
  497.         self.source_code_sources = []
  498.         self.default_server = ''
  499.         self.main_server = ''
  500.         self.nearest_server = ''
  501.         self.used_servers = []
  502.         for template in sources_list.matcher.templates:
  503.             if template.name == self.codename and template.distribution == self.id:
  504.                 self.source_template = template
  505.                 break
  506.                 continue
  507.         
  508.         if self.source_template == None:
  509.             print 'Error: could not find a distribution template'
  510.             sys.exit(1)
  511.         
  512.         media = []
  513.         comps = []
  514.         cdrom_comps = []
  515.         enabled_comps = []
  516.         source_code = []
  517.         for source in sources_list.list:
  518.             if source.invalid == False and source.dist == self.codename and source.template and source.template.name == self.codename:
  519.                 if source.uri.startswith('cdrom:') and source.disabled == False:
  520.                     self.cdrom_sources.append(source)
  521.                     cdrom_comps.extend(source.comps)
  522.                 elif source.uri.startswith('cdrom:') and source.disabled == True:
  523.                     self.cdrom_sources.append(source)
  524.                 elif source.type == 'deb' and source.disabled == False:
  525.                     self.main_sources.append(source)
  526.                     comps.extend(source.comps)
  527.                     media.append(source.uri)
  528.                 elif source.type == 'deb' and source.disabled == True:
  529.                     self.disabled_sources.append(source)
  530.                 elif source.type.endswith('-src') and source.disabled == False:
  531.                     self.source_code_sources.append(source)
  532.                 elif source.type.endswith('-src') and source.disabled == True:
  533.                     self.disabled_sources.append(source)
  534.                 
  535.             
  536.             if source.template in self.source_template.children:
  537.                 if source.type == 'deb':
  538.                     self.child_sources.append(source)
  539.                 elif source.type == 'deb-src':
  540.                     self.source_code_sources.append(source)
  541.                 
  542.             source.type == 'deb'
  543.         
  544.         self.download_comps = set(comps)
  545.         self.cdrom_comps = set(cdrom_comps)
  546.         enabled_comps.extend(comps)
  547.         enabled_comps.extend(cdrom_comps)
  548.         self.enabled_comps = set(enabled_comps)
  549.         self.used_media = set(media)
  550.         self.get_mirrors()
  551.  
  552.     
  553.     def get_mirrors(self):
  554.         '''
  555.     Provide a set of mirrors where you can get the distribution from
  556.     '''
  557.         self.main_server = self.source_template.base_uri
  558.         if self.id == 'Ubuntu':
  559.             locale = os.getenv('LANG', default = 'en.UK')
  560.             a = locale.find('_')
  561.             z = locale.find('.')
  562.             if z == -1:
  563.                 z = len(locale)
  564.             
  565.             country_code = locale[a + 1:z].lower()
  566.             self.nearest_server = 'http://%s.archive.ubuntu.com/ubuntu/' % country_code
  567.             if self.countries.has_key(country_code):
  568.                 self.country = self.countries[country_code]
  569.             else:
  570.                 self.country = None
  571.         
  572.         for medium in self.used_media:
  573.             if not medium.startswith('cdrom:'):
  574.                 self.used_servers.append(medium)
  575.                 continue
  576.         
  577.         if len(self.main_sources) == 0:
  578.             self.default_server = self.main_server
  579.         else:
  580.             self.default_server = self.main_sources[0].uri
  581.  
  582.     
  583.     def add_source(self, sources_list, type = None, uri = None, dist = None, comps = None, comment = ''):
  584.         '''
  585.     Add distribution specific sources
  586.     '''
  587.         if uri == None:
  588.             uri = self.default_server
  589.         
  590.         if dist == None:
  591.             dist = self.codename
  592.         
  593.         if comps == None:
  594.             comps = list(self.enabled_comps)
  595.         
  596.         if type == None:
  597.             type = 'deb'
  598.         
  599.         if comment == '':
  600.             comment == 'Added by software-properties'
  601.         
  602.         new_source = sources_list.add(type, uri, dist, comps, comment)
  603.         if self.get_source_code == True and not type.endswith('-src'):
  604.             sources_list.add('%s-src' % type, uri, dist, comps, comment, file = new_source.file, pos = sources_list.list.index(new_source) + 1)
  605.         
  606.  
  607.     
  608.     def enable_component(self, sourceslist, comp):
  609.         '''
  610.     Disable a component in all main, child and source code sources
  611.     (excluding cdrom based sources)
  612.  
  613.     sourceslist:  an aptsource.sources_list
  614.     comp:         the component that should be enabled
  615.     '''
  616.         sources = []
  617.         sources.extend(self.main_sources)
  618.         sources.extend(self.child_sources)
  619.         sources.extend(self.source_code_sources)
  620.         if len(self.main_sources) < 1:
  621.             self.add_source(sourceslist, comps = [
  622.                 '%s' % comp])
  623.         else:
  624.             for source in sources:
  625.                 if comp not in source.comps:
  626.                     source.comps.append(comp)
  627.                     continue
  628.             
  629.         if self.get_source_code == True:
  630.             for source in self.source_code_sources:
  631.                 if comp not in source.comps:
  632.                     source.comps.append(comp)
  633.                     continue
  634.             
  635.         
  636.  
  637.     
  638.     def disable_component(self, sourceslist, comp):
  639.         '''
  640.     Disable a component in all main, child and source code sources
  641.     (excluding cdrom based sources)
  642.     '''
  643.         sources = []
  644.         sources.extend(self.main_sources)
  645.         sources.extend(self.child_sources)
  646.         sources.extend(self.source_code_sources)
  647.         if comp in self.cdrom_comps:
  648.             sources = []
  649.             sources.extend(self.main_sources)
  650.         
  651.         for source in sources:
  652.             if comp in source.comps:
  653.                 source.comps.remove(comp)
  654.                 if len(source.comps) < 1:
  655.                     sourceslist.remove(source)
  656.                 
  657.             len(source.comps) < 1
  658.         
  659.  
  660.  
  661. if __name__ == '__main__':
  662.     apt_pkg.InitConfig()
  663.     sources = SourcesList()
  664.     for entry in sources:
  665.         print entry.str()
  666.     
  667.     mirror = is_mirror('http://archive.ubuntu.com/ubuntu/', 'http://de.archive.ubuntu.com/ubuntu/')
  668.     print 'is_mirror(): %s' % mirror
  669.     print is_mirror('http://archive.ubuntu.com/ubuntu', 'http://de.archive.ubuntu.com/ubuntu/')
  670.  
  671.