packages feed

iso3166-country-codes-0.1: Data/ISO3166_CountryCodes/Getter.hs

module Getter(get_country_code_list) where

{- This operates essentially as a single file http cache
-}

import Network.HTTP
import System.Directory
import System.Time
import IO

country_code_URL = "http://www.iso.org/iso/iso3166_en_code_lists.txt"
local_copy = "Data/ISO3166_CountryCodes/iso3166_en_code_lists.txt"

last_modified_file = local_copy ++ ".last-modified"

{-
most errors are handled by failing...

-}

get_country_code_list
  = do local_copy_date <- getSomeModificationTime
       let r = getRequest country_code_URL
       Right response <- simpleHTTP r{rqHeaders=Header HdrIfModifiedSince local_copy_date:getHeaders r}

       case rspCode response of
         (3,0,4) -> do -- not modified since fetched
                       readFile local_copy
         (2,0,0) -> do let content = rspBody response -- doesn't seem lazy enough
                       writeFile local_copy content
                       case [date| Header HdrLastModified date <- rspHeaders response] of
                         [d] -> do writeFile last_modified_file d
                                   return content
         _ -> error $ "unhandled HTTP response: " ++ show response

{-

Using the file modification time might be better in some
ways, but we don't know whether the server holding the
source file implements if-modified-since correctly, so
storing the modification time returned by the server in its
own file is about as good as we can manage.

Besides, at time of writing Haskell's time manipulation is
in a mess.

-}

getSomeModificationTime
  = do already_here <- doesFileExist local_copy
       last_modified_recorded <- doesFileExist last_modified_file
       if already_here && last_modified_recorded -- we have a copy, but is it up to date?
         then readFile last_modified_file
         else return epoch -- this should be long enough ago to ensure a fetch

{- I originally used
epoch = "Thu, 1 Jan 1970 00:00:00 GMT"
but for some reason the server returns "not modified" if you do that

-}
epoch = "Sat, 27 May 2000 08:12:00 GMT"