{-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE OverloadedStrings #-} -- | Simple interpreter to parse XML into 'Feed', based on 'Conduit'. module Imm.XML.Simple where -- {{{ Imports import Imm.Feed import Imm.Prelude import Imm.XML import Control.Monad import Control.Monad.Fix import Data.Conduit import Data.XML.Types import Text.Atom.Conduit.Parse import Text.RSS.Conduit.Parse import Text.RSS1.Conduit.Parse import Text.XML.Stream.Parse import URI.ByteString -- }}} -- | A 'Conduit' to alter the raw XML before feeding it to the parser, depending on the feed 'URI' type PreProcess m = URI -> Conduit Event m Event -- | Interpreter for 'XmlParserF' mkCoXmlParser :: (MonadIO m, MonadCatch m) => PreProcess m -> CoXmlParserF m (PreProcess m) mkCoXmlParser preProcess = CoXmlParserF coParse where coParse uri bytestring = handleAny (\e -> return (Left e, preProcess)) $ do result <- runConduit $ parseLBS def bytestring =$= preProcess uri =$= force "Invalid feed" ((fmap Atom <$> atomFeed) `orE` (fmap Rss <$> rssDocument) `orE` (fmap Rss <$> rss1Document)) return (Right result, preProcess) -- | Default pre-process always forwards all 'Event's defaultPreProcess :: Monad m => PreProcess m defaultPreProcess _ = fix $ \loop -> await >>= maybe (return ()) (yield >=> const loop)