feed-translator-0.1.0.2: src/Web/Feed/FeedTranslator.hs
module Web.Feed.FeedTranslator ( TextTranslator
, Translator(..)
, UrlTranslator
, translateFeed
) where
import Control.Monad (liftM)
import Data.Text (Text, pack, unpack)
import Network.URI (URI, parseAbsoluteURI)
import Text.Feed.Constructor (withFeedItems, withFeedTitle, withItemDescription,
withItemId, withItemLink, withItemTitle)
import Text.Feed.Types (Feed, Item)
import Text.Feed.Query (feedItems, getFeedTitle, getItemId, getItemDescription,
getItemLink, getItemSummary, getItemTitle)
-- Text translator engine type.
type TextTranslator = Text -> IO Text
-- Link translator engine type.
type UrlTranslator = URI -> Maybe URI
-- Translator engine type combining 'TextTranslator' and 'UrlTranslator'.
data Translator = Translator { textTranslator :: TextTranslator
, urlTranslator :: UrlTranslator
}
-- | Translate the given feed.
translateFeed :: Translator -> Feed -> IO Feed
translateFeed translator feed = do
let title :: Text
title = pack $ getFeedTitle feed
items :: [Item]
items = feedItems feed
translatedTitle <- textTranslator translator title
translatedItems <- mapM (translateItem translator) items
return $ withFeedItems translatedItems
$ withFeedTitle (unpack translatedTitle) feed
-- | Translate a single item.
translateItem :: Translator -> Item -> IO Item
translateItem (Translator translate translateUrl) item = do
let itemId :: Maybe (Bool, String)
itemId = getItemId item
desc :: Maybe String
desc = case getItemDescription item of
Nothing -> getItemSummary item
Just "" -> getItemSummary item
Just s -> Just s
link :: Maybe String
link = getItemLink item
title :: Maybe String
title = getItemTitle item
tId :: Maybe String
tId = case itemId of
Just (True, id') -> Just $ translateLink id'
Just (False, id') -> Just id'
Nothing -> Nothing
uri :: Bool
uri = case itemId of
Just (True, _) -> True
_ -> False
tLink :: Maybe String
tLink = liftM translateLink link
tTitle <- translate' title
tDesc <- translate' desc
let replace :: Item -> Item
replace = setter tId (withItemId uri) .
setter tLink withItemLink .
setter tTitle withItemTitle .
setter tDesc withItemDescription
return $ replace item
where
translateLink :: String -> String
translateLink urlString =
case parseAbsoluteURI urlString of
Just uri -> case translateUrl uri of
Just translatedUri -> show translatedUri
Nothing -> urlString
Nothing -> urlString
translate' :: Maybe String -> IO (Maybe String)
translate' s =
case s of
Just s -> liftM (Just . unpack) $ translate $ pack s
Nothing -> return Nothing
setter :: Maybe a -> (a -> Item -> Item) -> Item -> Item
setter value set =
case value of
Just value -> set value
Nothing -> id