• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1import logging
2import os
3import tempfile
4import shutil
5import json
6from subprocess import check_call
7from tarfile import TarFile
8
9from dateutil.zoneinfo import METADATA_FN, ZONEFILENAME
10
11
12def rebuild(filename, tag=None, format="gz", zonegroups=[], metadata=None):
13    """Rebuild the internal timezone info in dateutil/zoneinfo/zoneinfo*tar*
14
15    filename is the timezone tarball from ``ftp.iana.org/tz``.
16
17    """
18    tmpdir = tempfile.mkdtemp()
19    zonedir = os.path.join(tmpdir, "zoneinfo")
20    moduledir = os.path.dirname(__file__)
21    try:
22        with TarFile.open(filename) as tf:
23            for name in zonegroups:
24                tf.extract(name, tmpdir)
25            filepaths = [os.path.join(tmpdir, n) for n in zonegroups]
26            try:
27                check_call(["zic", "-d", zonedir] + filepaths)
28            except OSError as e:
29                _print_on_nosuchfile(e)
30                raise
31        # write metadata file
32        with open(os.path.join(zonedir, METADATA_FN), 'w') as f:
33            json.dump(metadata, f, indent=4, sort_keys=True)
34        target = os.path.join(moduledir, ZONEFILENAME)
35        with TarFile.open(target, "w:%s" % format) as tf:
36            for entry in os.listdir(zonedir):
37                entrypath = os.path.join(zonedir, entry)
38                tf.add(entrypath, entry)
39    finally:
40        shutil.rmtree(tmpdir)
41
42
43def _print_on_nosuchfile(e):
44    """Print helpful troubleshooting message
45
46    e is an exception raised by subprocess.check_call()
47
48    """
49    if e.errno == 2:
50        logging.error(
51            "Could not find zic. Perhaps you need to install "
52            "libc-bin or some other package that provides it, "
53            "or it's not in your PATH?")
54