Home | History | Annotate | Download | only in timezone
      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