home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / lib / python2.6 / dist-packages / apt / debfile.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2009-04-20  |  16.2 KB  |  555 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. '''Classes for working with locally available Debian packages.'''
  5. from gettext import gettext as _
  6. import os
  7. import sys
  8. import apt_inst
  9. import apt_pkg
  10. (VERSION_NONE, VERSION_OUTDATED, VERSION_SAME, VERSION_NEWER) = range(4)
  11.  
  12. class NoDebArchiveException(IOError):
  13.     '''Exception which is raised if a file is no Debian archive.'''
  14.     pass
  15.  
  16.  
  17. class DebPackage(object):
  18.     '''A Debian Package (.deb file).'''
  19.     _supported_data_members = ('data.tar.gz', 'data.tar.bz2', 'data.tar.lzma')
  20.     debug = 0
  21.     
  22.     def __init__(self, filename = None, cache = None):
  23.         self._cache = cache
  24.         self._need_pkgs = []
  25.         self._sections = { }
  26.         self._installed_conflicts = set()
  27.         self._failure_string = ''
  28.         if filename:
  29.             self.open(filename)
  30.         
  31.  
  32.     
  33.     def open(self, filename):
  34.         ''' open given debfile '''
  35.         self.filename = filename
  36.         if not apt_inst.arCheckMember(open(self.filename), 'debian-binary'):
  37.             raise NoDebArchiveException(_("This is not a valid DEB archive, missing '%s' member" % 'debian-binary'))
  38.         apt_inst.arCheckMember(open(self.filename), 'debian-binary')
  39.         control = apt_inst.debExtractControl(open(self.filename))
  40.         self._sections = apt_pkg.ParseSection(control)
  41.         self.pkgname = self._sections['Package']
  42.  
  43.     
  44.     def __getitem__(self, key):
  45.         return self._sections[key]
  46.  
  47.     
  48.     def filelist(self):
  49.         '''return the list of files in the deb.'''
  50.         files = []
  51.         
  52.         def extract_cb(what, name, *_):
  53.             files.append(name)
  54.  
  55.         for member in self._supported_data_members:
  56.             if apt_inst.arCheckMember(open(self.filename), member):
  57.                 
  58.                 try:
  59.                     apt_inst.debExtract(open(self.filename), extract_cb, member)
  60.                 except SystemError:
  61.                     (None,)
  62.                     (None,)
  63.                     return [
  64.                         _("List of files for '%s'could not be read" % self.filename)]
  65.                 
  66.  
  67.             (None,)<EXCEPTION MATCH>SystemError
  68.         
  69.         return files
  70.  
  71.     filelist = property(filelist)
  72.     
  73.     def _is_or_group_satisfied(self, or_group):
  74.         """Return True if at least one dependency of the or-group is satisfied.
  75.  
  76.         This method gets an 'or_group' and analyzes if at least one dependency
  77.         of this group is already satisfied.
  78.         """
  79.         self._dbg(2, '_checkOrGroup(): %s ' % or_group)
  80.         for dep in or_group:
  81.             depname = dep[0]
  82.             ver = dep[1]
  83.             oper = dep[2]
  84.             if depname not in self._cache:
  85.                 if self._cache.isVirtualPackage(depname):
  86.                     self._dbg(3, '_isOrGroupSatisfied(): %s is virtual dep' % depname)
  87.                     for pkg in self._cache.getProvidingPackages(depname):
  88.                         if pkg.isInstalled:
  89.                             return True
  90.                     
  91.                 pkg.isInstalled
  92.                 continue
  93.             
  94.             inst = self._cache[depname]
  95.             instver = inst.installedVersion
  96.             if instver is not None and apt_pkg.CheckDep(instver, oper, ver):
  97.                 return True
  98.         
  99.         return False
  100.  
  101.     
  102.     def _satisfy_or_group(self, or_group):
  103.         '''Try to satisfy the or_group.'''
  104.         for dep in or_group:
  105.             (depname, ver, oper) = dep
  106.             if depname not in self._cache:
  107.                 if not self._cache.isVirtualPackage(depname):
  108.                     continue
  109.                 
  110.                 providers = self._cache.getProvidingPackages(depname)
  111.                 if len(providers) != 1:
  112.                     continue
  113.                 
  114.                 depname = providers[0].name
  115.             
  116.             pkg = self._cache[depname]
  117.             cand = self._cache._depcache.GetCandidateVer(pkg._pkg)
  118.             if not cand:
  119.                 continue
  120.             
  121.             if not apt_pkg.CheckDep(cand.VerStr, oper, ver):
  122.                 continue
  123.             
  124.             self._dbg(2, 'Need to get: %s' % depname)
  125.             self._need_pkgs.append(depname)
  126.             return True
  127.         
  128.         or_str = ''
  129.         for dep in or_group:
  130.             or_str += dep[0]
  131.             if dep != or_group[-1]:
  132.                 or_str += '|'
  133.                 continue
  134.         
  135.         self._failure_string += _('Dependency is not satisfiable: %s\n' % or_str)
  136.         return False
  137.  
  138.     
  139.     def _check_single_pkg_conflict(self, pkgname, ver, oper):
  140.         '''Return True if a pkg conflicts with a real installed/marked pkg.'''
  141.         self._dbg(3, "_checkSinglePkgConflict() pkg='%s' ver='%s' oper='%s'" % (pkgname, ver, oper))
  142.         pkg = self._cache[pkgname]
  143.         if pkg.isInstalled:
  144.             pkgver = pkg.installedVersion
  145.         elif pkg.markedInstall:
  146.             pkgver = pkg.candidateVersion
  147.         else:
  148.             return False
  149.         if pkg.isInstalled.CheckDep(pkgver, oper, ver) and not self.replaces_real_pkg(pkgname, oper, ver):
  150.             self._failure_string += _("Conflicts with the installed package '%s'" % pkg.name)
  151.             return True
  152.         return False
  153.  
  154.     
  155.     def _check_conflicts_or_group(self, or_group):
  156.         '''Check the or-group for conflicts with installed pkgs.'''
  157.         self._dbg(2, '_check_conflicts_or_group(): %s ' % or_group)
  158.         or_found = False
  159.         virtual_pkg = None
  160.         for dep in or_group:
  161.             depname = dep[0]
  162.             ver = dep[1]
  163.             oper = dep[2]
  164.             if depname not in self._cache:
  165.                 if self._cache.isVirtualPackage(depname):
  166.                     for pkg in self._cache.getProvidingPackages(depname):
  167.                         self._dbg(3, 'conflicts virtual check: %s' % pkg.name)
  168.                         if self.pkgname == pkg.name:
  169.                             self._dbg(3, 'conflict on self, ignoring')
  170.                             continue
  171.                         
  172.                         if self._check_single_pkg_conflict(pkg.name, ver, oper):
  173.                             self._installed_conflicts.add(pkg.name)
  174.                             continue
  175.                     
  176.                 continue
  177.             
  178.             if self._check_single_pkg_conflict(depname, ver, oper):
  179.                 self._installed_conflicts.add(depname)
  180.                 continue
  181.         
  182.         return bool(self._installed_conflicts)
  183.  
  184.     
  185.     def conflicts(self):
  186.         '''List of package names conflicting with this package.'''
  187.         key = 'Conflicts'
  188.         
  189.         try:
  190.             return apt_pkg.ParseDepends(self._sections[key])
  191.         except KeyError:
  192.             return []
  193.  
  194.  
  195.     conflicts = property(conflicts)
  196.     
  197.     def depends(self):
  198.         '''List of package names on which this package depends on.'''
  199.         depends = []
  200.         for key in ('Depends', 'PreDepends'):
  201.             
  202.             try:
  203.                 depends.extend(apt_pkg.ParseDepends(self._sections[key]))
  204.             continue
  205.             except KeyError:
  206.                 continue
  207.             
  208.  
  209.         
  210.         return depends
  211.  
  212.     depends = property(depends)
  213.     
  214.     def provides(self):
  215.         '''List of virtual packages which are provided by this package.'''
  216.         key = 'Provides'
  217.         
  218.         try:
  219.             return apt_pkg.ParseDepends(self._sections[key])
  220.         except KeyError:
  221.             return []
  222.  
  223.  
  224.     provides = property(provides)
  225.     
  226.     def replaces(self):
  227.         '''List of packages which are replaced by this package.'''
  228.         key = 'Replaces'
  229.         
  230.         try:
  231.             return apt_pkg.ParseDepends(self._sections[key])
  232.         except KeyError:
  233.             return []
  234.  
  235.  
  236.     replaces = property(replaces)
  237.     
  238.     def replaces_real_pkg(self, pkgname, oper, ver):
  239.         '''Return True if a given non-virtual package is replaced.
  240.  
  241.         Return True if the deb packages replaces a real (not virtual)
  242.         packages named (pkgname, oper, ver).
  243.         '''
  244.         self._dbg(3, 'replacesPkg() %s %s %s' % (pkgname, oper, ver))
  245.         pkg = self._cache[pkgname]
  246.         if pkg.isInstalled:
  247.             pkgver = pkg.installedVersion
  248.         elif pkg.markedInstall:
  249.             pkgver = pkg.candidateVersion
  250.         else:
  251.             pkgver = None
  252.         for or_group in self.replaces:
  253.             for name, ver, oper in or_group:
  254.                 if name == pkgname and apt_pkg.CheckDep(pkgver, oper, ver):
  255.                     self._dbg(3, "we have a replaces in our package for the conflict against '%s'" % pkgname)
  256.                     return True
  257.             
  258.         
  259.         return False
  260.  
  261.     
  262.     def check_conflicts(self):
  263.         '''Check if there are conflicts with existing or selected packages.
  264.  
  265.         Check if the package conflicts with a existing or to be installed
  266.         package. Return True if the pkg is OK.
  267.         '''
  268.         res = True
  269.         for or_group in self.conflicts:
  270.             if self._check_conflicts_or_group(or_group):
  271.                 res = False
  272.                 continue
  273.         
  274.         return res
  275.  
  276.     
  277.     def compare_to_version_in_cache(self, use_installed = True):
  278.         '''Compare the package to the version available in the cache.
  279.  
  280.         Checks if the package is already installed or availabe in the cache
  281.         and if so in what version, returns one of (VERSION_NONE,
  282.         VERSION_OUTDATED, VERSION_SAME, VERSION_NEWER).
  283.         '''
  284.         self._dbg(3, 'compareToVersionInCache')
  285.         pkgname = self._sections['Package']
  286.         debver = self._sections['Version']
  287.         self._dbg(1, 'debver: %s' % debver)
  288.         if pkgname in self._cache:
  289.             if use_installed:
  290.                 cachever = self._cache[pkgname].installedVersion
  291.             else:
  292.                 cachever = self._cache[pkgname].candidateVersion
  293.             if cachever is not None:
  294.                 cmp = apt_pkg.VersionCompare(cachever, debver)
  295.                 self._dbg(1, 'CompareVersion(debver,instver): %s' % cmp)
  296.                 if cmp == 0:
  297.                     return VERSION_SAME
  298.                 if cmp < 0:
  299.                     return VERSION_NEWER
  300.                 if cmp > 0:
  301.                     return VERSION_OUTDATED
  302.             
  303.         
  304.         return VERSION_NONE
  305.  
  306.     
  307.     def check(self):
  308.         '''Check if the package is installable.'''
  309.         self._dbg(3, 'checkDepends')
  310.         arch = self._sections['Architecture']
  311.         if arch != 'all' and arch != apt_pkg.Config.Find('APT::Architecture'):
  312.             self._dbg(1, 'ERROR: Wrong architecture dude!')
  313.             self._failure_string = _("Wrong architecture '%s'" % arch)
  314.             return False
  315.         if self.compare_to_version_in_cache() == VERSION_OUTDATED:
  316.             self._failure_string = _('A later version is already installed')
  317.             return False
  318.         self._failure_string = ''
  319.         if not self.check_conflicts():
  320.             return False
  321.         if not self._satisfy_depends(self.depends):
  322.             return False
  323.         if not self.check_conflicts():
  324.             return False
  325.         if self._cache._depcache.BrokenCount > 0:
  326.             self._failure_string = _('Failed to satisfy all dependencies (broken cache)')
  327.             self._cache.clear()
  328.             return False
  329.         return True
  330.  
  331.     
  332.     def satisfy_depends_str(self, dependsstr):
  333.         '''Satisfy the dependencies in the given string.'''
  334.         return self._satisfy_depends(apt_pkg.ParseDepends(dependsstr))
  335.  
  336.     
  337.     def _satisfy_depends(self, depends):
  338.         '''Satisfy the dependencies.'''
  339.         
  340.         try:
  341.             _actiongroup = apt_pkg.GetPkgActionGroup(self._cache._depcache)
  342.         except AttributeError:
  343.             pass
  344.  
  345.         for or_group in depends:
  346.             if not self._is_or_group_satisfied(or_group):
  347.                 if not self._satisfy_or_group(or_group):
  348.                     return False
  349.                 continue
  350.             self._satisfy_or_group(or_group)
  351.         
  352.         for pkg in self._need_pkgs:
  353.             
  354.             try:
  355.                 self._cache[pkg].markInstall(fromUser = False)
  356.             continue
  357.             except SystemError:
  358.                 e = None
  359.                 self._failure_string = _("Cannot install '%s'" % pkg)
  360.                 self._cache.clear()
  361.                 return False
  362.             
  363.  
  364.         
  365.         return True
  366.  
  367.     
  368.     def missing_deps(self):
  369.         '''Return missing dependencies.'''
  370.         self._dbg(1, 'Installing: %s' % self._need_pkgs)
  371.         if self._need_pkgs is None:
  372.             self.check()
  373.         
  374.         return self._need_pkgs
  375.  
  376.     missing_deps = property(missing_deps)
  377.     
  378.     def required_changes(self):
  379.         '''Get the changes required to satisfy the dependencies.
  380.  
  381.         Returns: a tuple with (install, remove, unauthenticated)
  382.         '''
  383.         install = []
  384.         remove = []
  385.         unauthenticated = []
  386.         for pkg in self._cache:
  387.             if pkg.markedInstall or pkg.markedUpgrade:
  388.                 install.append(pkg.name)
  389.                 authenticated = False
  390.                 for origin in pkg.candidateOrigin:
  391.                     authenticated |= origin.trusted
  392.                 
  393.                 if not authenticated:
  394.                     unauthenticated.append(pkg.name)
  395.                 
  396.             
  397.             if pkg.markedDelete:
  398.                 remove.append(pkg.name)
  399.                 continue
  400.         
  401.         return (install, remove, unauthenticated)
  402.  
  403.     required_changes = property(required_changes)
  404.     
  405.     def _dbg(self, level, msg):
  406.         '''Write debugging output to sys.stderr.'''
  407.         if level <= self.debug:
  408.             print >>sys.stderr, msg
  409.         
  410.  
  411.     
  412.     def install(self, install_progress = None):
  413.         '''Install the package.'''
  414.         if install_progress is None:
  415.             return os.system('dpkg -i %s' % self.filename)
  416.         
  417.         try:
  418.             install_progress.start_update()
  419.         except AttributeError:
  420.             install_progress is None
  421.             install_progress is None
  422.             install_progress.startUpdate()
  423.         except:
  424.             install_progress is None
  425.  
  426.         res = install_progress.run(self.filename)
  427.         
  428.         try:
  429.             install_progress.finish_update()
  430.         except AttributeError:
  431.             install_progress is None
  432.             install_progress is None
  433.             install_progress.finishUpdate()
  434.         except:
  435.             install_progress is None
  436.  
  437.         return res
  438.  
  439.  
  440.  
  441. class DscSrcPackage(DebPackage):
  442.     '''A locally available source package.'''
  443.     
  444.     def __init__(self, filename = None, cache = None):
  445.         DebPackage.__init__(self, None, cache)
  446.         self._depends = []
  447.         self._conflicts = []
  448.         self._binaries = []
  449.         if filename is not None:
  450.             self.open(filename)
  451.         
  452.  
  453.     
  454.     def depends(self):
  455.         '''Return the dependencies of the package'''
  456.         return self._depends
  457.  
  458.     depends = property(depends)
  459.     
  460.     def conflicts(self):
  461.         '''Return the dependencies of the package'''
  462.         return self._conflicts
  463.  
  464.     conflicts = property(conflicts)
  465.     
  466.     def open(self, file):
  467.         '''Open the package.'''
  468.         depends_tags = [
  469.             'Build-Depends',
  470.             'Build-Depends-Indep']
  471.         conflicts_tags = [
  472.             'Build-Conflicts',
  473.             'Build-Conflicts-Indep']
  474.         fobj = open(file)
  475.         tagfile = apt_pkg.ParseTagFile(fobj)
  476.         sec = tagfile.Section
  477.         
  478.         try:
  479.             while tagfile.Step() == 1:
  480.                 for tag in depends_tags:
  481.                     if not sec.has_key(tag):
  482.                         continue
  483.                     
  484.                     self._depends.extend(apt_pkg.ParseSrcDepends(sec[tag]))
  485.                 
  486.                 for tag in conflicts_tags:
  487.                     if not sec.has_key(tag):
  488.                         continue
  489.                     
  490.                     self._conflicts.extend(apt_pkg.ParseSrcDepends(sec[tag]))
  491.                 
  492.                 if sec.has_key('Source'):
  493.                     self.pkgname = sec['Source']
  494.                 
  495.                 if sec.has_key('Binary'):
  496.                     self.binaries = sec['Binary'].split(', ')
  497.                 
  498.                 if sec.has_key('Version'):
  499.                     self._sections['Version'] = sec['Version']
  500.                     continue
  501.         finally:
  502.             del sec
  503.             del tagfile
  504.             fobj.close()
  505.  
  506.         s = _("Install Build-Dependencies for source package '%s' that builds %s\n") % (self.pkgname, ' '.join(self.binaries))
  507.         self._sections['Description'] = s
  508.  
  509.     
  510.     def check(self):
  511.         '''Check if the package is installable..'''
  512.         if not self.check_conflicts():
  513.             for pkgname in self._installed_conflicts:
  514.                 if self._cache[pkgname]._pkg.Essential:
  515.                     raise Exception(_('An essential package would be removed'))
  516.                 self._cache[pkgname]._pkg.Essential
  517.                 self._cache[pkgname].markDelete()
  518.             
  519.         
  520.         return self._satisfy_depends(self.depends)
  521.  
  522.  
  523.  
  524. def _test():
  525.     '''Test function'''
  526.     Cache = Cache
  527.     import apt.cache
  528.     DpkgInstallProgress = DpkgInstallProgress
  529.     import apt.progress
  530.     cache = Cache()
  531.     vp = 'www-browser'
  532.     providers = cache.getProvidingPackages(vp)
  533.     print 'Providers for %s :' % vp
  534.     for pkg in providers:
  535.         print ' %s' % pkg.name
  536.     
  537.     d = DebPackage(sys.argv[1], cache)
  538.     print 'Deb: %s' % d.pkgname
  539.     if not d.check():
  540.         print "can't be satified"
  541.         print d._failure_string
  542.     
  543.     print 'missing deps: %s' % d.missing_deps
  544.     print d.required_changes
  545.     print 'Installing ...'
  546.     ret = d.install(DpkgInstallProgress())
  547.     print ret
  548.     s = DscSrcPackage(cache = cache)
  549.     d = 'libc6 (>= 2.3.2), libaio (>= 0.3.96) | libaio1 (>= 0.3.96)'
  550.     print s._satisfy_depends(apt_pkg.ParseDepends(d))
  551.  
  552. if __name__ == '__main__':
  553.     _test()
  554.  
  555.