# written 2007 by Markus Ullmann # License: GPL-2 """class for backend communication""" from pkgcore.config import load_config from pkgcore.ebuild.atom import atom from pkgcore.ebuild.repository import UnconfiguredTree, SlavedTree from pkgcore.restrictions.packages import OrRestriction from pkgcore.util.repo_utils import get_raw_repos, get_virtual_repos from snakeoil.lists import unstable_unique from snakeoil.fileutils import iter_read_bash from snakeoil.osutils import pjoin import os import errno import hashlib def file_sha1(path): sha1 = 'NULL' if os.path.exists(path): f = open(path, 'r') sha1 = hashlib.sha1(f.read()).hexdigest() return sha1 def file_mtime(path): mtime = -1 if os.path.exists(path): mtime = int(os.stat(path).st_mtime) return mtime class domain_repo_interface: """abstraction for pkgcore communication stuff""" def __init__(self): # Do not load yet self.config = None self.config = load_config() self.current_domain = None self.current_repo = None def load_config(self): self.config = load_config() def get_domainlist(self): domainlist = [] for domain in self.config.domain.iterkeys(): domainlist.append(domain) return domainlist def get_domain_by_name(self, domaintext): return self.config.domain[domaintext] def set_domain_by_name(self, domaintext): self.current_domain_text = domaintext self.current_domain = self.get_domain_by_name(domaintext) self.fill_repolist() def get_repolist(self, domain=None): if domain is None: domain = self.current_domain repolist = [] for repo in get_virtual_repos(get_raw_repos(domain.repos), False): if not isinstance(repo, UnconfiguredTree) and not isinstance( repo, SlavedTree): continue repolist.append(repo) return repolist def get_repolist_ids(self,domain=None): idlist = [] if domain is None: domain = self.current_domain for repo in self.get_repolist(domain): idlist.append(repo.repo_id) return idlist def fill_repolist(self): self.repolist = self.get_repolist() @property def repo_id_list(self): for repo in self.repolist: yield repo.repo_id def set_work_repo_by_id(self, repo_id): for repo in get_virtual_repos(get_raw_repos( self.current_domain.repos), False): if repo.repo_id == repo_id: self.current_repo = repo break self.fetch_packagemask_content() def set_work_repo_by_location(self, repo_location): for repo in get_virtual_repos(get_raw_repos( self.current_domain.repos), False): if repo.location == repo_location: self.current_repo = repo break self.fetch_packagemask_content() def fetch_packagemask_content(self): self.pmaskatoms = {} try: d = {} for line in iter_read_bash(pjoin( self.current_repo.location, "profiles/package.mask")): newatom = atom(line.strip()) d.setdefault(newatom.key, []).append(newatom) if not newatom.key in self.pmaskatoms: self.pmaskatoms[newatom.key] = newatom else: self.pmaskatoms[newatom.key] = newatom.intersect( self.pmaskatoms[newatom.key]) except IOError, oe: if oe.errno != errno.ENOENT: raise self.pmaskatoms = dict((k, OrRestriction(*unstable_unique(v))) for k,v in d.iteritems()) @property def work_repo_location(self): return self.current_repo.location @property def all_packages_list(self): return self.current_repo.versions @property def pmask_packages_list(self): for i in self.pmaskatoms.keys(): yield i.split('/',2) def get_changelog_meta(self, (category, package)): """Return the changelog mtime and SHA1""" filename = pjoin(self.current_repo.location, category, package, "ChangeLog") mtime = file_mtime(filename) sha1 = file_sha1(filename) return (mtime, sha1) def get_manifest_meta(self, (category, package)): """Return the Manifest mtime and SHA1""" filename = pjoin(self.current_repo.location, category, package, "Manifest") mtime = file_mtime(filename) sha1 = file_sha1(filename) return (mtime, sha1) def get_changelog(self, (category, package)): """Return the changelog contents""" filename = pjoin(self.current_repo.location, category, package, "ChangeLog") try: changelogfile = open(filename) except IOError, oe: if oe.errno not in (errno.ENOENT, ): raise return "No ChangeLog file there" text = "" for line in changelogfile: text += unicode(line, 'utf-8') changelogfile.close() return text def get_app_metadata(self,(category, package)): package_atom = atom("%s/%s" % (category, package)) pkg = max(self.current_repo.itermatch(package_atom, sorter=sorted)) description = unicode(getattr(pkg, 'description', None)) homepage = getattr(pkg, 'homepage', None) license = getattr(pkg, 'license', None) return (description, homepage, license) def get_package_keywords_dict(self, (category, package)): package_atom = atom("%s/%s" % (category, package)) package_dict = {} for pkg in self.current_repo.itermatch(package_atom, sorter=sorted): keyword_dict = {} if pkg.key in self.pmaskatoms and self.pmaskatoms[pkg.key].match(pkg): pkgmask_prefix = "M" else: pkgmask_prefix = "" for keyword in pkg.keywords: if keyword.startswith('-'): keyword_dict[keyword[1:]] = pkgmask_prefix + '-' elif keyword.startswith('~'): keyword_dict[keyword[1:]] = pkgmask_prefix + '~' else: keyword_dict[keyword] = pkgmask_prefix + '+' efilename = package + "-" + pkg.fullver + ".ebuild" epath = pjoin(self.work_repo_location, category, package, efilename) mtime = file_mtime(epath) sha1 = file_sha1(epath) yield (pkg.versioned_atom.fullver, keyword_dict, mtime, sha1) # vim:ts=4 et ft=python: