"""Download `Unicodedata` files."""
from __future__ import unicode_literals
import os
import zipfile
import codecs
from urllib.request import urlopen

__version__ = '2.2.0'

HOME = os.path.dirname(os.path.abspath(__file__))


def zip_unicode(output, version):
    """Zip the Unicode files."""

    zipper = zipfile.ZipFile(os.path.join(output, 'unicodedata', '%s.zip' % version), 'w', zipfile.ZIP_DEFLATED)
    target = os.path.join(output, 'unicodedata', version)

    print('Zipping %s.zip...' % version)

    for root, dirs, files in os.walk(target):
        for file in files:
            if file.endswith('.txt'):
                zipper.write(os.path.join(root, file), arcname=file)


def unzip_unicode(output, version):
    """Unzip the Unicode files."""

    unzipper = zipfile.ZipFile(os.path.join(output, 'unicodedata', '%s.zip' % version))
    target = os.path.join(output, 'unicodedata', version)

    print('Unzipping %s.zip...' % version)

    os.makedirs(target)

    for f in unzipper.namelist():
        # Do I need backslash on windows? Or is it forward as well?
        unzipper.extract(f, target)


def download_unicodedata(version, output=HOME, no_zip=False):
    """Download Unicode data scripts and blocks."""

    ver = tuple([int(x) for x in version.split('.')])

    files = [
        'UnicodeData.txt',
        'Scripts.txt',
        'Blocks.txt',
        'PropList.txt',
        'DerivedCoreProperties.txt',
        'DerivedNormalizationProps.txt',
        'CompositionExclusions.txt',
        'PropertyValueAliases.txt',
        'PropertyAliases.txt',
        'EastAsianWidth.txt',
        'LineBreak.txt',
        'HangulSyllableType.txt',
        'DerivedAge.txt',
        'auxiliary/WordBreakProperty.txt',
        'auxiliary/SentenceBreakProperty.txt',
        'auxiliary/GraphemeBreakProperty.txt',
        'extracted/DerivedDecompositionType.txt',
        'extracted/DerivedNumericType.txt',
        'extracted/DerivedNumericValues.txt',
        'extracted/DerivedJoiningType.txt',
        'extracted/DerivedJoiningGroup.txt',
        'extracted/DerivedCombiningClass.txt',
        'emoji/emoji-data.txt'
    ]

    files.append('ScriptExtensions.txt')
    files.append('IndicPositionalCategory.txt')
    files.append('IndicSyllabicCategory.txt')
    files.append('BidiBrackets.txt')

    if ver >= (11, 0, 0):
        files.append('VerticalOrientation.txt')

    http_url = 'http://www.unicode.org/Public/%s/ucd/' % version
    ftp_url = 'ftp://ftp.unicode.org/Public/%s/ucd/' % version

    destination = os.path.join(output, 'unicodedata', version)
    if not os.path.exists(destination):
        os.makedirs(destination)

    zip_data = not no_zip

    for f in files:
        file_location = os.path.join(destination, os.path.basename(f))
        retrieved = False
        if not os.path.exists(file_location):
            for url in (ftp_url, http_url):
                furl = url + f
                try:
                    print('Downloading: %s --> %s' % (furl, file_location))
                    response = urlopen(furl, timeout=30)
                    data = response.read()
                except Exception:
                    print('Failed: %s' % url)
                    continue
                with codecs.open(file_location, 'w', encoding='utf-8') as uf:
                    uf.write(data.decode('utf-8'))
                retrieved = True
                break
            if not retrieved:
                print('Failed to acquire all needed Unicode files!')
                break
        else:
            retrieved = True
            print('Skipping: found %s' % file_location)

        if not retrieved:
            zip_data = False
            break

    if zip_data and not os.path.exists(os.path.join(output, 'unicodedata', '%s.zip' % version)):
        zip_unicode(output, version)


def get_unicodedata(version, output=HOME, no_zip=False):
    """Ensure we have Unicode data to generate Unicode tables."""

    target = os.path.join(output, 'unicodedata', version)
    zip_target = os.path.join(output, 'unicodedata', '%s.zip' % version)

    if not os.path.exists(target) and os.path.exists(zip_target):
        unzip_unicode(output, version)

    # Download missing files if any. Zip if required.
    download_unicodedata(version, output, no_zip)


if __name__ == '__main__':
    import argparse
    import unicodedata

    parser = argparse.ArgumentParser(prog='unidatadownload', description='Generate a unicode property table.')
    parser.add_argument('--version', action='version', version="%(prog)s " + __version__)
    parser.add_argument('--output', default=HOME, help='Output file.')
    parser.add_argument('--unicode-version', default=None, help='Force a specific Unicode version.')
    args = parser.parse_args()

    if args.unicode_version is None:
        version = unicodedata.unidata_version
    else:
        version = args.unicode_version

    get_unicodedata(version, output=args.output)

[((10, 23, 10, 48), 'os.path.abspath', 'os.path.abspath', ({(10, 39, 10, 47): '__file__'}, {}), '(__file__)', False, 'import os\n'), ((17, 13, 17, 57), 'os.path.join', 'os.path.join', ({(17, 26, 17, 32): 'output', (17, 34, 17, 47): '"""unicodedata"""', (17, 49, 17, 56): 'version'}, {}), "(output, 'unicodedata', version)", False, 'import os\n'), ((21, 29, 21, 44), 'os.walk', 'os.walk', ({(21, 37, 21, 43): 'target'}, {}), '(target)', False, 'import os\n'), ((31, 13, 31, 57), 'os.path.join', 'os.path.join', ({(31, 26, 31, 32): 'output', (31, 34, 31, 47): '"""unicodedata"""', (31, 49, 31, 56): 'version'}, {}), "(output, 'unicodedata', version)", False, 'import os\n'), ((35, 4, 35, 23), 'os.makedirs', 'os.makedirs', ({(35, 16, 35, 22): 'target'}, {}), '(target)', False, 'import os\n'), ((84, 18, 84, 62), 'os.path.join', 'os.path.join', ({(84, 31, 84, 37): 'output', (84, 39, 84, 52): '"""unicodedata"""', (84, 54, 84, 61): 'version'}, {}), "(output, 'unicodedata', version)", False, 'import os\n'), ((125, 13, 125, 57), 'os.path.join', 'os.path.join', ({(125, 26, 125, 32): 'output', (125, 34, 125, 47): '"""unicodedata"""', (125, 49, 125, 56): 'version'}, {}), "(output, 'unicodedata', version)", False, 'import os\n'), ((126, 17, 126, 72), 'os.path.join', 'os.path.join', ({(126, 30, 126, 36): 'output', (126, 38, 126, 51): '"""unicodedata"""', (126, 53, 126, 71): "'%s.zip' % version"}, {}), "(output, 'unicodedata', '%s.zip' % version)", False, 'import os\n'), ((139, 13, 139, 110), 'argparse.ArgumentParser', 'argparse.ArgumentParser', (), '', False, 'import argparse\n'), ((16, 29, 16, 84), 'os.path.join', 'os.path.join', ({(16, 42, 16, 48): 'output', (16, 50, 16, 63): '"""unicodedata"""', (16, 65, 16, 83): "'%s.zip' % version"}, {}), "(output, 'unicodedata', '%s.zip' % version)", False, 'import os\n'), ((30, 31, 30, 86), 'os.path.join', 'os.path.join', ({(30, 44, 30, 50): 'output', (30, 52, 30, 65): '"""unicodedata"""', (30, 67, 30, 85): "'%s.zip' % version"}, {}), "(output, 'unicodedata', '%s.zip' % version)", False, 'import os\n'), ((85, 11, 85, 38), 'os.path.exists', 'os.path.exists', ({(85, 26, 85, 37): 'destination'}, {}), '(destination)', False, 'import os\n'), ((86, 8, 86, 32), 'os.makedirs', 'os.makedirs', ({(86, 20, 86, 31): 'destination'}, {}), '(destination)', False, 'import os\n'), ((128, 38, 128, 64), 'os.path.exists', 'os.path.exists', ({(128, 53, 128, 63): 'zip_target'}, {}), '(zip_target)', False, 'import os\n'), ((91, 50, 91, 69), 'os.path.basename', 'os.path.basename', ({(91, 67, 91, 68): 'f'}, {}), '(f)', False, 'import os\n'), ((93, 15, 93, 44), 'os.path.exists', 'os.path.exists', ({(93, 30, 93, 43): 'file_location'}, {}), '(file_location)', False, 'import os\n'), ((128, 11, 128, 33), 'os.path.exists', 'os.path.exists', ({(128, 26, 128, 32): 'target'}, {}), '(target)', False, 'import os\n'), ((118, 39, 118, 94), 'os.path.join', 'os.path.join', ({(118, 52, 118, 58): 'output', (118, 60, 118, 73): '"""unicodedata"""', (118, 75, 118, 93): "('%s.zip' % version)"}, {}), "(output, 'unicodedata', '%s.zip' % version)", False, 'import os\n'), ((24, 29, 24, 53), 'os.path.join', 'os.path.join', ({(24, 42, 24, 46): 'root', (24, 48, 24, 52): 'file'}, {}), '(root, file)', False, 'import os\n'), ((98, 31, 98, 56), 'urllib.request.urlopen', 'urlopen', (), '', False, 'from urllib.request import urlopen\n'), ((103, 21, 103, 70), 'codecs.open', 'codecs.open', (), '', False, 'import codecs\n')]