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 19 import ftplib 20 import os 21 import shutil 22 import subprocess 23 import sys 24 25 sys.path.append('%s/external/icu/tools' % os.environ.get('ANDROID_BUILD_TOP')) 26 import i18nutil 27 import tzdatautil 28 29 # Calculate the paths that are referred to by multiple functions. 30 android_build_top = i18nutil.GetAndroidRootOrDie() 31 iana_data_dir = os.path.realpath('%s/system/timezone/input_data/iana' % android_build_top) 32 33 def FtpRetrieveFile(ftp, filename): 34 ftp.retrbinary('RETR %s' % filename, open(filename, 'wb').write) 35 36 def CheckSignature(data_filename, signature_filename): 37 """Checks the signature of a file.""" 38 print 'Verifying signature...' 39 try: 40 subprocess.check_call(['gpg', '--trusted-key=ED97E90E62AA7E34', '--verify', 41 signature_filename, data_filename]) 42 except subprocess.CalledProcessError as err: 43 print 'Unable to verify signature' 44 print '\n\n******' 45 print 'If this fails for you, you probably need to import Paul Eggert''s public key:' 46 print ' gpg --receive-keys ED97E90E62AA7E34' 47 print '******\n\n' 48 raise 49 50 # Run with no arguments from any directory, with no special setup required. 51 # See http://www.iana.org/time-zones/ for more about the source of this data. 52 def main(): 53 print 'Looking for new IANA tzdata...' 54 55 iana_tar_filenames = [] 56 57 ftp = ftplib.FTP('ftp.iana.org') 58 ftp.login() 59 ftp.cwd('tz/releases') 60 for filename in ftp.nlst(): 61 if "/" in filename: 62 print "FTP server returned bogus file name" 63 sys.exit(1) 64 65 if filename.startswith('tzdata20') and filename.endswith('.tar.gz'): 66 iana_tar_filenames.append(filename) 67 iana_tar_filenames.sort(reverse=True) 68 69 if len(iana_tar_filenames) == 0: 70 print 'No tzdata files found' 71 sys.exit(1) 72 73 latest_iana_tar_filename = iana_tar_filenames[0] 74 75 local_iana_tar_file = tzdatautil.GetIanaTarFile(iana_data_dir, 'data') 76 77 if local_iana_tar_file: 78 local_iana_tar_filename = os.path.basename(local_iana_tar_file) 79 if latest_iana_tar_filename <= local_iana_tar_filename: 80 print 'Available data %s is older or the same as current data %s' % (latest_iana_tar_filename, local_iana_tar_filename) 81 sys.exit(0) 82 83 print 'Found new tzdata: %s' % latest_iana_tar_filename 84 i18nutil.SwitchToNewTemporaryDirectory() 85 86 print 'Downloading data (%s)...' % latest_iana_tar_filename 87 FtpRetrieveFile(ftp, latest_iana_tar_filename) 88 89 signature_filename = '%s.asc' % latest_iana_tar_filename 90 print 'Downloading signature (%s)...' % signature_filename 91 FtpRetrieveFile(ftp, signature_filename) 92 93 CheckSignature(latest_iana_tar_filename, signature_filename) 94 95 new_local_iana_tar_file = '%s/%s' % (iana_data_dir, latest_iana_tar_filename) 96 shutil.copyfile(latest_iana_tar_filename, new_local_iana_tar_file) 97 new_local_signature_file = '%s/%s' % (iana_data_dir, signature_filename) 98 shutil.copyfile(signature_filename, new_local_signature_file) 99 100 # Delete the existing local IANA tar file, if there is one. 101 if local_iana_tar_file: 102 os.remove(local_iana_tar_file) 103 104 local_signature_file = '%s.asc' % local_iana_tar_file 105 if os.path.exists(local_signature_file): 106 os.remove(local_signature_file) 107 108 print 'Look in %s for new IANA data files' % new_local_iana_tar_file 109 sys.exit(0) 110 111 112 if __name__ == '__main__': 113 main() 114