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"