new contributed stuff: DebFile

Stefano Zacchiroli zack at debian.org
Sun Jul 15 10:04:01 UTC 2007


Hi, I've a new proposed contribution for python-debian. The preview
release is available at:

  $ bzr branch http://people.debian.org/~zack/bzr/pkg-python-debian

The contribution contains two modules: arfile.py and debfile.py. The
former is non Debian-specific and handles 'ar' archives mimicking what
TarFile does for 'tar' archives.  The latter contains Debian-specific
extensions for handling .deb files and give access to .deb information
similar to what dpkg --info can do.  It also has some more high level
access to control files (returning Deb882 objects) and to changelogs
(returning Changelog objects).

Some examples, just to give the feeling of how the modules are used, are
available in the branch and also attached to this email.

The code has been written by me and Filippo Giunchedi.

What do you think of adding this to python-debian? Any suggestion about
the API before people start using it?

Cheers.

-- 
Stefano Zacchiroli -*- PhD in Computer Science ............... now what?
zack@{cs.unibo.it,debian.org,bononia.it} -%- http://www.bononia.it/zack/
(15:56:48)  Zack: e la demo dema ?    /\    All one has to do is hit the
(15:57:15)  Bac: no, la demo scema    \/    right keys at the right time
-------------- next part --------------
#!/usr/bin/python

# ar.py: ar emulation using ArFile 
# Copyright (C) 2007    Filippo Giunchedi   <filippo at debian.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

import os
import sys

import arfile

if __name__ == '__main__':
    if len(sys.argv) < 3:
        print "usage: arfile.py [tp] <arfile>"
        sys.exit(1)
    
    if not os.path.exists(sys.argv[2]):
        print "please provide a file to operate on"
        sys.exit(1)
        
    a = arfile.ArFile(sys.argv[2])

    if sys.argv[1] == 't':
        print "\n".join(a.getnames())
    elif sys.argv[1] == 'p':
        for m in a.getmembers():
            #print "".join(m.readlines())
            sys.stdout.write("".join(m.readlines()))
-------------- next part --------------
#!/usr/bin/python

# changelog_head - head like tool for .deb changelog entries
# Copyright (C) 2007 Stefano Zacchiroli <zack at debian.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.

"""Like "head" for changelog entries, return last n-th entries of the changelog
shipped in a .deb file."""

import string
import sys

import debfile

if __name__ == '__main__':
    if len(sys.argv) > 3 or len(sys.argv) < 2:
        print "Usage: changelog_head DEB [ENTRIES]"
        print "  ENTRIES defaults to 10"
        sys.exit(1)

    entries = 10
    try:
        entries = int(sys.argv[2])
    except IndexError:
        pass

    deb = debfile.DebFile(sys.argv[1])
    chg = deb.changelog()
    entries = chg._blocks[:entries]
    print string.join(map(str, entries), '')

-------------- next part --------------
#!/usr/bin/python

# dpkg-info - DebFile's implementation of "dpkg --info"
# Copyright (C) 2007 Stefano Zacchiroli <zack at debian.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.


""" (An approximation of) a 'dpkg --info' implementation relying on DebFile
class. """

import os
import stat
import string
import sys

import debfile

if __name__ == '__main__':
    if len(sys.argv) != 2:
        print "Usage: dpkg-info DEB"
        sys.exit(1)
    fname = sys.argv[1]

    deb = debfile.DebFile(fname)
    if deb.version == '2.0':
        print ' new debian package, version %s.' % deb.version
    print ' size %d bytes: control archive= %d bytes.' % (
            os.stat(fname)[stat.ST_SIZE], deb['control.tar.gz'].size)
    for fname in deb.control:   # print info about control part contents
        content = deb.control[fname]
        if not content:
            continue
        lines = content.split('\n')
        ftype = ''
        try:
            if lines[0].startswith('#!'):
                ftype = lines[0].split()[0]
        except IndexError:
            pass
        print '  %d bytes, %d lines, %s, %s' % (len(content), len(lines),
                fname, ftype)
    for n, v in deb.debcontrol().iteritems(): # print DEBIAN/control fields
        if n.lower() == 'description':  # increase indentation of long dsc
            lines = v.split('\n')
            shortDsc = lines[0]
            longDsc = string.join(map(lambda l: ' ' + l, lines[1:]), '\n')
            print ' %s: %s\n%s' % (n, shortDsc, longDsc)
        else:
            print ' %s: %s' % (n, v)

-------------- next part --------------
#!/usr/bin/python

# extract_cron - extract cron-related files from .deb s
# Copyright (C) 2007 Stefano Zacchiroli <zack at debian.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.

"""Extracts all cron-related files from a (list of) .deb package(s)."""

import os
import re
import sys

import debfile

def is_cron(fname):
    return re.match(r'^etc/cron\.(d|daily|hourly|monthly|weekly)\b', fname)

if __name__ == '__main__':
    if not sys.argv[1:]:
        print "Usage: extract_cron DEB ..."
        sys.exit(1)

    for fname in sys.argv[1:]:
        deb = debfile.DebFile(fname)
        cron_files = filter(is_cron, list(deb.data))
        for cron_file in cron_files:
            print 'Extracting cron-related file %s ...' % cron_file
            path = os.path.join('.', cron_file)
            dir = os.path.dirname(path)
            if not os.path.exists(dir):
                os.mkdir(dir)
            out = file(path, 'w')
            out.write(deb.data.get_content(cron_file))
            out.close()

-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
Url : http://lists.alioth.debian.org/pipermail/pkg-python-debian-discuss/attachments/20070715/08e15473/attachment.pgp 


More information about the pkg-python-debian-discuss mailing list