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

'''Converts a ZIP archive to a TAR archive and writes 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"
__version__ = "0.2.1"
__status__ = "Development"

import os
import sys

# Modules for tar and zipfile handling
import tarfile
import zipfile

# For time calculation
import datetime
import time

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

# Process arguments
if len(sys.argv) < 2:
    print_(__doc__)
    exit(1)

if sys.argv[1] in ('-h', '--help'):
    print_(__doc__)
    exit(0)
elif sys.argv[1] in ('-V', '--version'):
    print_(os.path.basename(__file__)+" v"+__version__)
    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 content of zipped file to tar
    infile = zipf.open(zipinfo.filename, 'r')
    tarf.addfile(tarinfo, infile)

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