+
+
+-- | Save the image at 'url'. Saves to a temporary file, and
+-- returns the path to that file if successful. Otherwise,
+-- returns 'Nothing'.
+--
+-- We need to be able to parse the filename out of the URL
+-- so that when we stick our image in the document, the reader
+-- knows that type (jpg, png, etc.) it is.
+save_image :: URL -> IO (Maybe FilePath)
+save_image url = do
+ it_exists <- doesFileExist url
+ if it_exists then do
+ -- It's local, just use it.
+ return $ Just url
+ else do
+ let fn = filename url
+ case fn of
+ Nothing -> return Nothing
+ Just file -> do
+ temp_dir <- getTemporaryDirectory
+ (out_path, out_handle) <- openBinaryTempFile temp_dir file
+ result <- openURI url
+ case result of
+ Left err -> do
+ hPutStrLn stderr ("HTTP Error: " ++ err)
+ return Nothing
+ Right bs -> do
+ B.hPut out_handle bs
+ return $ Just out_path
+
+
+
+
+-- | Map absolute image URLs to local system file paths where the
+-- image referenced by the URL is stored.
+type ImageMap = Map.Map URL FilePath
+
+download_image_urls :: [URL] -> IO ImageMap
+download_image_urls image_urls = do
+ files <- mapM save_image image_urls
+ let pairs = zip image_urls files
+ return $ foldl my_insert empty_map pairs
+ where
+ empty_map = Map.empty :: ImageMap
+
+ my_insert :: ImageMap -> (URL, Maybe FilePath) -> ImageMap
+ my_insert dict (_, Nothing) = dict
+ my_insert dict (k, Just v) = Map.insert k v dict