{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE TypeSynonymInstances #-}
{-# LANGUAGE CPP #-}
module Text.Feed.Import
( parseFeedFromFile
, parseFeedString
, parseFeedSource
, FeedSource
, readRSS2
, readRSS1
, readAtom
) where
import Prelude.Compat
import Control.Exception
import Data.ByteString.Lazy (ByteString)
import Data.Text.Lazy (Text, pack)
import Data.XML.Types as XML
import Text.Atom.Feed.Import as Atom
import Text.Feed.Types
import Text.RSS.Import as RSS
import Text.RSS1.Import as RSS1
import Control.Monad.Compat
import qualified Text.XML as C
#if MIN_VERSION_utf8_string(1,0,0)
import Codec.Binary.UTF8.String (decodeString)
import System.IO (IOMode(..), hGetContents, openBinaryFile)
utf8readFile :: FilePath -> IO String
utf8readFile :: String -> IO String
utf8readFile String
fp = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap String -> String
decodeString (Handle -> IO String
hGetContents forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< String -> IOMode -> IO Handle
openBinaryFile String
fp IOMode
ReadMode)
#else
import System.IO.UTF8 as UTF8 (readFile)
utf8readFile :: FilePath -> IO String
utf8readFile = UTF8.readFile
#endif
class FeedSource s where
parseFeedSourceXML :: s -> Either SomeException C.Document
instance FeedSource ByteString where
parseFeedSourceXML :: ByteString -> Either SomeException Document
parseFeedSourceXML = ParseSettings -> ByteString -> Either SomeException Document
C.parseLBS forall a. Default a => a
C.def
instance FeedSource Text where
parseFeedSourceXML :: Text -> Either SomeException Document
parseFeedSourceXML = ParseSettings -> Text -> Either SomeException Document
C.parseText forall a. Default a => a
C.def
instance FeedSource String where
parseFeedSourceXML :: String -> Either SomeException Document
parseFeedSourceXML = forall s. FeedSource s => s -> Either SomeException Document
parseFeedSourceXML forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
pack
parseFeedFromFile :: FilePath -> IO (Maybe Feed)
parseFeedFromFile :: String -> IO (Maybe Feed)
parseFeedFromFile String
fp = String -> Maybe Feed
parseFeedString forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> IO String
utf8readFile String
fp
parseFeedWithParser :: FeedSource s => (s -> Either e C.Document) -> s -> Maybe Feed
parseFeedWithParser :: forall s e.
FeedSource s =>
(s -> Either e Document) -> s -> Maybe Feed
parseFeedWithParser s -> Either e Document
parser s
str =
case s -> Either e Document
parser s
str of
Left e
_ -> forall a. Maybe a
Nothing
Right Document
d -> Element -> Maybe Feed
readAtom Element
e forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
`mplus` Element -> Maybe Feed
readRSS2 Element
e forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
`mplus` Element -> Maybe Feed
readRSS1 Element
e forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
`mplus` forall a. a -> Maybe a
Just (Element -> Feed
XMLFeed Element
e)
where e :: Element
e = Element -> Element
C.toXMLElement forall a b. (a -> b) -> a -> b
$ Document -> Element
C.documentRoot Document
d
parseFeedString :: String -> Maybe Feed
parseFeedString :: String -> Maybe Feed
parseFeedString = forall s. FeedSource s => s -> Maybe Feed
parseFeedSource
parseFeedSource :: FeedSource s => s -> Maybe Feed
parseFeedSource :: forall s. FeedSource s => s -> Maybe Feed
parseFeedSource = forall s e.
FeedSource s =>
(s -> Either e Document) -> s -> Maybe Feed
parseFeedWithParser forall s. FeedSource s => s -> Either SomeException Document
parseFeedSourceXML
readRSS2 :: XML.Element -> Maybe Feed
Element
e = RSS -> Feed
RSSFeed forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Element -> Maybe RSS
RSS.elementToRSS Element
e
readRSS1 :: XML.Element -> Maybe Feed
Element
e = Feed -> Feed
RSS1Feed forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Element -> Maybe Feed
RSS1.elementToFeed Element
e
readAtom :: XML.Element -> Maybe Feed
readAtom :: Element -> Maybe Feed
readAtom Element
e = Feed -> Feed
AtomFeed forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Element -> Maybe Feed
Atom.elementFeed Element
e