#!/usr/bin/python
# Download updated modules for xanim from the Mark Podlipec's FTP site
#
# (C) 1999-2001 Chris Lawrence.
# You may freely distribute this file under the terms of the GNU General
# Public License, version 2 or later.

import commands, sys, fnmatch, string, tempfile, os, string, popen2, urllib
import urlparse, StringIO, ftplib

def my_read(fp, length=None):
    input = ''
    count = 0
    if length is not None:
        while len(input) < length:
            desired = length - len(input)
            if desired > 2048: desired=2048
            stuff = fp.read(desired)
            if stuff:
                input = input+stuff
                sys.stderr.write('.')
                sys.stderr.flush()
            else:
                break
    else:
        stuff = fp.read(2048)
        input = input+stuff
        sys.stderr.write('.')
        sys.stderr.flush()
        while stuff:
            stuff = fp.read(2048)
            input = input+stuff
            sys.stderr.write('.')
            sys.stderr.flush()
    
    return input

# FTP site and directory
URLROOT='ftp://xanim.va.pubnix.com/dlls/'

# Where the module file registry goes; don't change this location!
LOGFILE='/usr/lib/xanim/xanim-modules'

# Mapping from Debian architectures to Mark's
ARCHMAP = { 'powerpc' : 'linuxELFppc',
            'alpha' : 'linuxELFalphaC6',
            'i386' : 'linuxELFx86c6' }

# Mapping of available modules and versions
FILEMAP = { 'powerpc' : ('cvid_2.1', 'cyuv_1.0', 'h261_1.0', 'h263_1.0',
                         'iv32_2.1', 'iv41_1.1', 'iv50_1.0'),
            'alpha' : ('cvid_2.1', 'cyuv_1.0', 'h261_1.0', 'h263_1.1',
                       'iv32_2.1', 'iv41_1.1', 'iv50_1.0'),
            'i386' : ('cvid_2.1', 'cyuv_1.0', 'h261_1.0', 'h263_1.1',
                      'iv32_2.1', 'iv41_1.1', 'iv50_1.0')
            }

# Mapping of modules and their long names
MODNAMES = { 'cvid' : 'Radius Cinepak',
             'cyuv' : 'Creative CYUV',
             'h261' : 'CCITT H.261',
             'h263' : 'CCITT H.263',
             'iv32' : 'Intel Indeo 3.1, 3.2',
             'iv41' : 'Intel Indeo 4.1',
             'iv50' : 'Intel Indeo 5.0' }

def main():
    if len(sys.argv) > 1 and sys.argv[1] == '--sanitation':
        if not os.path.exists(LOGFILE):
            sys.exit(0)

        print 'update-xanim-modules: Fixing module paths and permissions'
        installed = map(string.strip, open(LOGFILE).readlines())
        installed = map(lambda x: os.path.join('/usr/lib/xanim', x), installed)
        newinst = []

        fp = open(LOGFILE, 'w', 0644)
        for file in installed:
            if '\0' in file: continue
            if not file in newinst:
                file = os.path.join('/usr/lib/xanim', file)
                (dir, filename) = os.path.split(file)

                # Throw out any bogus files
                if dir != '/usr/lib/xanim': continue
                if not os.path.exists(file): continue

                fp.write(file+'\n')
                os.chmod(file, 0644)
                os.chown(file, 0, 0)
                newinst.append(file)

        fp.close()
        sys.exit(0)

    arch = commands.getoutput('dpkg --print-installation-architecture')

    xanim_arch = ARCHMAP.get(arch)
    needed = FILEMAP.get(arch)

    if not xanim_arch or not needed:
        print 'No xanim modules are available for '+arch
        sys.exit(0)

    if len(sys.argv) > 1:
        urlroot = 'file:'+os.path.abspath(sys.argv[1])+'/'
        pasv = 0
    else:
        urlroot = URLROOT
        print """
These modules may be useful if you have animations in egregiously
non-free formats you wish to display.  However, because the author is
unable to distribute source for them, you should consider whether you
trust him enough to install his code sight-unseen on your system.  The
maintainer of this package has not seen the source code for these
modules and therefore cannot make any guarantees as to their security
implications.  Caveat downloader."""
        print

        ok = ''
        while ok != 'y':
            ok = raw_input('Download xanim modules? [yes/no] ')
            if ok: ok = string.lower(ok[0])

            if ok == 'n':
                print
                print 'You can also install the modules by downloading the'
                print 'following files from '+URLROOT+':'
                for module in needed:
                    print '  vid_%s_%s.tgz' % (module, xanim_arch)
                print 'Then run "update-xanim-modules DIR", where DIR is the'
                print 'name of the directory that contains the downloaded files.'
                sys.exit(0)
            elif ok != 'y':
                print 'Please say yes or no.'

        print "Do you need to use passive FTP mode?"
        print """
Passive FTP mode is generally only necessary if you have a transparent
firewall or IP masquerading (NAT) setup.  Most people do not need to use
passive mode.  (If you have a firewall and use a standard HTTP proxy server
for Internet access, answer no; instead, read the man page for
update-xanim-modules to set up the required proxy environment variable.)"""
        print
        pasv = 1
        ok = ''
        while 1:
            ok = raw_input('Use passive FTP? [yes/no] ')
            if ok: ok = string.lower(ok[0])

            if ok == 'y':
                pasv = 1
                break
            elif ok == 'n':
                pasv = 0
                break

            print 'Please say yes or no.'

    if os.path.exists(LOGFILE):
        installed = map(string.strip, open(LOGFILE).readlines())
        installed = map(lambda x: os.path.join('/usr/lib/xanim', x), installed)
        installed = filter(lambda x: ('\0' not in x) and
                           (os.path.split(x)[0] == '/usr/lib/xanim')
                           and os.path.exists(x), installed)
    else:
        installed = []

    tempfile.tempdir = os.environ.get('TMPDIR', '/tmp')
    print 'Downloading and installing from '+urlroot
    if pasv:
        bits = urlparse.urlparse(urlroot)
        site, dir = bits[1:3]
        conn = ftplib.FTP(site)
        conn.login()
        conn.set_pasv(1)
        conn.cwd(dir)
    else:
        conn = None
    
    os.chdir('/usr/lib/xanim')
    for module in needed:
        # Filenames in this directory are "vid_TYPE_VER_ARCH.tgz"
        file = 'vid_%s_%s.tgz' % (module, xanim_arch)
        (type, version) = string.split(module, '_')
        type = MODNAMES.get(type, type+' support')
        sys.stderr.write('    %s (%s) ' % (file, type))
        sys.stderr.flush()
        mask = os.umask(0133)
        (fpout, fpin) = popen2.popen2('tar --no-same-owner '
                                      '--no-same-permissions -zvxf -')
        os.umask(mask)
        if pasv:
            urlfp = None
            sys.stderr.write('+')
            sys.stderr.flush()
            conn.retrbinary('RETR '+file, fpin.write)
            sys.stderr.write('.')
            sys.stderr.flush()
        else:
            urlfp = urllib.urlopen(urlroot+file)
            sys.stderr.write('+')
            sys.stderr.flush()
            # Use our cute hashmark printer
            fpin.write(my_read(urlfp))
        fpin.close()
        sys.stderr.write('\n')

        newfiles = map(string.strip, fpout.readlines())
        newfiles = map(lambda x: os.path.join('/usr/lib/xanim', x), newfiles)
        for nf in newfiles:
            while installed.count(nf) > 1: installed.remove(nf)
            if nf not in installed: installed.append(nf)

        fpout.close()
        if urlfp:
            urlfp.close()

    if conn:
        conn.close()

    installed.sort()
    fp = open(LOGFILE, 'w', 0644)
    for file in installed:
        fp.write(file+'\n')

    print 'All modules downloaded and installed.'

if __name__ == '__main__':
    main()
