• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/python -B
2
3# Copyright 2017 The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9#      http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
17"""Downloads the latest IANA timezone data."""
18
19from __future__ import print_function
20
21import ftplib
22import os
23import shutil
24import subprocess
25import sys
26
27sys.path.append('%s/external/icu/tools' % os.environ.get('ANDROID_BUILD_TOP'))
28import i18nutil
29import tzdatautil
30
31# Calculate the paths that are referred to by multiple functions.
32android_build_top = i18nutil.GetAndroidRootOrDie()
33iana_data_dir = os.path.realpath('%s/system/timezone/input_data/iana' % android_build_top)
34
35def FtpRetrieveFile(ftp, filename):
36  ftp.retrbinary('RETR %s' % filename, open(filename, 'wb').write)
37
38def CheckSignature(data_filename, signature_filename):
39  """Checks the signature of a file."""
40  print('Verifying signature...')
41  try:
42    subprocess.check_call(['gpg', '--trusted-key=ED97E90E62AA7E34', '--verify',
43                          signature_filename, data_filename])
44  except subprocess.CalledProcessError as err:
45    print('Unable to verify signature')
46    print('\n\n******')
47    print('If this fails for you, you probably need to import Paul Eggert''s public key:')
48    print('  gpg --receive-keys ED97E90E62AA7E34')
49    print('******\n\n')
50    raise
51
52# Run with no arguments from any directory, with no special setup required.
53# See http://www.iana.org/time-zones/ for more about the source of this data.
54def main():
55  print('Looking for new IANA tzdata...')
56
57  tar_prefix = 'tzdata20'
58  # Use the input tzdata version name if it exists
59  if len(sys.argv) > 1:
60    tar_prefix = 'tzdata' + sys.argv[1]
61
62  iana_tar_filenames = []
63
64  ftp = ftplib.FTP('ftp.iana.org')
65  ftp.login()
66  ftp.cwd('tz/releases')
67  for filename in ftp.nlst():
68    if "/" in filename:
69      print("FTP server returned bogus file name")
70      sys.exit(1)
71
72    if filename.startswith(tar_prefix) and filename.endswith('.tar.gz'):
73      iana_tar_filenames.append(filename)
74  iana_tar_filenames.sort(reverse=True)
75
76  if len(iana_tar_filenames) == 0:
77    print('No tzdata files found')
78    sys.exit(1)
79
80  latest_iana_tar_filename = iana_tar_filenames[0]
81
82  local_iana_tar_file = tzdatautil.GetIanaTarFile(iana_data_dir, 'data')
83
84  if local_iana_tar_file:
85    local_iana_tar_filename = os.path.basename(local_iana_tar_file)
86    if latest_iana_tar_filename <= local_iana_tar_filename:
87      print('Available data %s is older or the same as current data %s' % (latest_iana_tar_filename, local_iana_tar_filename))
88      sys.exit(0)
89
90  print('Found new tzdata: %s' % latest_iana_tar_filename)
91  i18nutil.SwitchToNewTemporaryDirectory()
92
93  print('Downloading data (%s)...' % latest_iana_tar_filename)
94  FtpRetrieveFile(ftp, latest_iana_tar_filename)
95
96  signature_filename = '%s.asc' % latest_iana_tar_filename
97  print('Downloading signature (%s)...' % signature_filename)
98  FtpRetrieveFile(ftp, signature_filename)
99
100  CheckSignature(latest_iana_tar_filename, signature_filename)
101
102  new_local_iana_tar_file = '%s/%s' % (iana_data_dir, latest_iana_tar_filename)
103  shutil.copyfile(latest_iana_tar_filename, new_local_iana_tar_file)
104  new_local_signature_file = '%s/%s' % (iana_data_dir, signature_filename)
105  shutil.copyfile(signature_filename, new_local_signature_file)
106
107  # Delete the existing local IANA tar file, if there is one.
108  if local_iana_tar_file:
109    os.remove(local_iana_tar_file)
110
111  local_signature_file = '%s.asc' % local_iana_tar_file
112  if os.path.exists(local_signature_file):
113    os.remove(local_signature_file)
114
115  print('Look in %s for new IANA data files' % new_local_iana_tar_file)
116  sys.exit(0)
117
118
119if __name__ == '__main__':
120  main()
121