#! /usr/bin/python3
# vim: set filetype=python:

'''convert a ZIP archive to a TAR archive and write it to stdout.
usage: zip2tarcat [-h] zipfile > tarfile
'''
# This is a simplified version of zip2tar, which has more functions,
# but uses the module argument parser.

__authors__ = 'D. Gloger'
__maintainer__ = 'D. Gloger'  # with edits by B.Lindholm
__version__ = '0.2.2'
__status__ = 'Development'

# Modules for tar and zipfile handling
import os, sys, datetime, time, tarfile, zipfile

# Print function with maximal compatibility.
def print_(s):
    sys.stdout.write(s+'\n')

# Process arguments
if len(sys.argv) < 2:
    print_(__doc__)
    sys.exit(1)
if sys.argv[1] in ('-h', '--help'):
    print_(__doc__)
    sys.exit(0)
elif sys.argv[1] in ('-V', '--version'):
    print_(os.path.basename(__file__)+' v'+__version__)
    sys.exit(0)

# Input zipfile
infile = sys.argv[1]
# Read zipfile
zipf = zipfile.ZipFile(infile, 'r')
# This simplified version can only write to the standard output
tarf = tarfile.open(fileobj=sys.stdout.buffer, mode='w|')

# Loop over all filenames
for zipinfo in zipf.infolist():

    # filename
    name = zipinfo.filename

    # add file info to tar
    tarinfo = tarfile.TarInfo(name)
    tarinfo.size = zipinfo.file_size

    # convert local time from ZIP timestamp (as struct_time) ...
    local_time = datetime.datetime(*zipinfo.date_time).timetuple()
    # ... to TAR timestamp based on UTC time (as seconds since the epoch).
    tarinfo.mtime = time.mktime(local_time)

    # files:
    if zipinfo.internal_attr & 1:
        tarinfo.mode = 0o644
        tarinfo.type = tarfile.REGTYPE
    # directories:
    if name.endswith('/'):
        tarinfo.mode = 0o755
        tarinfo.type = tarfile.DIRTYPE

    # write contents of file to tar
    infile = zipf.open(zipinfo.filename, 'r')
    tarf.addfile(tarinfo, infile)

# Close both archives
tarf.close()
zipf.close()
