def write_package_stanza(self, deb_path, dest): """Write a stanza for the package to a Packages file. @param deb_path: The path to the deb package. @param dest: A writable package file. """ deb_file = open(deb_path) deb = apt_inst.DebFile(deb_file) control = deb.control.extractdata("control") deb_file.close() filename = os.path.basename(deb_path) size = os.path.getsize(deb_path) contents = read_binary_file(deb_path) md5 = hashlib.md5(contents).hexdigest() sha1 = hashlib.sha1(contents).hexdigest() sha256 = hashlib.sha256(contents).hexdigest() tag_section = apt_pkg.TagSection(control) new_tags = [("Filename", filename), ("Size", str(size)), ("MD5sum", md5), ("SHA1", sha1), ("SHA256", sha256)] try: tag_section.write(dest, apt_pkg.REWRITE_PACKAGE_ORDER, [apt_pkg.TagRewrite(k, v) for k, v in new_tags]) except AttributeError: # support for python-apt < 1.9 section = apt_pkg.rewrite_section(tag_section, apt_pkg.REWRITE_PACKAGE_ORDER, new_tags) dest.write(section.encode("utf-8"))
def read_control(filename): recommends = [] predepends = [] depends = [] section = '' maintainer = '' arch = '' with open(filename) as deb_file: try: extracts = utils.deb_extract_control(deb_file) control = apt_pkg.TagSection(extracts) except: print(formatted_text("can't parse control info")) raise control_keys = list(control.keys()) if "Pre-Depends" in control: predepends_str = control["Pre-Depends"] predepends = split_depends(predepends_str) if "Depends" in control: depends_str = control["Depends"] # create list of dependancy lists depends = split_depends(depends_str) if "Recommends" in control: recommends_str = control["Recommends"] recommends = split_depends(recommends_str) if "Section" in control: section_str = control["Section"] c_match = re_contrib.search(section_str) nf_match = re_nonfree.search(section_str) if c_match: # contrib colour section = colour_output(section_str, 'contrib') elif nf_match: # non-free colour section = colour_output(section_str, 'nonfree') else: # main section = colour_output(section_str, 'main') if "Architecture" in control: arch_str = control["Architecture"] arch = colour_output(arch_str, 'arch') if "Maintainer" in control: maintainer = control["Maintainer"] localhost = re_localhost.search(maintainer) if localhost: #highlight bad email maintainer = colour_output(maintainer, 'maintainer') else: maintainer = escape_if_needed(maintainer) return (control, control_keys, section, predepends, depends, recommends, arch, maintainer)
def __init__(self, directory, hashed_files, keyrings, require_signature=True): self.hashed_files = hashed_files """list of source files (including the .dsc itself) @type: list of L{HashedFile} """ self._dsc_file = None for f in hashed_files: if re_file_dsc.match(f.filename): if self._dsc_file is not None: raise InvalidSourceException("Multiple .dsc found ({0} and {1})".format(self._dsc_file.filename, f.filename)) else: self._dsc_file = f # make sure the hash for the dsc is valid before we use it self._dsc_file.check(directory) dsc_file_path = os.path.join(directory, self._dsc_file.filename) data = open(dsc_file_path, 'r').read() self._signed_file = SignedFile(data, keyrings, require_signature) self.dsc = apt_pkg.TagSection(self._signed_file.contents) """dict to access fields in the .dsc file @type: dict-like """ self.package_list = daklib.packagelist.PackageList(self.dsc) """Information about packages built by the source. @type: daklib.packagelist.PackageList """ self._files = None
def __init__(self, directory, filename, keyrings, require_signature=True): if not re_file_safe.match(filename): raise InvalidChangesException( '{0}: unsafe filename'.format(filename)) self.directory = directory """directory the .changes is located in @type: str """ self.filename = filename """name of the .changes file @type: str """ with open(self.path, 'rb') as fd: data = fd.read() self.signature = SignedFile(data, keyrings, require_signature) self.changes = apt_pkg.TagSection(self.signature.contents) """dict to access fields of the .changes file @type: dict-like """ self._binaries = None self._source = None self._files = None self._keyrings = keyrings self._require_signature = require_signature
def test_write_rename(self): ts = apt_pkg.TagSection("a: 1\nb: 2\nc: 3\n") outpath = os.path.join(self.temp_dir, "test") with io.open(outpath, "w") as outfile: ts.write(outfile, ["a", "z", "b"], [apt_pkg.TagRename("c", "z")]) with io.open(outpath) as outfile: self.assertEqual(outfile.read(), "a: 1\nz: 3\nb: 2\n")
def __init__(self, base, suite_name, data): self._base = base self._suite_name = suite_name self._dict = apt_pkg.TagSection(data) self._hashes = daklib.upload.parse_file_list( self._dict, False, daklib.regexes.re_file_safe_slash, _release_hashes_fields)
def open(self, filename): " open given debfile " self.filename = filename self._debfile = apt_inst.DebFile(self.filename) control = self._debfile.control.extractdata("control") self._sections = apt_pkg.TagSection(control) self.pkgname = self._sections["Package"]
def parse(fname): """ read a deb """ control = apt_inst.DebFile(fname).control.extractdata("control") sections = apt_pkg.TagSection(control) if "Modaliases" in sections: modaliases = sections["Modaliases"] else: modaliases = '' return (sections["Architecture"], sections["Package"], modaliases)
def __init__(self, directory, hashed_file): self.hashed_file = hashed_file """file object for the .deb @type: HashedFile """ path = os.path.join(directory, hashed_file.input_filename) data = apt_inst.DebFile(path).control.extractdata("control") self.control = apt_pkg.TagSection(data) """dict to access fields in DEBIAN/control
def open(self, filename): """ open given debfile """ self._dbg(3, "open '%s'" % filename) self._need_pkgs = [] self._installed_conflicts = set() self._failure_string = "" self.filename = filename self._debfile = apt_inst.DebFile(self.filename) control = self._debfile.control.extractdata("control") self._sections = apt_pkg.TagSection(control) self.pkgname = self._sections["Package"] self._check_was_run = False
def __init__(self, tagSection, repoSuite=None): self.__repoSuite = repoSuite if tagSection: self.__tagSection = tagSection self.__id = tagSection['ID'] self.__status = BundleStatus.getByName(tagSection['Status']) self.__target = tagSection['Target'] self.__trac = tagSection.get('Trac', None) self.__ignores = str(tagSection.get('Ignores') or "").split(" ") elif repoSuite: self.__id = repoSuite.getSuiteName() self.__tagSection = apt_pkg.TagSection("ID: {}\n".format(self.__id)) self.__status = BundleStatus.getByTags(repoSuite.getTags()) self.__target = self.getInfo().get("Target", "unknown") self.__trac = None self.__ignores = []
def get_package_stanza(self, deb_path): """Return a stanza for the package to be included in a Packages file. @param deb_path: The path to the deb package. """ deb_file = open(deb_path) deb = apt_inst.DebFile(deb_file) control = deb.control.extractdata("control") deb_file.close() filename = os.path.basename(deb_path) size = os.path.getsize(deb_path) contents = read_binary_file(deb_path) md5 = hashlib.md5(contents).hexdigest() sha1 = hashlib.sha1(contents).hexdigest() sha256 = hashlib.sha256(contents).hexdigest() # Use rewrite_section to ensure that the field order is correct. return apt_pkg.rewrite_section(apt_pkg.TagSection(control), apt_pkg.REWRITE_PACKAGE_ORDER, [("Filename", filename), ("Size", str(size)), ("MD5sum", md5), ("SHA1", sha1), ("SHA256", sha256)])
def provide_dell_recovery_file_chooser_picked(self, widget=None): """Called when a file is selected on the add dell-recovery page""" ok_button = self.builder_widgets.get_object('builder_add_ok') filefilter = Gtk.FileFilter() filefilter.add_pattern("*.deb") self.file_dialog.set_filter(filefilter) ret = self.run_file_dialog() if ret is not None: import apt_inst import apt_pkg control = apt_inst.DebFile(ret).control.extractdata("control") sections = apt_pkg.TagSection(control) if sections["Package"] != 'dell-recovery': self.add_dell_recovery_deb = '' else: self.add_dell_recovery_deb = ret if self.add_dell_recovery_deb: ok_button.set_sensitive(True)
def _get_clone_info_dict(self, statefile): distro = self._get_info_distro(statefile) or "unknown" # nr installed with tarfile.open(statefile) as tar: f = tar.extractfile(self.TARPREFIX + "var/lib/apt-clone/installed.pkgs") installed = autoinstalled = 0 meta = [] for line in f.readlines(): line = line.decode("utf-8") (name, version, auto) = line.strip().split() installed += 1 if int(auto): autoinstalled += 1 # FIXME: this is a bad way to figure out about the # meta-packages if name.endswith("-desktop"): meta.append(name) # date m = tar.getmember(self.TARPREFIX + "var/lib/apt-clone/installed.pkgs") date = m.mtime # check hostname (if found) hostname = "unknown" arch = "unknown" if self.TARPREFIX + "var/lib/apt-clone/uname" in tar.getnames(): info = tar.extractfile(self.TARPREFIX + "var/lib/apt-clone/uname").read() section = apt_pkg.TagSection(info) hostname = section.get("hostname", "unknown") arch = section.get("arch", "unknown") return { 'hostname': hostname, 'distro': distro, 'meta': ", ".join(meta), 'installed': installed, 'autoinstalled': autoinstalled, 'date': time.ctime(date), 'arch': arch, }
def extractAndParseControl(self): """Extract and parse control information.""" try: deb_file = apt_inst.DebFile(self.filepath) control_file = deb_file.control.extractdata("control") control_lines = apt_pkg.TagSection(control_file) except (SystemExit, KeyboardInterrupt): raise except: yield UploadError( "%s: extracting control file raised %s, giving up." % (self.filename, sys.exc_type)) return for mandatory_field in self.mandatory_fields: if control_lines.find(mandatory_field) is None: yield UploadError("%s: control file lacks mandatory field %r" % (self.filename, mandatory_field)) control = {} for key in control_lines.keys(): control[key] = control_lines.find(key) self.parseControl(control)
def info(self, statefile): distro = self._get_info_distro(statefile) or "unknown" # nr installed tar = tarfile.open(statefile) f = tar.extractfile(self.TARPREFIX+"var/lib/apt-clone/installed.pkgs") installed = autoinstalled = 0 meta = [] for line in f.readlines(): (name, version, auto) = line.strip().split() installed += 1 if int(auto): autoinstalled += 1 if name.endswith("-desktop"): meta.append(name) # date m = tar.getmember(self.TARPREFIX+"var/lib/apt-clone/installed.pkgs") date = m.mtime # check hostname (if found) hostname = "unknown" arch = "unknown" if self.TARPREFIX+"var/lib/apt-clone/uname" in tar.getnames(): info = tar.extractfile(self.TARPREFIX+"var/lib/apt-clone/uname").read() section = apt_pkg.TagSection(info) hostname = section.get("hostname", "unknown") arch = section.get("arch", "unknown") return "Hostname: %(hostname)s\n"\ "Arch: %(arch)s\n"\ "Distro: %(distro)s\n"\ "Meta: %(meta)s\n"\ "Installed: %(installed)s pkgs (%(autoinstalled)s automatic)\n"\ "Date: %(date)s\n" % { 'hostname' : hostname, 'distro' : distro, 'meta' : ", ".join(meta), 'installed' : installed, 'autoinstalled' : autoinstalled, 'date' : time.ctime(date), 'arch' : arch, }
def _add_package(self, packages_file, name, architecture="all", version="1.0", description="description", control_fields=None): if control_fields is None: control_fields = {} package_stanza = textwrap.dedent( """ Package: %(name)s Priority: optional Section: misc Installed-Size: 1234 Maintainer: Someone Architecture: %(architecture)s Source: source Version: %(version)s Description: short description %(description)s """ % { "name": name, "version": version, "architecture": architecture, "description": description }).encode("utf-8") # We want to re-order the TagSection, but it requires bytes as input. # As we also want to write a binary file, we have to explicitly pass # the hardly documented `bytes=True` to TagSection as it would be # returned as unicode in Python 3 otherwise. In future versions of # apt_pkg there should be a TagSection.write() which is recommended. package_stanza = apt_pkg.rewrite_section( apt_pkg.TagSection(package_stanza, bytes=True), apt_pkg.REWRITE_PACKAGE_ORDER, list(control_fields.items())) append_binary_file(packages_file, b"\n" + package_stanza + b"\n")
% (member.name, member.linkname, member.mode, member.uid, member.gid, member.size, member.mtime, member.major, member.minor) if __name__ == "__main__": if len(sys.argv) < 2: print "need filename argumnet" sys.exit(1) file = sys.argv[1] print "Working on: %s" % file print "Displaying data.tar.gz:" apt_inst.DebFile(open(file)).data.go(Callback) print "Now extracting the control file:" control = apt_inst.DebFile(open(file)).control.extractdata("control") sections = apt_pkg.TagSection(control) print "Maintainer is: " print sections["Maintainer"] print print "DependsOn: " depends = sections["Depends"] print apt_pkg.parse_depends(depends) print "extracting archive" dir = "/tmp/deb" os.mkdir(dir) apt_inst.DebFile(open(file)).data.extractall(dir) def visit(arg, dirname, names):
def parse(self, control, blob_id): """Parse control file contents. Returns a package object.""" tags = apt_pkg.TagSection(control) return self.parse_tags(tags, blob_id)
#!/usr/bin/env python # # a example that prints the URIs of all upgradable packages # import apt import apt_pkg cache = apt.Cache() upgradable = filter(lambda p: p.isUpgradable, cache) for pkg in upgradable: pkg._lookupRecord(True) path = apt_pkg.TagSection(pkg._records.Record)["Filename"] cand = pkg._depcache.GetCandidateVer(pkg._pkg) for (packagefile, i) in cand.FileList: indexfile = cache._list.FindIndex(packagefile) if indexfile: uri = indexfile.ArchiveURI(path) print uri
def test_write_invalid_order(self): ts = apt_pkg.TagSection("a: 1\nb: 2\nc: 3\n") outpath = os.path.join(self.temp_dir, "test") with io.open(outpath, "w") as outfile: self.assertRaises(TypeError, ts.write, outfile, ["a", 1, "b"], [])
def __init__(self, record_str): self._rec = apt_pkg.TagSection(record_str)