def check(self): """Check if the package is installable.""" self._dbg(3, "check") self._check_was_run = True # check arch if not "Architecture" in self._sections: self._dbg(1, "ERROR: no architecture field") self._failure_string = _("No Architecture field in the package") return False arch = self._sections["Architecture"] if arch != "all" and arch != apt_pkg.config.find("APT::Architecture"): if arch in apt_pkg.get_architectures(): self._multiarch = arch self.pkgname = "%s:%s" % (self.pkgname, self._multiarch) self._dbg(1, "Found multiarch arch: '%s'" % arch) else: self._dbg(1, "ERROR: Wrong architecture dude!") self._failure_string = _("Wrong architecture '%s'") % arch return False self._failure_string = "" if self._cache._depcache.broken_count > 0: self._failure_string = _("Failed to satisfy all dependencies " "(broken cache)") # clean the cache again self._cache.clear() return False return True
def check(self, allow_downgrade=False): """Check if the package is installable.""" self._dbg(3, "check") self._check_was_run = True # check arch if "Architecture" not in self._sections: self._dbg(1, "ERROR: no architecture field") self._failure_string = _("No Architecture field in the package") return False arch = self._sections["Architecture"] if arch != "all" and arch != apt_pkg.config.find("APT::Architecture"): if arch in apt_pkg.get_architectures(): self._multiarch = arch self.pkgname = "%s:%s" % (self.pkgname, self._multiarch) self._dbg(1, "Found multiarch arch: '%s'" % arch) else: self._dbg(1, "ERROR: Wrong architecture dude!") self._failure_string = _("Wrong architecture '%s'") % arch return False # check version if (not allow_downgrade and self.compare_to_version_in_cache() == self.VERSION_OUTDATED): if self._cache[self.pkgname].installed: # the deb is older than the installed self._failure_string = _( "A later version is already installed") return False # FIXME: this sort of error handling sux self._failure_string = "" # check conflicts if not self.check_conflicts(): return False # check if installing it would break anything on the # current system if not self.check_breaks_existing_packages(): return False # try to satisfy the dependencies if not self._satisfy_depends(self.depends): return False # check for conflicts again (this time with the packages that are # makeed for install) if not self.check_conflicts(): return False if self._cache._depcache.broken_count > 0: self._failure_string = _("Failed to satisfy all dependencies " "(broken cache)") # clean the cache again self._cache.clear() return False return True
def get_server_list(self): ''' Return a list of used and suggested servers ''' def compare_mirrors(mir1, mir2): ''' Helper function that handles comaprision of mirror urls that could contain trailing slashes''' return re.match(mir1.strip("/ "), mir2.rstrip("/ ")) # Store all available servers: # Name, URI, active mirrors = [] if (len(self.used_servers) < 1 or (len(self.used_servers) == 1 and compare_mirrors(self.used_servers[0], self.main_server))): mirrors.append([_("Main server"), self.main_server, True]) if self.nearest_server: mirrors.append([ self._get_mirror_name(self.nearest_server), self.nearest_server, False ]) elif (len(self.used_servers) == 1 and not compare_mirrors(self.used_servers[0], self.main_server)): mirrors.append([_("Main server"), self.main_server, False]) # Only one server is used server = self.used_servers[0] # Append the nearest server if it's not already used if self.nearest_server: if not compare_mirrors(server, self.nearest_server): mirrors.append([ self._get_mirror_name(self.nearest_server), self.nearest_server, False ]) if server: mirrors.append([self._get_mirror_name(server), server, True]) elif len(self.used_servers) > 1: # More than one server is used. Since we don't handle this case # in the user interface we set "custom servers" to true and # append a list of all used servers mirrors.append([_("Main server"), self.main_server, False]) if self.nearest_server: mirrors.append([ self._get_mirror_name(self.nearest_server), self.nearest_server, False ]) mirrors.append([_("Custom servers"), None, True]) for server in self.used_servers: mirror_entry = [self._get_mirror_name(server), server, False] if (compare_mirrors(server, self.nearest_server) or compare_mirrors(server, self.main_server)): continue elif not mirror_entry in mirrors: mirrors.append(mirror_entry) return mirrors
def get_server_list(self): ''' Return a list of used and suggested servers ''' def compare_mirrors(mir1, mir2): ''' Helper function that handles comaprision of mirror urls that could contain trailing slashes''' return re.match(mir1.strip("/ "), mir2.rstrip("/ ")) # Store all available servers: # Name, URI, active mirrors = [] if (len(self.used_servers) < 1 or (len(self.used_servers) == 1 and compare_mirrors(self.used_servers[0], self.main_server))): mirrors.append([_("Main server"), self.main_server, True]) if self.nearest_server: mirrors.append([self._get_mirror_name(self.nearest_server), self.nearest_server, False]) elif (len(self.used_servers) == 1 and not compare_mirrors(self.used_servers[0], self.main_server)): mirrors.append([_("Main server"), self.main_server, False]) # Only one server is used server = self.used_servers[0] # Append the nearest server if it's not already used if self.nearest_server: if not compare_mirrors(server, self.nearest_server): mirrors.append([self._get_mirror_name(self.nearest_server), self.nearest_server, False]) if server: mirrors.append([self._get_mirror_name(server), server, True]) elif len(self.used_servers) > 1: # More than one server is used. Since we don't handle this case # in the user interface we set "custom servers" to true and # append a list of all used servers mirrors.append([_("Main server"), self.main_server, False]) if self.nearest_server: mirrors.append([self._get_mirror_name(self.nearest_server), self.nearest_server, False]) mirrors.append([_("Custom servers"), None, True]) for server in self.used_servers: mirror_entry = [self._get_mirror_name(server), server, False] if (compare_mirrors(server, self.nearest_server) or compare_mirrors(server, self.main_server)): continue elif mirror_entry not in mirrors: mirrors.append(mirror_entry) return mirrors
def _get_content(self, part, name, auto_decompress=True, auto_hex=True): data = part.get_content(name) # check for zip content if name.endswith(".gz") and auto_decompress: io = StringIO(data) gz = gzip.GzipFile(fileobj=io) data = _("Automatically decompressed:\n\n") data += gz.read() # auto-convert to hex try: data = unicode(data, "utf-8") except Exception, e: new_data = _("Automatically converted to printable ascii:\n") new_data += self.to_strish(data) return new_data
def __init__(self, name, keyid, date): # type: (str, str, str) -> None self.raw_name = name # Allow to translated some known keys self.name = _(name) self.keyid = keyid self.date = date
def open(self, file): # type: (str) -> None """Open the package.""" depends_tags = ["Build-Depends", "Build-Depends-Indep"] conflicts_tags = ["Build-Conflicts", "Build-Conflicts-Indep"] fd = apt_pkg.open_maybe_clear_signed_file(file) fobj = os.fdopen(fd) tagfile = apt_pkg.TagFile(fobj) try: for sec in tagfile: for tag in depends_tags: if tag not in sec: continue self._depends.extend(apt_pkg.parse_src_depends(sec[tag])) for tag in conflicts_tags: if tag not in sec: continue self._conflicts.extend(apt_pkg.parse_src_depends(sec[tag])) if 'Source' in sec: self.pkgname = sec['Source'] if 'Binary' in sec: self.binaries = [b.strip() for b in sec['Binary'].split(',')] for tag in sec.keys(): # type: ignore if tag in sec: self._sections[tag] = sec[tag] finally: del tagfile fobj.close() s = _("Install Build-Dependencies for " "source package '%s' that builds %s\n") % (self.pkgname, " ".join(self.binaries)) self._sections["Description"] = s self._check_was_run = False
def _check_single_pkg_conflict(self, pkgname, ver, oper): """Return True if a pkg conflicts with a real installed/marked pkg.""" # FIXME: deal with conflicts against its own provides # (e.g. Provides: ftp-server, Conflicts: ftp-server) self._dbg( 3, "_check_single_pkg_conflict() pkg='%s' ver='%s' oper='%s'" % ( pkgname, ver, oper)) pkg = self._cache[pkgname] if pkg.is_installed: pkgver = pkg.installed.version elif pkg.marked_install: pkgver = pkg.candidate.version else: return False #print "pkg: %s" % pkgname #print "ver: %s" % ver #print "pkgver: %s " % pkgver #print "oper: %s " % oper if (apt_pkg.check_dep(pkgver, oper, ver) and not self.replaces_real_pkg(pkgname, oper, ver)): self._failure_string += _("Conflicts with the installed package " "'%s'") % pkg.name self._dbg(3, "conflicts with installed pkg '%s'" % pkg.name) return True return False
def open(self, file): """Open the package.""" depends_tags = ["Build-Depends", "Build-Depends-Indep"] conflicts_tags = ["Build-Conflicts", "Build-Conflicts-Indep"] fobj = open(file) tagfile = apt_pkg.TagFile(fobj) try: for sec in tagfile: for tag in depends_tags: if tag not in sec: continue self._depends.extend(apt_pkg.parse_src_depends(sec[tag])) for tag in conflicts_tags: if tag not in sec: continue self._conflicts.extend(apt_pkg.parse_src_depends(sec[tag])) if 'Source' in sec: self.pkgname = sec['Source'] if 'Binary' in sec: self.binaries = sec['Binary'].split(', ') if 'Version' in sec: self._sections['Version'] = sec['Version'] finally: del tagfile fobj.close() s = _("Install Build-Dependencies for " "source package '%s' that builds %s\n") % (self.pkgname, " ".join(self.binaries)) self._sections["Description"] = s self._check_was_run = False
def open(self, progress=None): """ Open the package cache, after that it can be used like a dictionary """ if progress is None: progress = apt.progress.base.OpProgress() self._run_callbacks("cache_pre_open") self._cache = apt_pkg.Cache(progress) self._depcache = apt_pkg.DepCache(self._cache) self._records = apt_pkg.PackageRecords(self._cache) self._list = apt_pkg.SourceList() self._list.read_main_list() self._set.clear() self._weakref.clear() progress.op = _("Building data structures") i = last = 0 size = len(self._cache.packages) for pkg in self._cache.packages: if progress is not None and last+100 < i: progress.update(i/float(size)*100) last = i # drop stuff with no versions (cruft) if len(pkg.version_list) > 0: self._set.add(pkg.name) i += 1 progress.done() self._run_callbacks("cache_post_open")
def open(self, file): """Open the package.""" depends_tags = ["Build-Depends", "Build-Depends-Indep"] conflicts_tags = ["Build-Conflicts", "Build-Conflicts-Indep"] fd = apt_pkg.open_maybe_clear_signed_file(file) fobj = os.fdopen(fd) tagfile = apt_pkg.TagFile(fobj) try: for sec in tagfile: for tag in depends_tags: if tag not in sec: continue self._depends.extend(apt_pkg.parse_src_depends(sec[tag])) for tag in conflicts_tags: if tag not in sec: continue self._conflicts.extend(apt_pkg.parse_src_depends(sec[tag])) if 'Source' in sec: self.pkgname = sec['Source'] if 'Binary' in sec: self.binaries = [ b.strip() for b in sec['Binary'].split(',') ] for tag in sec.keys(): if tag in sec: self._sections[tag] = sec[tag] finally: del tagfile fobj.close() s = _("Install Build-Dependencies for " "source package '%s' that builds %s\n") % ( self.pkgname, " ".join(self.binaries)) self._sections["Description"] = s self._check_was_run = False
def _check_single_pkg_conflict(self, pkgname, ver, oper): # type: (str, str, str) -> bool """Return True if a pkg conflicts with a real installed/marked pkg.""" # FIXME: deal with conflicts against its own provides # (e.g. Provides: ftp-server, Conflicts: ftp-server) self._dbg( 3, "_check_single_pkg_conflict() pkg='%s' ver='%s' oper='%s'" % (pkgname, ver, oper)) pkg = self._cache[pkgname] if pkg.is_installed: assert pkg.installed is not None pkgver = pkg.installed.version elif pkg.marked_install: assert pkg.candidate is not None pkgver = pkg.candidate.version else: return False #print "pkg: %s" % pkgname #print "ver: %s" % ver #print "pkgver: %s " % pkgver #print "oper: %s " % oper if (apt_pkg.check_dep(pkgver, oper, ver) and not self.replaces_real_pkg(pkgname, oper, ver)): self._failure_string += _("Conflicts with the installed package " "'%s'") % pkg.name self._dbg(3, "conflicts with installed pkg '%s'" % pkg.name) return True return False
def open(self, file): """Open the package.""" depends_tags = ["Build-Depends", "Build-Depends-Indep"] conflicts_tags = ["Build-Conflicts", "Build-Conflicts-Indep"] fobj = open(file) tagfile = apt_pkg.TagFile(fobj) try: for sec in tagfile: for tag in depends_tags: if not tag in sec: continue self._depends.extend(apt_pkg.parse_src_depends(sec[tag])) for tag in conflicts_tags: if not tag in sec: continue self._conflicts.extend(apt_pkg.parse_src_depends(sec[tag])) if 'Source' in sec: self.pkgname = sec['Source'] if 'Binary' in sec: self.binaries = sec['Binary'].split(', ') if 'Version' in sec: self._sections['Version'] = sec['Version'] finally: del tagfile fobj.close() s = _("Install Build-Dependencies for " "source package '%s' that builds %s\n") % ( self.pkgname, " ".join(self.binaries)) self._sections["Description"] = s
def filelist(self): """return the list of files in the deb.""" files = [] try: self._debfile.data.go(lambda item, data: files.append(item.name)) except SystemError: return [_("List of files for '%s' could not be read") % self.filename] return files
def _get_content(self, part, name, auto_decompress=True, auto_hex=True): if name.startswith("./"): name = name[2:] data = part.extractdata(name) # check for zip content if name.endswith(".gz") and auto_decompress: io = StringIO(data) gz = gzip.GzipFile(fileobj=io) data = _("Automatically decompressed:\n\n") data += gz.read() # auto-convert to hex try: data = unicode(data, "utf-8") except Exception: new_data = _("Automatically converted to printable ascii:\n") new_data += self.to_strish(data) return new_data return data
def control_filelist(self): """ return the list of files in control.tar.gt """ control = [] try: self._debfile.control.go(lambda item, data: control.append(item.name)) except SystemError: return [_("List of control files for '%s' could not be read") % self.filename] return sorted(control)
def _get_content(self, part, name, auto_decompress=True, auto_hex=True): if name.startswith("./"): name = name[2:] data = part.extractdata(name) # check for zip content if name.endswith(".gz") and auto_decompress: io = BytesIO(data) gz = gzip.GzipFile(fileobj=io) data = _("Automatically decompressed:\n\n").encode("utf-8") data += gz.read() # auto-convert to hex try: data = data.decode("utf-8") except Exception: new_data = _("Automatically converted to printable ascii:\n") new_data += self.to_strish(data) return new_data return data
def _get_content(self, part, name, auto_decompress=True, auto_hex=True): # type: (apt_inst.TarFile, str, bool, bool) -> str if name.startswith("./"): name = name[2:] data = part.extractdata(name) # check for zip content if name.endswith(".gz") and auto_decompress: io = BytesIO(data) gz = gzip.GzipFile(fileobj=io) data = _("Automatically decompressed:\n\n").encode("utf-8") data += gz.read() # auto-convert to hex try: return data.decode("utf-8") except Exception: new_data = _("Automatically converted to printable ascii:\n") new_data += self.to_strish(data) return new_data
def data_content(self, name): """ return the content of a specific control.tar.gz file """ try: from debian.debfile import DebFile except: raise Exception(_("Python-debian module not available")) data = DebFile(self.filename).data if name in data: return self._get_content(data, name) return ""
def check(self): """Check if the package is installable..""" if not self.check_conflicts(): for pkgname in self._installed_conflicts: if self._cache[pkgname]._pkg.essential: raise Exception(_("An essential package would be removed")) self._cache[pkgname].mark_delete() # FIXME: a additional run of the checkConflicts() # after _satisfyDepends() should probably be done return self._satisfy_depends(self.depends)
def control_filelist(self): """ return the list of files in control.tar.gt """ control = [] try: self._debfile.control.go( lambda item, data: control.append(item.name)) except SystemError: return [_("List of control files for '%s' could not be read") % self.filename] return sorted(control)
def pulse(self): old.FetchProgress.pulse(self) current_item = self.currentItems + 1 if current_item > self.totalItems: current_item = self.totalItems if self.current_cps > 0: text = (_("Downloading file %(current)li of %(total)li with " "%(speed)s/s") % \ {"current": current_item, "total": self.totalItems, "speed": apt_pkg.size_to_str(self.currentCPS)}) else: text = (_("Downloading file %(current)li of %(total)li") % \ {"current": current_item, "total": self.totalItems}) self.emit("status-changed", text, self.percent) while self._context.pending(): self._context.iteration() return self._continue
def control_filelist(self): """ return the list of files in control.tar.gt """ try: from debian.debfile import DebFile except: raise Exception(_("Python-debian module not available")) content = [] for name in DebFile(self.filename).control: if name and name != ".": content.append(name) return sorted(content)
def pulse(self, owner): current_item = self.current_items + 1 if current_item > self.total_items: current_item = self.total_items if self.current_cps > 0: text = (_("Downloading file %(current)li of %(total)li with " "%(speed)s/s") % {"current": current_item, "total": self.total_items, "speed": apt_pkg.size_to_str(self.current_cps)}) else: text = (_("Downloading file %(current)li of %(total)li") % {"current": current_item, "total": self.total_items}) self.status_label.setText(text) percent = (((self.current_bytes + self.current_items) * 100.0) / float(self.total_bytes + self.total_items)) self.pbar.setValue(int(percent)) QtGui.qApp.processEvents() return True
def check(self): """Check if the package is installable.""" self._dbg(3, "check_depends") # check arch arch = self._sections["Architecture"] if arch != "all" and arch != apt_pkg.config.find("APT::Architecture"): self._dbg(1, "ERROR: Wrong architecture dude!") self._failure_string = _("Wrong architecture '%s'" % arch) return False # check version if self.compare_to_version_in_cache() == VERSION_OUTDATED: # the deb is older than the installed self._failure_string = _("A later version is already installed") return False # FIXME: this sort of error handling sux self._failure_string = "" # check conflicts if not self.check_conflicts(): return False # try to satisfy the dependencies if not self._satisfy_depends(self.depends): return False # check for conflicts again (this time with the packages that are # makeed for install) if not self.check_conflicts(): return False if self._cache._depcache.broken_count > 0: self._failure_string = _("Failed to satisfy all dependencies " "(broken cache)") # clean the cache again self._cache.clear() return False return True
def _get_mirror_name(self, server): ''' Try to get a human readable name for the main mirror of a country Customize for different distributions ''' country = None i = server.find("://") l = server.find(".archive.ubuntu.com") if i != -1 and l != -1: country = server[i + len("://"):l] if country in self.countries: # TRANSLATORS: %s is a country return _("Server for %s") % self.countries[country] else: return ("%s" % server.rstrip("/ "))
def pulse(self, owner): base.AcquireProgress.pulse(self, owner) current_item = self.current_items + 1 if current_item > self.total_items: current_item = self.total_items if self.current_cps > 0: text = (_("Downloading file %(current)li of %(total)li with " "%(speed)s/s") % \ {"current": current_item, "total": self.total_items, "speed": apt_pkg.size_to_str(self.current_cps)}) else: text = (_("Downloading file %(current)li of %(total)li") % \ {"current": current_item, "total": self.total_items}) percent = (((self.current_bytes + self.current_items) * 100.0) / float(self.total_bytes + self.total_items)) self.emit("status-changed", text, percent) while self._context.pending(): self._context.iteration() return self._continue
def _get_mirror_name(self, server): ''' Try to get a human readable name for the main mirror of a country Customize for different distributions ''' country = None i = server.find("://") l = server.find(".archive.ubuntu.com") if i != -1 and l != -1: country = server[i + len("://"):l] if country in self.countries: # TRANSLATORS: %s is a country return _("Server for %s") % self.countries[country] else: return("%s" % server.rstrip("/ "))
def _get_mirror_name(self, server): """ Try to get a human readable name for the main mirror of a country Debian specific """ country = None i = server.find("://ftp.") l = server.find(".debian.org") if i != -1 and l != -1: country = server[i + len("://ftp.") : l] if country in self.countries: # TRANSLATORS: %s is a country return _("Server for %s") % gettext.dgettext("iso_3166", self.countries[country].rstrip()).rstrip() else: return "%s" % server.rstrip("/ ")
def pulse(self, owner): current_item = self.current_items + 1 if current_item > self.total_items: current_item = self.total_items if self.current_cps > 0: text = (_("Downloading file %(current)li of %(total)li with " "%(speed)s/s") % { "current": current_item, "total": self.total_items, "speed": apt_pkg.size_to_str(self.current_cps) }) else: text = (_("Downloading file %(current)li of %(total)li") % { "current": current_item, "total": self.total_items }) self.status_label.setText(text) percent = (((self.current_bytes + self.current_items) * 100.0) / float(self.total_bytes + self.total_items)) self.pbar.setValue(int(percent)) QtGui.qApp.processEvents() return True
def _get_mirror_name(self, server): ''' Try to get a human readable name for the main mirror of a country Debian specific ''' country = None i = server.find("://ftp.") l = server.find(".debian.org") if i != -1 and l != -1: country = server[i + len("://ftp."):l] if country in self.countries: # TRANSLATORS: %s is a country return _("Server for %s") % gettext.dgettext( "iso_3166", self.countries[country].rstrip()).rstrip() else: return ("%s" % server.rstrip("/ "))
def __init__(self): gtk.VBox.__init__(self) self.set_spacing(6) # Setup some child widgets self._expander = gtk.Expander(_("Details")) self._terminal = vte.Terminal() #self._terminal.set_font_from_string("monospace 10") self._expander.add(self._terminal) self._progressbar = gtk.ProgressBar() # Setup the always italic status label self._label = gtk.Label() attr_list = pango.AttrList() attr_list.insert(pango.AttrStyle(pango.STYLE_ITALIC, 0, -1)) self._label.set_attributes(attr_list) self._label.set_ellipsize(pango.ELLIPSIZE_END) self._label.set_alignment(0, 0) # add child widgets self.pack_start(self._progressbar, False) self.pack_start(self._label, False) self.pack_start(self._expander, False) # Setup the internal progress handlers self._progress_open = GOpProgress() self._progress_open.connect("status-changed", self._on_status_changed) self._progress_open.connect("status-started", self._on_status_started) self._progress_open.connect("status-finished", self._on_status_finished) self._progress_acquire = GAcquireProgress() self._progress_acquire.connect("status-changed", self._on_status_changed) self._progress_acquire.connect("status-started", self._on_status_started) self._progress_acquire.connect("status-finished", self._on_status_finished) self._progress_fetch = None self._progress_install = GInstallProgress(self._terminal) self._progress_install.connect("status-changed", self._on_status_changed) self._progress_install.connect("status-started", self._on_status_started) self._progress_install.connect("status-finished", self._on_status_finished) self._progress_install.connect("status-timeout", self._on_status_timeout) self._progress_install.connect("status-error", self._on_status_timeout) self._progress_install.connect("status-conffile", self._on_status_timeout)
def check(self, allow_downgrade=False): # type: (bool) -> bool """Check if the package is installable. The second parameter is ignored and only exists for compatibility with parent type.""" if not self.check_conflicts(): for pkgname in self._installed_conflicts: if self._cache[pkgname]._pkg.essential: raise Exception(_("An essential package would be removed")) self._cache[pkgname].mark_delete() # properties are ok now self._check_was_run = True # FIXME: a additional run of the check_conflicts() # after _satisfy_depends() should probably be done return self._satisfy_depends(self.depends)
def description(self): """Return the formatted long description. Return the formated long description according to the Debian policy (Chapter 5.6.13). See http://www.debian.org/doc/debian-policy/ch-controlfields.html for more information. """ desc = "" dsc = self._translated_records.long_desc try: if not isinstance(dsc, unicode): # Only convert where needed (i.e. Python 2.X) dsc = unicode(dsc, "utf-8") except UnicodeDecodeError, err: return _("Invalid unicode in description for '%s' (%s). " "Please report.") % (self.package.name, err)
def description(self): """Return the formatted long description. Return the formated long description according to the Debian policy (Chapter 5.6.13). See http://www.debian.org/doc/debian-policy/ch-controlfields.html for more information. """ desc = '' dsc = self._translated_records.long_desc try: if not isinstance(dsc, unicode): # Only convert where needed (i.e. Python 2.X) dsc = unicode(dsc, "utf-8") except UnicodeDecodeError, err: return _("Invalid unicode in description for '%s' (%s). " "Please report.") % (self.package.name, err)
def _satisfy_or_group(self, or_group): # type: (List[Tuple[str, str, str]]) -> bool """Try to satisfy the or_group.""" for dep in or_group: depname, ver, oper = dep # multiarch depname = self._maybe_append_multiarch_suffix(depname) # if we don't have it in the cache, it may be virtual if depname not in self._cache: if not self._cache.is_virtual_package(depname): continue providers = self._cache.get_providing_packages(depname) # if a package just has a single virtual provider, we # just pick that (just like apt) if len(providers) != 1: continue depname = providers[0].name # now check if we can satisfy the deps with the candidate(s) # in the cache pkg = self._cache[depname] cand = self._cache._depcache.get_candidate_ver(pkg._pkg) if not cand: continue if not apt_pkg.check_dep(cand.ver_str, oper, ver): continue # check if we need to install it self._dbg(2, "Need to get: %s" % depname) self._need_pkgs.append(depname) return True # if we reach this point, we failed or_str = "" for dep in or_group: or_str += dep[0] if ver and oper: or_str += " (%s %s)" % (dep[2], dep[1]) if dep != or_group[len(or_group) - 1]: or_str += "|" self._failure_string += _( "Dependency is not satisfiable: %s\n") % or_str return False
def description(self): """Return the formatted long description. Return the formatted long description according to the Debian policy (Chapter 5.6.13). See http://www.debian.org/doc/debian-policy/ch-controlfields.html for more information. """ desc = '' dsc = self._translated_records.long_desc try: if not isinstance(dsc, unicode): # Only convert where needed (i.e. Python 2.X) dsc = unicode(dsc, "utf-8") except UnicodeDecodeError as err: return _("Invalid unicode in description for '%s' (%s). " "Please report.") % (self.package.name, err) lines = iter(dsc.split("\n")) # Skip the first line, since its a duplication of the summary lines.next() for raw_line in lines: if raw_line.strip() == ".": # The line is just line break if not desc.endswith("\n"): desc += "\n\n" continue if raw_line.startswith(" "): # The line should be displayed verbatim without word wrapping if not desc.endswith("\n"): line = "\n%s\n" % raw_line[2:] else: line = "%s\n" % raw_line[2:] elif raw_line.startswith(" "): # The line is part of a paragraph. if desc.endswith("\n") or desc == "": # Skip the leading white space line = raw_line[1:] else: line = raw_line else: line = raw_line # Add current line to the description desc += line return desc
def open(self, progress=None): """ Open the package cache, after that it can be used like a dictionary """ if progress is None: progress = apt.progress.base.OpProgress() # close old cache on (re)open self.close() self.op_progress = progress self._run_callbacks("cache_pre_open") self._cache = apt_pkg.Cache(progress) self._depcache = apt_pkg.DepCache(self._cache) self._records = apt_pkg.PackageRecords(self._cache) self._list = apt_pkg.SourceList() self._list.read_main_list() self._set.clear() self._fullnameset.clear() self._sorted_set = None self._weakref.clear() self._have_multi_arch = len(apt_pkg.get_architectures()) > 1 progress.op = _("Building data structures") i = last = 0 size = len(self._cache.packages) for pkg in self._cache.packages: if progress is not None and last + 100 < i: progress.update(i / float(size) * 100) last = i # drop stuff with no versions (cruft) if pkg.has_versions: self._set.add(pkg.get_fullname(pretty=True)) if self._have_multi_arch: self._fullnameset.add(pkg.get_fullname(pretty=False)) i += 1 progress.done() self._run_callbacks("cache_post_open")
def _satisfy_depends(self, depends): """Satisfy the dependencies.""" # turn off MarkAndSweep via a action group (if available) try: _actiongroup = apt_pkg.ActionGroup(self._cache._depcache) _actiongroup # pyflakes except AttributeError: pass # check depends for or_group in depends: if not self._is_or_group_satisfied(or_group): if not self._satisfy_or_group(or_group): return False # now try it out in the cache for pkg in self._need_pkgs: try: self._cache[pkg].mark_install(from_user=False) except SystemError: self._failure_string = _("Cannot install '%s'") % pkg self._cache.clear() return False return True
def open(self, file): """Open the package.""" depends_tags = ["Build-Depends", "Build-Depends-Indep"] conflicts_tags = ["Build-Conflicts", "Build-Conflicts-Indep"] fobj = open(file) tagfile = apt_pkg.TagFile(fobj) try: for sec in tagfile: # we only care about the stanza with the "Format:" tag, the # rest is gpg signature noise. we should probably have # bindings for apts OpenMaybeClearsignedFile() if "Format" not in sec: continue for tag in depends_tags: if tag not in sec: continue self._depends.extend(apt_pkg.parse_src_depends(sec[tag])) for tag in conflicts_tags: if tag not in sec: continue self._conflicts.extend(apt_pkg.parse_src_depends(sec[tag])) if 'Source' in sec: self.pkgname = sec['Source'] if 'Binary' in sec: self.binaries = [b.strip() for b in sec['Binary'].split(',')] for tag in sec.keys(): if tag in sec: self._sections[tag] = sec[tag] finally: del tagfile fobj.close() s = _("Install Build-Dependencies for " "source package '%s' that builds %s\n") % (self.pkgname, " ".join(self.binaries)) self._sections["Description"] = s self._check_was_run = False
# type: () -> List[TrustedKey] """Returns a list of TrustedKey instances for each key which is used to trust repositories. """ # The output of `apt-key list` is difficult to parse since the # --with-colons parameter isn't user output = _call_apt_key_script("adv", "--with-colons", "--batch", "--fixed-list-mode", "--list-keys") res = [] for line in output.split("\n"): fields = line.split(":") if fields[0] == "pub": keyid = fields[4] if fields[0] == "uid": uid = fields[9] creation_date = fields[5] key = TrustedKey(uid, keyid, creation_date) res.append(key) return res if __name__ == "__main__": # Add some known keys we would like to see translated so that they get # picked up by gettext lambda: _("Ubuntu Archive Automatic Signing Key <*****@*****.**>") lambda: _("Ubuntu CD Image Automatic Signing Key <*****@*****.**>") apt_pkg.init() for trusted_key in list_keys(): print(trusted_key)
def __init__(self, dist = None, base_dir = "/usr/share/python-apt/templates"): self.metarelease_uri = '' self.templates = [] self.arch = apt_pkg.config.find("APT::Architecture") location = None match_loc = re.compile(r"^#LOC:(.+)$") match_mirror_line = re.compile( r"^(#LOC:.+)|(((http)|(ftp)|(rsync)|(file)|(mirror)|(https))://" r"[A-Za-z0-9/\.:\-_@]+)$") #match_mirror_line = re.compile(r".+") if not dist: try: dist = Popen(["lsb_release", "-i", "-s"], stdout=PIPE).communicate()[0].strip() except OSError as exc: if exc.errno != errno.ENOENT: logging.warn('lsb_release failed, using defaults:' % exc) dist = "Debian" self.dist = dist map_mirror_sets = {} dist_fname = "%s/%s.info" % (base_dir, dist) with open(dist_fname) as dist_file: template = None component = None for line in dist_file: tokens = line.split(':', 1) if len(tokens) < 2: continue field = tokens[0].strip() value = tokens[1].strip() if field == 'ChangelogURI': self.changelogs_uri = _(value) elif field == 'MetaReleaseURI': self.metarelease_uri = value elif field == 'Suite': self.finish_template(template, component) component=None template = Template() template.name = value template.distribution = dist template.match_name = "^%s$" % value elif field == 'MatchName': template.match_name = value elif field == 'ParentSuite': template.child = True for nanny in self.templates: # look for parent and add back ref to it if nanny.name == value: template.parents.append(nanny) nanny.children.append(template) elif field == 'Available': template.available = apt_pkg.string_to_bool(value) elif field == 'Official': template.official = apt_pkg.string_to_bool(value) elif field == 'RepositoryType': template.type = value elif field == 'BaseURI' and not template.base_uri: template.base_uri = value elif field == 'BaseURI-%s' % self.arch: template.base_uri = value elif field == 'MatchURI' and not template.match_uri: template.match_uri = value elif field == 'MatchURI-%s' % self.arch: template.match_uri = value elif (field == 'MirrorsFile' or field == 'MirrorsFile-%s' % self.arch): # Make the path absolute. value = os.path.isabs(value) and value or \ os.path.abspath(os.path.join(base_dir, value)) if value not in map_mirror_sets: mirror_set = {} try: with open(value) as value_f: mirror_data = filter(match_mirror_line.match, [x.strip() for x in value_f]) except Exception: print "WARNING: Failed to read mirror file" mirror_data = [] for line in mirror_data: if line.startswith("#LOC:"): location = match_loc.sub(r"\1", line) continue (proto, hostname, dir) = split_url(line) if hostname in mirror_set: mirror_set[hostname].add_repository(proto, dir) else: mirror_set[hostname] = Mirror( proto, hostname, dir, location) map_mirror_sets[value] = mirror_set template.mirror_set = map_mirror_sets[value] elif field == 'Description': template.description = _(value) elif field == 'Component': if (component and not template.has_component(component.name)): template.components.append(component) component = Component(value) elif field == 'CompDescription': component.set_description(_(value)) elif field == 'CompDescriptionLong': component.set_description_long(_(value)) elif field == 'ParentComponent': component.set_parent_component(value) self.finish_template(template, component) template=None component=None
def check_breaks_existing_packages(self): # type: () -> bool """ check if installing the package would break exsisting package on the system, e.g. system has: smc depends on smc-data (= 1.4) and user tries to installs smc-data 1.6 """ # show progress information as this step may take some time size = float(len(self._cache)) steps = max(int(size / 50), 1) debver = self._sections["Version"] debarch = self._sections["Architecture"] # store what we provide so that we can later check against that provides = [x[0][0] for x in self.provides] for (i, pkg) in enumerate(self._cache): if i % steps == 0: self._cache.op_progress.update(float(i) / size * 100.0) if not pkg.is_installed: continue assert pkg.installed is not None # check if the exising dependencies are still satisfied # with the package ver = pkg._pkg.current_ver for dep_or in pkg.installed.dependencies: for dep in dep_or.or_dependencies: if dep.name == self.pkgname: if not apt_pkg.check_dep(debver, dep.relation, dep.version): self._dbg(2, "would break (depends) %s" % pkg.name) # TRANSLATORS: the first '%s' is the package that # breaks, the second the dependency that makes it # break, the third the relation (e.g. >=) and the # latest the version for the releation self._failure_string += _( "Breaks existing package '%(pkgname)s' " "dependency %(depname)s " "(%(deprelation)s %(depversion)s)") % { 'pkgname': pkg.name, 'depname': dep.name, 'deprelation': dep.relation, 'depversion': dep.version } self._cache.op_progress.done() return False # now check if there are conflicts against this package on # the existing system if "Conflicts" in ver.depends_list: for conflicts_ver_list in ver.depends_list["Conflicts"]: for c_or in conflicts_ver_list: if (c_or.target_pkg.name == self.pkgname and c_or.target_pkg.architecture == debarch): if apt_pkg.check_dep(debver, c_or.comp_type, c_or.target_ver): self._dbg( 2, "would break (conflicts) %s" % pkg.name) # TRANSLATORS: the first '%s' is the package # that conflicts, the second the packagename # that it conflicts with (so the name of the # deb the user tries to install), the third is # the relation (e.g. >=) and the last is the # version for the relation self._failure_string += _( "Breaks existing package '%(pkgname)s' " "conflict: %(targetpkg)s " "(%(comptype)s %(targetver)s)") % { 'pkgname': pkg.name, 'targetpkg': c_or.target_pkg.name, 'comptype': c_or.comp_type, 'targetver': c_or.target_ver } self._cache.op_progress.done() return False if (c_or.target_pkg.name in provides and self.pkgname != pkg.name): self._dbg(2, "would break (conflicts) %s" % provides) self._failure_string += _( "Breaks existing package '%(pkgname)s' " "that conflict: '%(targetpkg)s'. But the " "'%(debfile)s' provides it via: " "'%(provides)s'") % { 'provides': ",".join(provides), 'debfile': self.filename, 'targetpkg': c_or.target_pkg.name, 'pkgname': pkg.name } self._cache.op_progress.done() return False self._cache.op_progress.done() return True
def __init__(self, dist=None, base_dir="/usr/share/python-apt/templates"): self.metarelease_uri = '' self.templates = [] self.arch = apt_pkg.config.find("APT::Architecture") location = None match_loc = re.compile(r"^#LOC:(.+)$") match_mirror_line = re.compile( r"^(#LOC:.+)|(((http)|(ftp)|(rsync)|(file)|(mirror)|(https))://" r"[A-Za-z0-9/\.:\-_@]+)$") #match_mirror_line = re.compile(r".+") if not dist: try: dist = Popen(["lsb_release", "-i", "-s"], stdout=PIPE).communicate()[0].strip() except OSError as exc: if exc.errno != errno.ENOENT: logging.warning('lsb_release failed, using defaults:' % exc) dist = "Debian" self.dist = dist map_mirror_sets = {} dist_fname = "%s/%s.info" % (base_dir, dist) with open(dist_fname) as dist_file: template = None component = None for line in dist_file: tokens = line.split(':', 1) if len(tokens) < 2: continue field = tokens[0].strip() value = tokens[1].strip() if field == 'ChangelogURI': self.changelogs_uri = _(value) elif field == 'MetaReleaseURI': self.metarelease_uri = value elif field == 'Suite': self.finish_template(template, component) component = None template = Template() template.name = value template.distribution = dist template.match_name = "^%s$" % value elif field == 'MatchName': template.match_name = value elif field == 'ParentSuite': template.child = True for nanny in self.templates: # look for parent and add back ref to it if nanny.name == value: template.parents.append(nanny) nanny.children.append(template) elif field == 'Available': template.available = apt_pkg.string_to_bool(value) elif field == 'Official': template.official = apt_pkg.string_to_bool(value) elif field == 'RepositoryType': template.type = value elif field == 'BaseURI' and not template.base_uri: template.base_uri = value elif field == 'BaseURI-%s' % self.arch: template.base_uri = value elif field == 'MatchURI' and not template.match_uri: template.match_uri = value elif field == 'MatchURI-%s' % self.arch: template.match_uri = value elif (field == 'MirrorsFile' or field == 'MirrorsFile-%s' % self.arch): # Make the path absolute. value = os.path.isabs(value) and value or \ os.path.abspath(os.path.join(base_dir, value)) if value not in map_mirror_sets: mirror_set = {} try: with open(value) as value_f: mirror_data = list( filter(match_mirror_line.match, [x.strip() for x in value_f])) except Exception: print("WARNING: Failed to read mirror file") mirror_data = [] for line in mirror_data: if line.startswith("#LOC:"): location = match_loc.sub(r"\1", line) continue (proto, hostname, dir) = split_url(line) if hostname in mirror_set: mirror_set[hostname].add_repository(proto, dir) else: mirror_set[hostname] = Mirror( proto, hostname, dir, location) map_mirror_sets[value] = mirror_set template.mirror_set = map_mirror_sets[value] elif field == 'Description': template.description = _(value) elif field == 'Component': if (component and not template.has_component(component.name)): template.components.append(component) component = Component(value) elif field == 'CompDescription': component.set_description(_(value)) elif field == 'CompDescriptionLong': component.set_description_long(_(value)) elif field == 'ParentComponent': component.set_parent_component(value) self.finish_template(template, component) template = None component = None
def _on_status_finished(self, progress): """Called when something finished.""" self._on_status_changed(progress, _("Complete"), 100) while gtk.events_pending(): gtk.main_iteration()
def _on_status_started(self, progress): """Called when something starts.""" self._on_status_changed(progress, _("Starting..."), 0) while gtk.events_pending(): gtk.main_iteration()