packages feed

download-media-content-0.0.0.1: src/Network/DownloadMediaContent.hs

-- | Provides functions to download media content from an RSS feed
{-# LANGUAGE OverloadedStrings #-}
module Network.DownloadMediaContent
    ( readFileOrUrl
    , mediaContentUrls
    , downloadFile
    , generateNames
    ) where

import Data.List (nub)
import Data.Maybe (catMaybes)
import Network.HTTP.Enumerator (parseUrl, simpleHttp)
import System.FilePath (takeExtension, (<.>))
import Text.HTML.TagSoup (Tag (..), parseTags)
import Text.Printf (printf)
import qualified Data.ByteString.Lazy as BL
import qualified Data.Text.Lazy as TL
import qualified Data.Text.Lazy.Encoding as TL

-- | Download a file or simply open it
readFileOrUrl :: String            -- ^ Filename or URL
              -> IO BL.ByteString  -- ^ Resulting content
readFileOrUrl name = case parseUrl name of
    Nothing -> BL.readFile name
    _       -> simpleHttp name

-- | Take an XML document and extract the URL's of @media:content@ tags
mediaContentUrls :: BL.ByteString  -- ^ Document
                 -> [String]       -- ^ Media URL's
mediaContentUrls = nub . map str . catMaybes . map mediaContentUrl . parseTags
  where
    str = TL.unpack . TL.decodeUtf8
    mediaContentUrl (TagOpen "media:content" attrs) = lookup "url" attrs
    mediaContentUrl (TagOpen "link" attrs)
        | lookup "rel" attrs == Just "enclosure"    = lookup "href" attrs
        | otherwise                                 = Nothing
    mediaContentUrl _                               = Nothing

-- | Download a file
downloadFile :: String    -- ^ URL
             -> FilePath  -- ^ Output filename
             -> IO ()
downloadFile url filePath = simpleHttp url >>= BL.writeFile filePath

-- | Generate a number of names based on a list existing URL's
generateNames :: [String]            -- ^ URL's
              -> [(String, String)]  -- ^ URL's and generated names
generateNames urls =
    map (\(url, n) -> (url, generateName url n)) $ zip urls [1 ..]
  where
    generateName :: String -> Int -> String
    generateName url n =
        let name = printf ("%0" ++ show width ++ "d") n
            ext = takeExtension $ takeWhile (`notElem` "#?") url
        in name <.> ext
    width = length $ show $ length urls