home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2006 November (DVD) / PCWELT_11_2006.ISO / casper / filesystem.squashfs / usr / share / pycentral / python-apt / site-packages / apt / package.py < prev    next >
Encoding:
Python Source  |  2006-08-14  |  13.6 KB  |  385 lines

  1. # package.py - apt package abstraction
  2. #  
  3. #  Copyright (c) 2005 Canonical
  4. #  
  5. #  Author: Michael Vogt <michael.vogt@ubuntu.com>
  6. #  This program is free software; you can redistribute it and/or 
  7. #  modify it under the terms of the GNU General Public License as 
  8. #  published by the Free Software Foundation; either version 2 of the
  9. #  License, or (at your option) any later version.
  10. #  This program is distributed in the hope that it will be useful,
  11. #  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. #  GNU General Public License for more details.
  14. #  You should have received a copy of the GNU General Public License
  15. #  along with this program; if not, write to the Free Software
  16. #  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
  17. #  USA
  18.  
  19. import apt_pkg
  20. import sys
  21. import random
  22. import string
  23.  
  24.  
  25. class Package(object):
  26.     """ This class represents a package in the cache
  27.     """
  28.     def __init__(self, cache, depcache, records, sourcelist, pcache, pkgiter):
  29.         """ Init the Package object """
  30.         self._cache = cache             # low level cache
  31.         self._depcache = depcache
  32.         self._records = records
  33.         self._pkg = pkgiter
  34.         self._list = sourcelist               # sourcelist
  35.         self._pcache = pcache           # python cache in cache.py
  36.         pass
  37.  
  38.     # helper
  39.     def _lookupRecord(self, UseCandidate=True):
  40.         """ internal helper that moves the Records to the right
  41.             position, must be called before _records is accessed """
  42.         if UseCandidate:
  43.             ver = self._depcache.GetCandidateVer(self._pkg)
  44.         else:
  45.             ver = self._pkg.CurrentVer
  46.  
  47.         # check if we found a version
  48.         if ver == None:
  49.             #print "No version for: %s (Candidate: %s)" % (self._pkg.Name, UseCandidate)
  50.             return False
  51.         
  52.         if ver.FileList == None:
  53.             print "No FileList for: %s " % self._pkg.Name()
  54.             return False
  55.         f, index = ver.FileList.pop(0)
  56.         self._records.Lookup((f,index))
  57.         return True
  58.  
  59.  
  60.     # basic information (implemented as properties)
  61.  
  62.     # FIXME once python2.3 is dropped we can use @property instead
  63.     # of name = property(name)
  64.  
  65.     def name(self):
  66.         """ Return the name of the package """
  67.         return self._pkg.Name
  68.     name = property(name)
  69.  
  70.     def id(self):
  71.         """ Return a uniq ID for the pkg, can be used to store
  72.             additional information about the pkg """
  73.         return self._pkg.ID
  74.     id = property(id)
  75.  
  76.     def installedVersion(self):
  77.         """ Return the installed version as string """
  78.         ver = self._pkg.CurrentVer
  79.         if ver != None:
  80.             return ver.VerStr
  81.         else:
  82.             return None
  83.     installedVersion = property(installedVersion)
  84.  
  85.     def candidateVersion(self):
  86.         """ Return the candidate version as string """
  87.         ver = self._depcache.GetCandidateVer(self._pkg)
  88.         if ver != None:
  89.             return ver.VerStr
  90.         else:
  91.             return None
  92.     candidateVersion = property(candidateVersion)
  93.  
  94.     def _downloadable(self, useCandidate=True):
  95.         """ helper, return if the version is downloadable """
  96.         if useCandidate:
  97.             ver = self._depcache.GetCandidateVer(self._pkg)
  98.         else:
  99.             ver = self._pkg.CurrentVer
  100.         if ver == None:
  101.             return False
  102.         return ver.Downloadable
  103.     def candidateDownloadable(self):
  104.         " returns if the canidate is downloadable "
  105.         return self._downloadable(useCandidate=True)
  106.     candidateDownloadable = property(candidateDownloadable)
  107.  
  108.     def installedDownloadable(self):
  109.         " returns if the installed version is downloadable "
  110.         return self._downloadable(useCandidate=False)
  111.     installedDownloadable = property(installedDownloadable)
  112.  
  113.     def sourcePackageName(self):
  114.         """ Return the source package name as string """
  115.         if not self._lookupRecord():
  116.             return None
  117.         src = self._records.SourcePkg
  118.         if src != "":
  119.             return src
  120.         else:
  121.             return self._pkg.Name
  122.     sourcePackageName = property(sourcePackageName)
  123.  
  124.     def section(self):
  125.         """ Return the section of the package"""
  126.         return self._pkg.Section
  127.     section = property(section)
  128.  
  129.     def priority(self):
  130.         """ Return the priority (of the candidate version)"""
  131.         ver = self._depcache.GetCandidateVer(self._pkg)
  132.         if ver:
  133.             return ver.PriorityStr
  134.         else:
  135.             return None
  136.     priority = property(priority)
  137.  
  138.     def installedPriority(self):
  139.         """ Return the priority (of the installed version)"""
  140.         ver = self._depcache.GetCandidateVer(self._pkg)
  141.         if ver:
  142.             return ver.PriorityStr
  143.         else:
  144.             return None
  145.     installedPriority = property(installedPriority)
  146.  
  147.     def summary(self):
  148.         """ Return the short description (one line summary) """
  149.         if not self._lookupRecord():
  150.             return ""
  151.         ver = self._depcache.GetCandidateVer(self._pkg)
  152.         desc_iter = ver.TranslatedDescription
  153.         self._records.Lookup(desc_iter.FileList.pop(0))
  154.         return self._records.ShortDesc
  155.     summary = property(summary)
  156.  
  157.     def description(self, format=True):
  158.         """ Return the formated long description """
  159.         if not self._lookupRecord():
  160.             return ""
  161.         # get the translated description
  162.         ver = self._depcache.GetCandidateVer(self._pkg)
  163.         desc_iter = ver.TranslatedDescription
  164.         self._records.Lookup(desc_iter.FileList.pop(0))
  165.         desc = ""
  166.         for line in string.split(unicode(self._records.LongDesc,"utf-8"),"\n"):
  167.                 tmp = string.strip(line)
  168.                 if tmp == ".":
  169.                     desc += "\n"
  170.                 else:
  171.                     desc += tmp + "\n"
  172.         return desc
  173.     description = property(description)
  174.  
  175.     def rawDescription(self):
  176.         """ return the long description (raw)"""
  177.         if not self._lookupRecord():
  178.             return ""
  179.         return self._records.LongDesc
  180.     rawDescription = property(rawDescription)
  181.         
  182.  
  183.     # depcache states
  184.     def markedInstall(self):
  185.         """ Package is marked for install """
  186.         return self._depcache.MarkedInstall(self._pkg)
  187.     markedInstall = property(markedInstall)
  188.  
  189.     def markedUpgrade(self):
  190.         """ Package is marked for upgrade """
  191.         return self._depcache.MarkedUpgrade(self._pkg)
  192.     markedUpgrade = property(markedUpgrade)
  193.  
  194.     def markedDelete(self):
  195.         """ Package is marked for delete """
  196.         return self._depcache.MarkedDelete(self._pkg)
  197.     markedDelete = property(markedDelete) 
  198.  
  199.     def markedKeep(self):
  200.         """ Package is marked for keep """
  201.         return self._depcache.MarkedKeep(self._pkg)
  202.     markedKeep = property(markedKeep)
  203.  
  204.     def markedDowngrade(self):
  205.         """ Package is marked for downgrade """
  206.         return self._depcache.MarkedDowngrade(self._pkg)
  207.     markedDowngrade = property(markedDowngrade)
  208.  
  209.     def markedReinstall(self):
  210.         """ Package is marked for reinstall """
  211.         return self._depcache.MarkedReinstall(self._pkg)
  212.     markedReinstall = property(markedReinstall)
  213.  
  214.     def isInstalled(self):
  215.         """ Package is installed """
  216.         return (self._pkg.CurrentVer != None)
  217.     isInstalled = property(isInstalled)
  218.  
  219.     def isUpgradable(self):
  220.         """ Package is upgradable """    
  221.         return self.isInstalled and self._depcache.IsUpgradable(self._pkg)
  222.     isUpgradable = property(isUpgradable)
  223.  
  224.     # size
  225.     def packageSize(self):
  226.         """ The size of the candidate deb package """
  227.         ver = self._depcache.GetCandidateVer(self._pkg)
  228.         return ver.Size
  229.     packageSize = property(packageSize)
  230.  
  231.     def installedPackageSize(self):
  232.         """ The size of the installed deb package """
  233.         ver = self._pkg.CurrentVer
  234.         return ver.Size
  235.     installedPackageSize = property(installedPackageSize)
  236.  
  237.     def candidateInstalledSize(self, UseCandidate=True):
  238.         """ The size of the candidate installed package """
  239.         ver = self._depcache.GetCandidateVer(self._pkg)
  240.     candidateInstalledSize = property(candidateInstalledSize)
  241.  
  242.     def installedSize(self):
  243.         """ The size of the currently installed package """
  244.         ver = self._pkg.CurrentVer
  245.         return ver.InstalledSize
  246.     installedSize = property(installedSize)
  247.  
  248.     # canidate origin
  249.     class Origin:
  250.         def __init__(self, pkg, VerFileIter):
  251.             self.component = VerFileIter.Component
  252.             self.archive = VerFileIter.Archive
  253.             self.origin = VerFileIter.Origin
  254.             self.label = VerFileIter.Label
  255.             self.site = VerFileIter.Site
  256.             # check the trust
  257.             indexfile = pkg._list.FindIndex(VerFileIter)
  258.             if indexfile and indexfile.IsTrusted:
  259.                 self.trusted = True
  260.             else:
  261.                 self.trusted = False
  262.         def __repr__(self):
  263.             return "component: '%s' archive: '%s' origin: '%s' label: '%s' " \
  264.                    "site '%s' isTrusted: '%s'"%  (self.component, self.archive,
  265.                                                   self.origin, self.label,
  266.                                                   self.site, self.trusted)
  267.         
  268.     def candidateOrigin(self):
  269.         ver = self._depcache.GetCandidateVer(self._pkg)
  270.         if not ver:
  271.             return None
  272.         origins = []
  273.         for (verFileIter,index) in ver.FileList:
  274.             origins.append(self.Origin(self, verFileIter))
  275.         return origins
  276.     candidateOrigin = property(candidateOrigin)
  277.  
  278.     # depcache actions
  279.     def markKeep(self):
  280.         """ mark a package for keep """
  281.         self._pcache.cachePreChange()
  282.         self._depcache.MarkKeep(self._pkg)
  283.         self._pcache.cachePostChange()
  284.     def markDelete(self, autoFix=True, purge=False):
  285.         """ mark a package for delete. Run the resolver if autoFix is set.
  286.             Mark the package as purge (remove with configuration) if 'purge'
  287.             is set.
  288.             """
  289.         self._pcache.cachePreChange()
  290.         self._depcache.MarkDelete(self._pkg, purge)
  291.         # try to fix broken stuffsta
  292.         if autoFix and self._depcache.BrokenCount > 0:
  293.             Fix = apt_pkg.GetPkgProblemResolver(self._depcache)
  294.             Fix.Clear(self._pkg)
  295.             Fix.Protect(self._pkg)
  296.             Fix.Remove(self._pkg)
  297.             Fix.InstallProtect()
  298.             Fix.Resolve()
  299.         self._pcache.cachePostChange()
  300.     def markInstall(self, autoFix=True, autoInst=True):
  301.         """ mark a package for install. Run the resolver if autoFix is set,
  302.             automatically install required dependencies if autoInst is set
  303.         """
  304.         self._pcache.cachePreChange()
  305.         self._depcache.MarkInstall(self._pkg, autoInst)
  306.         # try to fix broken stuff
  307.         if autoFix and self._depcache.BrokenCount > 0:
  308.             fixer = apt_pkg.GetPkgProblemResolver(self._depcache)
  309.             fixer.Clear(self._pkg)
  310.             fixer.Protect(self._pkg)
  311.             fixer.Resolve(True)
  312.         self._pcache.cachePostChange()
  313.     def markUpgrade(self):
  314.         """ mark a package for upgrade """
  315.         if self.isUpgradable:
  316.             self.markInstall()
  317.         else:
  318.             # FIXME: we may want to throw a exception here
  319.             sys.stderr.write("MarkUpgrade() called on a non-upgrable pkg: '%s'\n"  %self._pkg.Name)
  320.  
  321.     def commit(self, fprogress, iprogress):
  322.         """ commit the changes, need a FetchProgress and InstallProgress
  323.             object as argument
  324.         """
  325.         self._depcache.Commit(fprogress, iprogress)
  326.         
  327.  
  328. # self-test
  329. if __name__ == "__main__":
  330.     print "Self-test for the Package modul"
  331.     apt_pkg.init()
  332.     cache = apt_pkg.GetCache()
  333.     depcache = apt_pkg.GetDepCache(cache)
  334.     records = apt_pkg.GetPkgRecords(cache)
  335.     sourcelist = apt_pkg.GetPkgSourceList()
  336.  
  337.     pkgiter = cache["apt-utils"]
  338.     pkg = Package(cache, depcache, records, sourcelist, None, pkgiter)
  339.     print "Name: %s " % pkg.name
  340.     print "ID: %s " % pkg.id
  341.     print "Priority (Candidate): %s " % pkg.priority
  342.     print "Priority (Installed): %s " % pkg.installedPriority
  343.     print "Installed: %s " % pkg.installedVersion
  344.     print "Candidate: %s " % pkg.candidateVersion
  345.     print "CandidateDownloadable: %s" % pkg.candidateDownloadable
  346.     print "CandidateOrigins: %s" % pkg.candidateOrigin
  347.     print "SourcePkg: %s " % pkg.sourcePackageName
  348.     print "Section: %s " % pkg.section
  349.     print "Summary: %s" % pkg.summary
  350.     print "Description (formated) :\n%s" % pkg.description
  351.     print "Description (unformated):\n%s" % pkg.rawDescription
  352.     print "InstalledSize: %s " % pkg.installedSize
  353.     print "PackageSize: %s " % pkg.packageSize
  354.  
  355.     # now test install/remove
  356.     import apt
  357.     progress = apt.progress.OpTextProgress()
  358.     cache = apt.Cache(progress)
  359.     for i in [True, False]:
  360.         print "Running install on random upgradable pkgs with AutoFix: %s " % i
  361.         for name in cache.keys():
  362.             pkg = cache[name]
  363.             if pkg.isUpgradable:
  364.                 if random.randint(0,1) == 1:
  365.                     pkg.markInstall(i)
  366.         print "Broken: %s " % cache._depcache.BrokenCount
  367.         print "InstCount: %s " % cache._depcache.InstCount
  368.  
  369.     print
  370.     # get a new cache
  371.     for i in [True, False]:
  372.         print "Randomly remove some packages with AutoFix: %s" % i
  373.         cache = apt.Cache(progress)
  374.         for name in cache.keys():
  375.             if random.randint(0,1) == 1:
  376.                 try:
  377.                     cache[name].markDelete(i)
  378.                 except SystemError:
  379.                     print "Error trying to remove: %s " % name
  380.         print "Broken: %s " % cache._depcache.BrokenCount
  381.         print "DelCount: %s " % cache._depcache.DelCount
  382.