[Pkg-python-debian-commits] r65 trunk: first checkin of DebFile, which extends ArFile with .deb-specific functionalities
zack at bononia.it
zack at bononia.it
Sat Jul 14 08:59:46 UTC 2007
------------------------------------------------------------
revno: 65
committer: zack at bononia.it
branch nick: pkg-python-debian.debfile
timestamp: Sat 2007-07-14 10:59:46 +0200
message:
first checkin of DebFile, which extends ArFile with .deb-specific functionalities
added:
debian_bundle/debfile.py
-------------- next part --------------
=== added file 'debian_bundle/debfile.py'
--- a/debian_bundle/debfile.py 1970-01-01 00:00:00 +0000
+++ b/debian_bundle/debfile.py 2007-07-14 08:59:46 +0000
@@ -0,0 +1,132 @@
+import arfile
+import gzip
+import tarfile
+
+DATA_PART = 'data.tar.gz'
+CTRL_PART = 'control.tar.gz'
+INFO_PART = 'debian-binary'
+MAINT_SCRIPTS = ['preinst', 'postinst', 'prerm', 'postrm', 'config']
+
+CTRL_FILE = 'control'
+MD5_FILE = 'md5sums'
+
+class DebError(arfile.ArError):
+ pass
+
+
+class DebPart(object):
+ """'Part' of a .deb binary package.
+
+ A .deb package is considered as made of 2 parts: a 'data' part
+ (corresponding to the 'data.tar.gz' archive embedded in a .deb) and a
+ 'control' part (the 'control.tar.gz' archive)."""
+
+ def __init__(self, member):
+ self.__member = member # arfile.ArMember file member
+ self.__tgz = None
+
+ def tgz(self):
+ """Return a TarFile object corresponding to this part of a .deb
+ package."""
+
+ if self.__tgz is None:
+ gzfile = gzip.GzipFile(fileobj=self.__member)
+ tarfile = tarfile.TarFile(fileobj=gzfile)
+ self.__tgz = tarfile
+ return self.__tgz
+
+ def has_file(self, fname):
+ """Check if this part contains a given file name."""
+
+ return (fname in self.tgz().getnames())
+
+ def get_file(self, fname):
+ """Return a file object corresponding to a given file name."""
+
+ return (self.tgz().extractfile(fname))
+
+ def get_content(self, fname):
+ """Return the string content of a given file."""
+
+ f = self.tgz().extractfile(fname)
+ content = f.read()
+ f.close()
+ return content
+
+ # container emulation
+
+ def __iter__(self):
+ return iter(self.tgz().getnames())
+
+ def __contains__(self, fname):
+ return self.has_file(fname)
+
+ def __getitem__(self, fname):
+ return self.get_content(fname)
+
+
+class DebData(DebPart):
+
+ pass
+
+
+class DebControl(DebPart):
+
+ def scripts(self):
+ """ Return a dictionary of maintainer scripts (postinst, prerm, ...)
+ mapping script names to script text. """
+
+ scripts = {}
+ for fname in MAINT_SCRIPTS:
+ if self.has_file(fname):
+ scripts[fname] = self.get_content(fname)
+
+ return scripts
+
+ def control(self):
+ """ Return the debian/control as a string.
+
+ Convenience method, same as: .get_content('control') """
+
+ return self.get_content(CTRL_FILE)
+
+ def md5sums(self):
+ """ Return a dictionary mapping filenames (of the data part) to
+ md5sums. Fails if the control part does not contain a 'md5sum' file. """
+
+ if not self.has_file(MD5_FILE):
+ raise DebError("'%s' file not found, can't list MD5 sums" %
+ MD5_FILE)
+
+ md5_file = self.get_file(MD5_FILE)
+ sums = {}
+ for line in md5_file:
+ md5, fname = line.split()
+ sums[fname] = md5
+ md5_file.close()
+ return sums
+
+class DebFile(arfile.ArFile):
+
+ def __init__(self, **args):
+ ArFile.__init__(self, **args)
+ if set(self.getnames()) != set([INFO_PART, CTRL_PART, DATA_PART])
+ raise DebError('unexpected .deb content')
+
+ self.__parts = {}
+ self.__parts[DATA_PART] = DebData(self.getmember(DATA_PART))
+ self.__parts[CTRL_PART] = DebControl(self.getmember(CTRL_PART))
+
+ f = self.getmember(INFO_PART)
+ self.__version = f.read().strip()
+ f.close()
+
+ def getVersion(self): return self.__version
+ version = property(getVersion)
+
+ def getData(self): return self.__parts[DATA_PART]
+ data = property(getData)
+
+ def getCtrl(self): return self.__parts[CTRL_PART]
+ control = property(getCtrl)
+
More information about the pkg-python-debian-commits
mailing list