You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			76 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			Python
		
	
			
		
		
	
	
			76 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			Python
		
	
import logging
 | 
						|
import os
 | 
						|
import tempfile
 | 
						|
import shutil
 | 
						|
import json
 | 
						|
from subprocess import check_call, check_output
 | 
						|
from tarfile import TarFile
 | 
						|
 | 
						|
from dateutil.zoneinfo import METADATA_FN, ZONEFILENAME
 | 
						|
 | 
						|
 | 
						|
def rebuild(filename, tag=None, format="gz", zonegroups=[], metadata=None):
 | 
						|
    """Rebuild the internal timezone info in dateutil/zoneinfo/zoneinfo*tar*
 | 
						|
 | 
						|
    filename is the timezone tarball from ``ftp.iana.org/tz``.
 | 
						|
 | 
						|
    """
 | 
						|
    tmpdir = tempfile.mkdtemp()
 | 
						|
    zonedir = os.path.join(tmpdir, "zoneinfo")
 | 
						|
    moduledir = os.path.dirname(__file__)
 | 
						|
    try:
 | 
						|
        with TarFile.open(filename) as tf:
 | 
						|
            for name in zonegroups:
 | 
						|
                tf.extract(name, tmpdir)
 | 
						|
            filepaths = [os.path.join(tmpdir, n) for n in zonegroups]
 | 
						|
 | 
						|
            _run_zic(zonedir, filepaths)
 | 
						|
 | 
						|
        # write metadata file
 | 
						|
        with open(os.path.join(zonedir, METADATA_FN), 'w') as f:
 | 
						|
            json.dump(metadata, f, indent=4, sort_keys=True)
 | 
						|
        target = os.path.join(moduledir, ZONEFILENAME)
 | 
						|
        with TarFile.open(target, "w:%s" % format) as tf:
 | 
						|
            for entry in os.listdir(zonedir):
 | 
						|
                entrypath = os.path.join(zonedir, entry)
 | 
						|
                tf.add(entrypath, entry)
 | 
						|
    finally:
 | 
						|
        shutil.rmtree(tmpdir)
 | 
						|
 | 
						|
 | 
						|
def _run_zic(zonedir, filepaths):
 | 
						|
    """Calls the ``zic`` compiler in a compatible way to get a "fat" binary.
 | 
						|
 | 
						|
    Recent versions of ``zic`` default to ``-b slim``, while older versions
 | 
						|
    don't even have the ``-b`` option (but default to "fat" binaries). The
 | 
						|
    current version of dateutil does not support Version 2+ TZif files, which
 | 
						|
    causes problems when used in conjunction with "slim" binaries, so this
 | 
						|
    function is used to ensure that we always get a "fat" binary.
 | 
						|
    """
 | 
						|
 | 
						|
    try:
 | 
						|
        help_text = check_output(["zic", "--help"])
 | 
						|
    except OSError as e:
 | 
						|
        _print_on_nosuchfile(e)
 | 
						|
        raise
 | 
						|
 | 
						|
    if b"-b " in help_text:
 | 
						|
        bloat_args = ["-b", "fat"]
 | 
						|
    else:
 | 
						|
        bloat_args = []
 | 
						|
 | 
						|
    check_call(["zic"] + bloat_args + ["-d", zonedir] + filepaths)
 | 
						|
 | 
						|
 | 
						|
def _print_on_nosuchfile(e):
 | 
						|
    """Print helpful troubleshooting message
 | 
						|
 | 
						|
    e is an exception raised by subprocess.check_call()
 | 
						|
 | 
						|
    """
 | 
						|
    if e.errno == 2:
 | 
						|
        logging.error(
 | 
						|
            "Could not find zic. Perhaps you need to install "
 | 
						|
            "libc-bin or some other package that provides it, "
 | 
						|
            "or it's not in your PATH?")
 |