    {-# LANGUAGE CPP #-}

    --------------------------------------------------------------------
    -- |
    -- Module    : Text.Feed.Query
    -- Copyright : (c) Galois, Inc. 2008,
    --             (c) Sigbjorn Finne 2009-
    -- License   : BSD3
    --
    -- Maintainer: Sigbjorn Finne <sof@forkIO.com>
    -- Stability : provisional
    -- Portability: portable
    --
    --------------------------------------------------------------------
    module Text.Feed.Query
      ( Text.Feed.Query.feedItems -- :: Feed.Feed -> [Feed.Item]
      , FeedGetter -- type _ a = Feed -> a
      , getFeedTitle -- :: FeedGetter Text
      , getFeedAuthor -- :: FeedGetter Text
      , getFeedHome -- :: FeedGetter URLString
      , getFeedHTML -- :: FeedGetter URLString
      , getFeedDescription -- :: FeedGetter Text
      , getFeedPubDate -- :: FeedGetter DateString
      , getFeedLastUpdate -- :: FeedGetter Text
      , getFeedDate -- :: FeedGetter DateString
      , getFeedLogoLink -- :: FeedGetter URLString
      , getFeedLanguage -- :: FeedGetter Text
      , getFeedCategories -- :: FeedGetter [(Text, Maybe Text)]
      , getFeedGenerator -- :: FeedGetter Text
      , getFeedItems -- :: FeedGetter [Item]
      , ItemGetter -- type _ a = Item -> Maybe a
      , getItemTitle -- :: ItemGetter Text
      , getItemLink -- :: ItemGetter Text
      , getItemPublishDate -- :: Data.Time.ParseTime t => ItemGetter (Maybe t)
      , getItemPublishDateString -- :: ItemGetter (DateString)
      , getItemDate -- :: ItemGetter (DateString)
      , getItemAuthor -- :: ItemGetter Text
      , getItemCommentLink -- :: ItemGetter (URLString)
      , getItemEnclosure -- :: ItemGetter (URI, Maybe Text, Integer)
      , getItemFeedLink -- :: ItemGetter (URLString)
      , getItemId -- :: ItemGetter (Bool, Text)
      , getItemCategories -- :: ItemGetter [Text]
      , getItemRights -- :: ItemGetter Text
      , getItemSummary -- :: ItemGetter Text
      , getItemDescription -- :: ItemGetter Text (synonym of previous.)
      ) where

    import Prelude.Compat

    import Text.Feed.Types as Feed

    import Data.XML.Types as XML
    import Text.Atom.Feed as Atom
    import Text.Atom.Feed.Export (atomName)
    import Text.RSS.Syntax as RSS
    import Text.RSS1.Syntax as RSS1

    import Data.XML.Compat

    import Text.DublinCore.Types

    import Control.Applicative ((<|>))
    import Control.Arrow ((&&&))
    import Control.Monad.Compat (mplus)
    import Data.Maybe
    import Data.Text (Text)
    import qualified Data.Text as T
    import Data.Text.Read

    import Data.Time.Format (ParseTime)
    import qualified Data.Time.Format as F

    -- for getItemPublishDate rfc822 date parsing.
    import Data.Time.Locale.Compat (defaultTimeLocale, iso8601DateFormat, rfc822DateFormat)

    feedItems :: Feed.Feed -> [Feed.Item]
    feedItems :: Feed -> [Item]
    feedItems fe :: Feed
    fe =
      case Feed
    fe of
        AtomFeed f :: Feed
    f -> (Entry -> Item) -> [Entry] -> [Item]
    forall a b. (a -> b) -> [a] -> [b]
    map Entry -> Item
    Feed.AtomItem (Feed -> [Entry]
    Atom.feedEntries Feed
    f)
        RSSFeed f :: RSS
    f -> (RSSItem -> Item) -> [RSSItem] -> [Item]
    forall a b. (a -> b) -> [a] -> [b]
    map RSSItem -> Item
    Feed.RSSItem (RSSChannel -> [RSSItem]
    RSS.rssItems (RSSChannel -> [RSSItem]) -> RSSChannel -> [RSSItem]
    forall a b. (a -> b) -> a -> b
    $ RSS -> RSSChannel
    RSS.rssChannel RSS
    f)
        RSS1Feed f :: Feed
    f -> (Item -> Item) -> [Item] -> [Item]
    forall a b. (a -> b) -> [a] -> [b]
    map Item -> Item
    Feed.RSS1Item (Feed -> [Item]
    RSS1.feedItems Feed
    f)
        XMLFeed f :: Element
    f ->
          case Name -> Element -> [Element]
    findElements "item" Element
    f of
            [] -> (Element -> Item) -> [Element] -> [Item]
    forall a b. (a -> b) -> [a] -> [b]
    map Element -> Item
    Feed.XMLItem ([Element] -> [Item]) -> [Element] -> [Item]
    forall a b. (a -> b) -> a -> b
    $ Name -> Element -> [Element]
    findElements (Text -> Name
    atomName "entry") Element
    f
            l :: [Element]
    l -> (Element -> Item) -> [Element] -> [Item]
    forall a b. (a -> b) -> [a] -> [b]
    map Element -> Item
    Feed.XMLItem [Element]
    l

    getFeedItems :: Feed.Feed -> [Feed.Item]
    getFeedItems :: Feed -> [Item]
    getFeedItems = Feed -> [Item]
    Text.Feed.Query.feedItems

    type FeedGetter a = Feed.Feed -> Maybe a

    getFeedAuthor :: FeedGetter Text
    getFeedAuthor :: FeedGetter Text
    getFeedAuthor ft :: Feed
    ft =
      case Feed
    ft of
        Feed.AtomFeed f :: Feed
    f -> (Person -> Text) -> Maybe Person -> Maybe Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap Person -> Text
    Atom.personName (Maybe Person -> Maybe Text) -> Maybe Person -> Maybe Text
    forall a b. (a -> b) -> a -> b
    $ [Person] -> Maybe Person
    forall a. [a] -> Maybe a
    listToMaybe ([Person] -> Maybe Person) -> [Person] -> Maybe Person
    forall a b. (a -> b) -> a -> b
    $ Feed -> [Person]
    Atom.feedAuthors Feed
    f
        Feed.RSSFeed f :: RSS
    f -> RSSChannel -> Maybe Text
    RSS.rssEditor (RSS -> RSSChannel
    RSS.rssChannel RSS
    f)
        Feed.RSS1Feed f :: Feed
    f ->
          (DCItem -> Text) -> Maybe DCItem -> Maybe Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap DCItem -> Text
    dcText (Maybe DCItem -> Maybe Text) -> Maybe DCItem -> Maybe Text
    forall a b. (a -> b) -> a -> b
    $ [DCItem] -> Maybe DCItem
    forall a. [a] -> Maybe a
    listToMaybe ([DCItem] -> Maybe DCItem) -> [DCItem] -> Maybe DCItem
    forall a b. (a -> b) -> a -> b
    $ (DCItem -> Bool) -> [DCItem] -> [DCItem]
    forall a. (a -> Bool) -> [a] -> [a]
    filter DCItem -> Bool
    isAuthor ([DCItem] -> [DCItem]) -> [DCItem] -> [DCItem]
    forall a b. (a -> b) -> a -> b
    $ Channel -> [DCItem]
    RSS1.channelDC (Feed -> Channel
    RSS1.feedChannel Feed
    f)
        Feed.XMLFeed f :: Element
    f ->
          case Name -> Element -> Maybe Element
    findElement "channel" Element
    f of
            Just e1 :: Element
    e1 -> Element -> Text
    strContent (Element -> Text) -> Maybe Element -> Maybe Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Name -> Element -> Maybe Element
    findElement "editor" Element
    e1
            Nothing ->
              (Element -> Text) -> Maybe Element -> Maybe Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap Element -> Text
    strContent (Maybe Element -> Maybe Text) -> Maybe Element -> Maybe Text
    forall a b. (a -> b) -> a -> b
    $ Name -> Element -> Maybe Element
    findElement (Text -> Name
    atomName "name") (Element -> Maybe Element) -> Maybe Element -> Maybe Element
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
    =<< Name -> Element -> Maybe Element
    findChild (Text -> Name
    atomName "author") Element
    f
      where
        isAuthor :: DCItem -> Bool
    isAuthor dc :: DCItem
    dc = DCItem -> DCInfo
    dcElt DCItem
    dc DCInfo -> DCInfo -> Bool
    forall a. Eq a => a -> a -> Bool
    == DCInfo
    DC_Creator

    getFeedTitle :: Feed.Feed -> Text
    getFeedTitle :: Feed -> Text
    getFeedTitle ft :: Feed
    ft =
      case Feed
    ft of
        Feed.AtomFeed f :: Feed
    f -> TextContent -> Text
    contentToStr (TextContent -> Text) -> TextContent -> Text
    forall a b. (a -> b) -> a -> b
    $ Feed -> TextContent
    Atom.feedTitle Feed
    f
        Feed.RSSFeed f :: RSS
    f -> RSSChannel -> Text
    RSS.rssTitle (RSS -> RSSChannel
    RSS.rssChannel RSS
    f)
        Feed.RSS1Feed f :: Feed
    f -> Channel -> Text
    RSS1.channelTitle (Feed -> Channel
    RSS1.feedChannel Feed
    f)
        Feed.XMLFeed f :: Element
    f ->
          case Name -> Element -> Maybe Element
    findElement "channel" Element
    f of
            Just e1 :: Element
    e1 -> Text -> (Element -> Text) -> Maybe Element -> Text
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe "" Element -> Text
    strContent (Name -> Element -> Maybe Element
    findElement "title" Element
    e1)
            Nothing -> Text -> (Element -> Text) -> Maybe Element -> Text
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe "" Element -> Text
    strContent (Name -> Element -> Maybe Element
    findChild (Text -> Name
    atomName "title") Element
    f)

    getFeedHome :: FeedGetter URLString
    getFeedHome :: FeedGetter Text
    getFeedHome ft :: Feed
    ft =
      case Feed
    ft of
        Feed.AtomFeed f :: Feed
    f -> (Link -> Text) -> Maybe Link -> Maybe Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap Link -> Text
    Atom.linkHref (Maybe Link -> Maybe Text) -> Maybe Link -> Maybe Text
    forall a b. (a -> b) -> a -> b
    $ [Link] -> Maybe Link
    forall a. [a] -> Maybe a
    listToMaybe ([Link] -> Maybe Link) -> [Link] -> Maybe Link
    forall a b. (a -> b) -> a -> b
    $ (Link -> Bool) -> [Link] -> [Link]
    forall a. (a -> Bool) -> [a] -> [a]
    filter Link -> Bool
    isSelf (Feed -> [Link]
    Atom.feedLinks Feed
    f)
        Feed.RSSFeed f :: RSS
    f -> Text -> Maybe Text
    forall a. a -> Maybe a
    Just (RSSChannel -> Text
    RSS.rssLink (RSS -> RSSChannel
    RSS.rssChannel RSS
    f))
        Feed.RSS1Feed f :: Feed
    f -> Text -> Maybe Text
    forall a. a -> Maybe a
    Just (Channel -> Text
    RSS1.channelURI (Feed -> Channel
    RSS1.feedChannel Feed
    f))
        Feed.XMLFeed f :: Element
    f ->
          case Name -> Element -> Maybe Element
    findElement "channel" Element
    f of
            Just e1 :: Element
    e1 -> Element -> Text
    strContent (Element -> Text) -> Maybe Element -> Maybe Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Name -> Element -> Maybe Element
    findElement "link" Element
    e1
            Nothing -> Name -> Element -> Maybe Text
    attributeText "href" (Element -> Maybe Text) -> Maybe Element -> Maybe Text
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
    =<< Name -> Element -> Maybe Element
    findChild (Text -> Name
    atomName "link") Element
    f
      where
        isSelf :: Link -> Bool
    isSelf lr :: Link
    lr = Maybe (Either Text Text) -> Text
    toStr (Link -> Maybe (Either Text Text)
    Atom.linkRel Link
    lr) Text -> Text -> Bool
    forall a. Eq a => a -> a -> Bool
    == "self"

    getFeedHTML :: FeedGetter URLString
    getFeedHTML :: FeedGetter Text
    getFeedHTML ft :: Feed
    ft =
      case Feed
    ft of
        Feed.AtomFeed f :: Feed
    f -> (Link -> Text) -> Maybe Link -> Maybe Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap Link -> Text
    Atom.linkHref (Maybe Link -> Maybe Text) -> Maybe Link -> Maybe Text
    forall a b. (a -> b) -> a -> b
    $ [Link] -> Maybe Link
    forall a. [a] -> Maybe a
    listToMaybe ([Link] -> Maybe Link) -> [Link] -> Maybe Link
    forall a b. (a -> b) -> a -> b
    $ (Link -> Bool) -> [Link] -> [Link]
    forall a. (a -> Bool) -> [a] -> [a]
    filter Link -> Bool
    isSelf (Feed -> [Link]
    Atom.feedLinks Feed
    f)
        Feed.RSSFeed f :: RSS
    f -> Text -> Maybe Text
    forall a. a -> Maybe a
    Just (RSSChannel -> Text
    RSS.rssLink (RSS -> RSSChannel
    RSS.rssChannel RSS
    f))
        Feed.RSS1Feed f :: Feed
    f -> Text -> Maybe Text
    forall a. a -> Maybe a
    Just (Channel -> Text
    RSS1.channelURI (Feed -> Channel
    RSS1.feedChannel Feed
    f))
        Feed.XMLFeed f :: Element
    f ->
          case Name -> Element -> Maybe Element
    findElement "channel" Element
    f of
            Just e1 :: Element
    e1 -> Element -> Text
    strContent (Element -> Text) -> Maybe Element -> Maybe Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Name -> Element -> Maybe Element
    findElement "link" Element
    e1
            Nothing -> Maybe Text
    forall a. Maybe a
    Nothing -- ToDo parse atom like tags
      where
        isSelf :: Link -> Bool
    isSelf lr :: Link
    lr =
          let rel :: Maybe (Either Text Text)
    rel = Link -> Maybe (Either Text Text)
    Atom.linkRel Link
    lr
           in (Maybe (Either Text Text) -> Bool
    forall a. Maybe a -> Bool
    isNothing Maybe (Either Text Text)
    rel Bool -> Bool -> Bool
    || Maybe (Either Text Text) -> Text
    toStr Maybe (Either Text Text)
    rel Text -> Text -> Bool
    forall a. Eq a => a -> a -> Bool
    == "alternate") Bool -> Bool -> Bool
    && Maybe Text -> Bool
    isHTMLType (Link -> Maybe Text
    linkType Link
    lr)
        isHTMLType :: Maybe Text -> Bool
    isHTMLType (Just str :: Text
    str) = "html" Text -> Text -> Bool
    `T.isSuffixOf` Text
    str
        isHTMLType _ = Bool
    True -- if none given, assume html.

    getFeedDescription :: FeedGetter Text
    getFeedDescription :: FeedGetter Text
    getFeedDescription ft :: Feed
    ft =
      case Feed
    ft of
        Feed.AtomFeed f :: Feed
    f -> (TextContent -> Text) -> Maybe TextContent -> Maybe Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap TextContent -> Text
    contentToStr (Feed -> Maybe TextContent
    Atom.feedSubtitle Feed
    f)
        Feed.RSSFeed f :: RSS
    f -> Text -> Maybe Text
    forall a. a -> Maybe a
    Just (Text -> Maybe Text) -> Text -> Maybe Text
    forall a b. (a -> b) -> a -> b
    $ RSSChannel -> Text
    RSS.rssDescription (RSS -> RSSChannel
    RSS.rssChannel RSS
    f)
        Feed.RSS1Feed f :: Feed
    f -> Text -> Maybe Text
    forall a. a -> Maybe a
    Just (Channel -> Text
    RSS1.channelDesc (Feed -> Channel
    RSS1.feedChannel Feed
    f))
        Feed.XMLFeed f :: Element
    f ->
          case Name -> Element -> Maybe Element
    findElement "channel" Element
    f of
            Just e1 :: Element
    e1 -> Element -> Text
    strContent (Element -> Text) -> Maybe Element -> Maybe Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Name -> Element -> Maybe Element
    findElement "description" Element
    e1
            Nothing -> Element -> Text
    strContent (Element -> Text) -> Maybe Element -> Maybe Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Name -> Element -> Maybe Element
    findChild (Text -> Name
    atomName "subtitle") Element
    f

    getFeedPubDate :: FeedGetter DateString
    getFeedPubDate :: FeedGetter Text
    getFeedPubDate ft :: Feed
    ft =
      case Feed
    ft of
        Feed.AtomFeed f :: Feed
    f -> Text -> Maybe Text
    forall a. a -> Maybe a
    Just (Text -> Maybe Text) -> Text -> Maybe Text
    forall a b. (a -> b) -> a -> b
    $ Feed -> Text
    Atom.feedUpdated Feed
    f
        Feed.RSSFeed f :: RSS
    f -> RSSChannel -> Maybe Text
    RSS.rssPubDate (RSS -> RSSChannel
    RSS.rssChannel RSS
    f)
        Feed.RSS1Feed f :: Feed
    f ->
          (DCItem -> Text) -> Maybe DCItem -> Maybe Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap DCItem -> Text
    dcText (Maybe DCItem -> Maybe Text) -> Maybe DCItem -> Maybe Text
    forall a b. (a -> b) -> a -> b
    $ [DCItem] -> Maybe DCItem
    forall a. [a] -> Maybe a
    listToMaybe ([DCItem] -> Maybe DCItem) -> [DCItem] -> Maybe DCItem
    forall a b. (a -> b) -> a -> b
    $ (DCItem -> Bool) -> [DCItem] -> [DCItem]
    forall a. (a -> Bool) -> [a] -> [a]
    filter DCItem -> Bool
    isDate (Channel -> [DCItem]
    RSS1.channelDC (Channel -> [DCItem]) -> Channel -> [DCItem]
    forall a b. (a -> b) -> a -> b
    $ Feed -> Channel
    RSS1.feedChannel Feed
    f)
        Feed.XMLFeed f :: Element
    f ->
          case Name -> Element -> Maybe Element
    findElement "channel" Element
    f of
            Just e1 :: Element
    e1 -> Element -> Text
    strContent (Element -> Text) -> Maybe Element -> Maybe Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Name -> Element -> Maybe Element
    findElement "pubDate" Element
    e1
            Nothing -> Element -> Text
    strContent (Element -> Text) -> Maybe Element -> Maybe Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Name -> Element -> Maybe Element
    findChild (Text -> Name
    atomName "published") Element
    f
      where
        isDate :: DCItem -> Bool
    isDate dc :: DCItem
    dc = DCItem -> DCInfo
    dcElt DCItem
    dc DCInfo -> DCInfo -> Bool
    forall a. Eq a => a -> a -> Bool
    == DCInfo
    DC_Date

    getFeedLastUpdate :: FeedGetter Text
    getFeedLastUpdate :: FeedGetter Text
    getFeedLastUpdate ft :: Feed
    ft =
      case Feed
    ft of
        Feed.AtomFeed f :: Feed
    f -> Text -> Maybe Text
    forall a. a -> Maybe a
    Just (Text -> Maybe Text) -> Text -> Maybe Text
    forall a b. (a -> b) -> a -> b
    $ Feed -> Text
    Atom.feedUpdated Feed
    f
        Feed.RSSFeed f :: RSS
    f -> RSSChannel -> Maybe Text
    RSS.rssPubDate (RSS -> RSSChannel
    RSS.rssChannel RSS
    f)
        Feed.RSS1Feed f :: Feed
    f ->
          (DCItem -> Text) -> Maybe DCItem -> Maybe Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap DCItem -> Text
    dcText (Maybe DCItem -> Maybe Text) -> Maybe DCItem -> Maybe Text
    forall a b. (a -> b) -> a -> b
    $ [DCItem] -> Maybe DCItem
    forall a. [a] -> Maybe a
    listToMaybe ([DCItem] -> Maybe DCItem) -> [DCItem] -> Maybe DCItem
    forall a b. (a -> b) -> a -> b
    $ (DCItem -> Bool) -> [DCItem] -> [DCItem]
    forall a. (a -> Bool) -> [a] -> [a]
    filter DCItem -> Bool
    isDate (Channel -> [DCItem]
    RSS1.channelDC (Channel -> [DCItem]) -> Channel -> [DCItem]
    forall a b. (a -> b) -> a -> b
    $ Feed -> Channel
    RSS1.feedChannel Feed
    f)
        Feed.XMLFeed f :: Element
    f ->
          case Name -> Element -> Maybe Element
    findElement "channel" Element
    f of
            Just e1 :: Element
    e1 -> Element -> Text
    strContent (Element -> Text) -> Maybe Element -> Maybe Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Name -> Element -> Maybe Element
    findElement "pubDate" Element
    e1
            Nothing -> Element -> Text
    strContent (Element -> Text) -> Maybe Element -> Maybe Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Name -> Element -> Maybe Element
    findChild (Text -> Name
    atomName "updated") Element
    f
      where
        isDate :: DCItem -> Bool
    isDate dc :: DCItem
    dc = DCItem -> DCInfo
    dcElt DCItem
    dc DCInfo -> DCInfo -> Bool
    forall a. Eq a => a -> a -> Bool
    == DCInfo
    DC_Date

    getFeedDate :: FeedGetter DateString
    getFeedDate :: FeedGetter Text
    getFeedDate = FeedGetter Text
    getFeedPubDate

    getFeedLogoLink :: FeedGetter URLString
    getFeedLogoLink :: FeedGetter Text
    getFeedLogoLink ft :: Feed
    ft =
      case Feed
    ft of
        Feed.AtomFeed f :: Feed
    f -> Feed -> Maybe Text
    Atom.feedLogo Feed
    f
        Feed.RSSFeed f :: RSS
    f -> (RSSImage -> Text) -> Maybe RSSImage -> Maybe Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap RSSImage -> Text
    RSS.rssImageURL (RSSChannel -> Maybe RSSImage
    RSS.rssImage (RSSChannel -> Maybe RSSImage) -> RSSChannel -> Maybe RSSImage
    forall a b. (a -> b) -> a -> b
    $ RSS -> RSSChannel
    RSS.rssChannel RSS
    f)
        Feed.RSS1Feed f :: Feed
    f -> Image -> Text
    RSS1.imageURI (Image -> Text) -> Maybe Image -> Maybe Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Feed -> Maybe Image
    RSS1.feedImage Feed
    f
        Feed.XMLFeed f :: Element
    f ->
          case Name -> Element -> Maybe Element
    findElement "channel" Element
    f of
            Just ch :: Element
    ch -> do
              Element
    e1 <- Name -> Element -> Maybe Element
    findElement "image" Element
    ch
              Element
    v <- Name -> Element -> Maybe Element
    findElement "url" Element
    e1
              Text -> Maybe Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Element -> Text
    strContent Element
    v)
            Nothing -> Element -> Text
    strContent (Element -> Text) -> Maybe Element -> Maybe Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Name -> Element -> Maybe Element
    findChild (Text -> Name
    atomName "logo") Element
    f

    getFeedLanguage :: FeedGetter Text
    getFeedLanguage :: FeedGetter Text
    getFeedLanguage ft :: Feed
    ft =
      case Feed
    ft of
        Feed.AtomFeed f :: Feed
    f -> Name -> Element -> Maybe Text
    attributeText "lang" (Element -> Maybe Text) -> Element -> Maybe Text
    forall a b. (a -> b) -> a -> b
    $ Name -> [Attr] -> Element
    forall t. ToNode t => Name -> t -> Element
    unode "" (Feed -> [Attr]
    Atom.feedAttrs Feed
    f)
        Feed.RSSFeed f :: RSS
    f -> RSSChannel -> Maybe Text
    RSS.rssLanguage (RSS -> RSSChannel
    RSS.rssChannel RSS
    f)
        Feed.RSS1Feed f :: Feed
    f ->
          (DCItem -> Text) -> Maybe DCItem -> Maybe Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap DCItem -> Text
    dcText (Maybe DCItem -> Maybe Text) -> Maybe DCItem -> Maybe Text
    forall a b. (a -> b) -> a -> b
    $ [DCItem] -> Maybe DCItem
    forall a. [a] -> Maybe a
    listToMaybe ([DCItem] -> Maybe DCItem) -> [DCItem] -> Maybe DCItem
    forall a b. (a -> b) -> a -> b
    $ (DCItem -> Bool) -> [DCItem] -> [DCItem]
    forall a. (a -> Bool) -> [a] -> [a]
    filter DCItem -> Bool
    isLang (Channel -> [DCItem]
    RSS1.channelDC (Channel -> [DCItem]) -> Channel -> [DCItem]
    forall a b. (a -> b) -> a -> b
    $ Feed -> Channel
    RSS1.feedChannel Feed
    f)
        Feed.XMLFeed f :: Element
    f -> do
          Element
    ch <- Name -> Element -> Maybe Element
    findElement "channel" Element
    f
          Element
    e1 <- Name -> Element -> Maybe Element
    findElement "language" Element
    ch
          Text -> Maybe Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Element -> Text
    strContent Element
    e1)
           -- ToDo parse atom like tags too
      where
        isLang :: DCItem -> Bool
    isLang dc :: DCItem
    dc = DCItem -> DCInfo
    dcElt DCItem
    dc DCInfo -> DCInfo -> Bool
    forall a. Eq a => a -> a -> Bool
    == DCInfo
    DC_Language

    getFeedCategories :: Feed.Feed -> [(Text, Maybe Text)]
    getFeedCategories :: Feed -> [(Text, Maybe Text)]
    getFeedCategories ft :: Feed
    ft =
      case Feed
    ft of
        Feed.AtomFeed f :: Feed
    f -> (Category -> (Text, Maybe Text))
    -> [Category] -> [(Text, Maybe Text)]
    forall a b. (a -> b) -> [a] -> [b]
    map (Category -> Text
    Atom.catTerm (Category -> Text)
    -> (Category -> Maybe Text) -> Category -> (Text, Maybe Text)
    forall (a :: * -> * -> *) b c c'.
    Arrow a =>
    a b c -> a b c' -> a b (c, c')
    &&& Category -> Maybe Text
    Atom.catScheme) (Feed -> [Category]
    Atom.feedCategories Feed
    f)
        Feed.RSSFeed f :: RSS
    f ->
          (RSSCategory -> (Text, Maybe Text))
    -> [RSSCategory] -> [(Text, Maybe Text)]
    forall a b. (a -> b) -> [a] -> [b]
    map (RSSCategory -> Text
    RSS.rssCategoryValue (RSSCategory -> Text)
    -> (RSSCategory -> Maybe Text) -> RSSCategory -> (Text, Maybe Text)
    forall (a :: * -> * -> *) b c c'.
    Arrow a =>
    a b c -> a b c' -> a b (c, c')
    &&& RSSCategory -> Maybe Text
    RSS.rssCategoryDomain) (RSSChannel -> [RSSCategory]
    RSS.rssCategories (RSS -> RSSChannel
    RSS.rssChannel RSS
    f))
        Feed.RSS1Feed f :: Feed
    f ->
          case (DCItem -> Bool) -> [DCItem] -> [DCItem]
    forall a. (a -> Bool) -> [a] -> [a]
    filter DCItem -> Bool
    isCat (Channel -> [DCItem]
    RSS1.channelDC (Channel -> [DCItem]) -> Channel -> [DCItem]
    forall a b. (a -> b) -> a -> b
    $ Feed -> Channel
    RSS1.feedChannel Feed
    f) of
            ls :: [DCItem]
    ls -> (DCItem -> (Text, Maybe Text)) -> [DCItem] -> [(Text, Maybe Text)]
    forall a b. (a -> b) -> [a] -> [b]
    map (\l :: DCItem
    l -> (DCItem -> Text
    dcText DCItem
    l, Maybe Text
    forall a. Maybe a
    Nothing)) [DCItem]
    ls
        Feed.XMLFeed f :: Element
    f ->
          case [Element] -> (Element -> [Element]) -> Maybe Element -> [Element]
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe [] (Name -> Element -> [Element]
    findElements "category") (Name -> Element -> Maybe Element
    findElement "channel" Element
    f) of
            ls :: [Element]
    ls -> (Element -> (Text, Maybe Text))
    -> [Element] -> [(Text, Maybe Text)]
    forall a b. (a -> b) -> [a] -> [b]
    map (\l :: Element
    l -> (Text -> (Element -> Text) -> Maybe Element -> Text
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe "" Element -> Text
    strContent (Name -> Element -> Maybe Element
    findElement "term" Element
    l), Name -> Element -> Maybe Text
    attributeText "domain" Element
    l)) [Element]
    ls
           -- ToDo parse atom like tags too
      where
        isCat :: DCItem -> Bool
    isCat dc :: DCItem
    dc = DCItem -> DCInfo
    dcElt DCItem
    dc DCInfo -> DCInfo -> Bool
    forall a. Eq a => a -> a -> Bool
    == DCInfo
    DC_Subject

    getFeedGenerator :: FeedGetter Text
    getFeedGenerator :: FeedGetter Text
    getFeedGenerator ft :: Feed
    ft =
      case Feed
    ft of
        Feed.AtomFeed f :: Feed
    f -> do
          Generator
    gen <- Feed -> Maybe Generator
    Atom.feedGenerator Feed
    f
          Generator -> Maybe Text
    Atom.genURI Generator
    gen
        Feed.RSSFeed f :: RSS
    f -> RSSChannel -> Maybe Text
    RSS.rssGenerator (RSS -> RSSChannel
    RSS.rssChannel RSS
    f)
        Feed.RSS1Feed f :: Feed
    f ->
          (DCItem -> Text) -> Maybe DCItem -> Maybe Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap DCItem -> Text
    dcText (Maybe DCItem -> Maybe Text) -> Maybe DCItem -> Maybe Text
    forall a b. (a -> b) -> a -> b
    $ [DCItem] -> Maybe DCItem
    forall a. [a] -> Maybe a
    listToMaybe ([DCItem] -> Maybe DCItem) -> [DCItem] -> Maybe DCItem
    forall a b. (a -> b) -> a -> b
    $ (DCItem -> Bool) -> [DCItem] -> [DCItem]
    forall a. (a -> Bool) -> [a] -> [a]
    filter DCItem -> Bool
    isSource (Channel -> [DCItem]
    RSS1.channelDC (Feed -> Channel
    RSS1.feedChannel Feed
    f))
        Feed.XMLFeed f :: Element
    f ->
          case Name -> Element -> Maybe Element
    findElement "channel" Element
    f of
            Just e1 :: Element
    e1 -> Element -> Text
    strContent (Element -> Text) -> Maybe Element -> Maybe Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Name -> Element -> Maybe Element
    findElement "generator" Element
    e1
            Nothing -> Name -> Element -> Maybe Text
    attributeText "uri" (Element -> Maybe Text) -> Maybe Element -> Maybe Text
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
    =<< Name -> Element -> Maybe Element
    findChild (Text -> Name
    atomName "generator") Element
    f
      where
        isSource :: DCItem -> Bool
    isSource dc :: DCItem
    dc = DCItem -> DCInfo
    dcElt DCItem
    dc DCInfo -> DCInfo -> Bool
    forall a. Eq a => a -> a -> Bool
    == DCInfo
    DC_Source

    type ItemGetter a = Feed.Item -> Maybe a

    getItemTitle :: ItemGetter Text
    getItemTitle :: ItemGetter Text
    getItemTitle it :: Item
    it =
      case Item
    it of
        Feed.AtomItem i :: Entry
    i -> Text -> Maybe Text
    forall a. a -> Maybe a
    Just (TextContent -> Text
    contentToStr (TextContent -> Text) -> TextContent -> Text
    forall a b. (a -> b) -> a -> b
    $ Entry -> TextContent
    Atom.entryTitle Entry
    i)
        Feed.RSSItem i :: RSSItem
    i -> RSSItem -> Maybe Text
    RSS.rssItemTitle RSSItem
    i
        Feed.RSS1Item i :: Item
    i -> Text -> Maybe Text
    forall a. a -> Maybe a
    Just (Item -> Text
    RSS1.itemTitle Item
    i)
        Feed.XMLItem e :: Element
    e -> (Element -> Text) -> Maybe Element -> Maybe Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap Element -> Text
    strContent (Maybe Element -> Maybe Text) -> Maybe Element -> Maybe Text
    forall a b. (a -> b) -> a -> b
    $ Name -> Element -> Maybe Element
    findElement "title" Element
    e Maybe Element -> Maybe Element -> Maybe Element
    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
    <|> Name -> Element -> Maybe Element
    findChild (Text -> Name
    atomName "title") Element
    e

    getItemLink :: ItemGetter Text
    getItemLink :: ItemGetter Text
    getItemLink it :: Item
    it =
      case Item
    it
           -- look up the 'alternate' HTML link relation on the entry, or one
           -- without link relation since that is equivalent to 'alternate':
            of
        Feed.AtomItem i :: Entry
    i -> (Link -> Text) -> Maybe Link -> Maybe Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap Link -> Text
    Atom.linkHref (Maybe Link -> Maybe Text) -> Maybe Link -> Maybe Text
    forall a b. (a -> b) -> a -> b
    $ [Link] -> Maybe Link
    forall a. [a] -> Maybe a
    listToMaybe ([Link] -> Maybe Link) -> [Link] -> Maybe Link
    forall a b. (a -> b) -> a -> b
    $ (Link -> Bool) -> [Link] -> [Link]
    forall a. (a -> Bool) -> [a] -> [a]
    filter Link -> Bool
    isSelf ([Link] -> [Link]) -> [Link] -> [Link]
    forall a b. (a -> b) -> a -> b
    $ Entry -> [Link]
    Atom.entryLinks Entry
    i
        Feed.RSSItem i :: RSSItem
    i -> RSSItem -> Maybe Text
    RSS.rssItemLink RSSItem
    i
        Feed.RSS1Item i :: Item
    i -> Text -> Maybe Text
    forall a. a -> Maybe a
    Just (Item -> Text
    RSS1.itemLink Item
    i)
        Feed.XMLItem i :: Element
    i ->
          (Element -> Text) -> Maybe Element -> Maybe Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap Element -> Text
    strContent (Name -> Element -> Maybe Element
    findElement "link" Element
    i) Maybe Text -> Maybe Text -> Maybe Text
    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
    <|>
          (Name -> Element -> Maybe Element
    findChild (Text -> Name
    atomName "link") Element
    i Maybe Element -> (Element -> Maybe Text) -> Maybe Text
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= Name -> Element -> Maybe Text
    attributeText "href")
      where
        isSelf :: Link -> Bool
    isSelf lr :: Link
    lr =
          let rel :: Maybe (Either Text Text)
    rel = Link -> Maybe (Either Text Text)
    Atom.linkRel Link
    lr
           in (Maybe (Either Text Text) -> Bool
    forall a. Maybe a -> Bool
    isNothing Maybe (Either Text Text)
    rel Bool -> Bool -> Bool
    || Maybe (Either Text Text) -> Text
    toStr Maybe (Either Text Text)
    rel Text -> Text -> Bool
    forall a. Eq a => a -> a -> Bool
    == "alternate") Bool -> Bool -> Bool
    && Maybe Text -> Bool
    isHTMLType (Link -> Maybe Text
    linkType Link
    lr)
        isHTMLType :: Maybe Text -> Bool
    isHTMLType (Just str :: Text
    str) = "html" Text -> Text -> Bool
    `T.isSuffixOf` Text
    str
        isHTMLType _ = Bool
    True -- if none given, assume html.

    -- | 'getItemPublishDate item' returns the publication date of the item,
    -- but first parsed per the supported RFC 822 and RFC 3339 formats.
    --
    -- If the date string cannot be parsed as such, Just Nothing is
    -- returned.  The caller must then instead fall back to processing the
    -- date string from 'getItemPublishDateString'.
    --
    -- The parsed date representation is one of the ParseTime instances;
    -- see 'Data.Time.Format'.
    getItemPublishDate :: ParseTime t => ItemGetter (Maybe t)
    getItemPublishDate :: ItemGetter (Maybe t)
    getItemPublishDate it :: Item
    it = do
      Text
    ds <- ItemGetter Text
    getItemPublishDateString Item
    it
      let rfc3339DateFormat1 :: String
    rfc3339DateFormat1 = Maybe String -> String
    iso8601DateFormat (String -> Maybe String
    forall a. a -> Maybe a
    Just "%H:%M:%S%Z")
          rfc3339DateFormat2 :: String
    rfc3339DateFormat2 = Maybe String -> String
    iso8601DateFormat (String -> Maybe String
    forall a. a -> Maybe a
    Just "%H:%M:%S%Q%Z")
          formats :: [String]
    formats = [String
    rfc3339DateFormat1, String
    rfc3339DateFormat2, String
    rfc822DateFormat]
          date :: Maybe t
    date = (Maybe t -> Maybe t -> Maybe t) -> [Maybe t] -> Maybe t
    forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
    foldl1 Maybe t -> Maybe t -> Maybe t
    forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
    mplus ((String -> Maybe t) -> [String] -> [Maybe t]
    forall a b. (a -> b) -> [a] -> [b]
    map (\fmt :: String
    fmt -> TimeLocale -> String -> String -> Maybe t
    parseTime TimeLocale
    defaultTimeLocale String
    fmt (String -> Maybe t) -> String -> Maybe t
    forall a b. (a -> b) -> a -> b
    $ Text -> String
    T.unpack Text
    ds) [String]
    formats)
      Maybe t -> Maybe (Maybe t)
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe t
    date
      where

    #if MIN_VERSION_time(1,5,0)
         parseTime :: TimeLocale -> String -> String -> Maybe t
    parseTime = Bool -> TimeLocale -> String -> String -> Maybe t
    forall (m :: * -> *) t.
    (MonadFail m, ParseTime t) =>
    Bool -> TimeLocale -> String -> String -> m t
    F.parseTimeM Bool
    True
    #else
         parseTime = F.parseTime
    #endif
    getItemPublishDateString :: ItemGetter DateString
    getItemPublishDateString :: ItemGetter Text
    getItemPublishDateString it :: Item
    it =
      case Item
    it of
        Feed.AtomItem i :: Entry
    i -> Text -> Maybe Text
    forall a. a -> Maybe a
    Just (Text -> Maybe Text) -> Text -> Maybe Text
    forall a b. (a -> b) -> a -> b
    $ Entry -> Text
    Atom.entryUpdated Entry
    i
        Feed.RSSItem i :: RSSItem
    i -> RSSItem -> Maybe Text
    RSS.rssItemPubDate RSSItem
    i
        Feed.RSS1Item i :: Item
    i -> (DCItem -> Text) -> Maybe DCItem -> Maybe Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap DCItem -> Text
    dcText (Maybe DCItem -> Maybe Text) -> Maybe DCItem -> Maybe Text
    forall a b. (a -> b) -> a -> b
    $ [DCItem] -> Maybe DCItem
    forall a. [a] -> Maybe a
    listToMaybe ([DCItem] -> Maybe DCItem) -> [DCItem] -> Maybe DCItem
    forall a b. (a -> b) -> a -> b
    $ (DCItem -> Bool) -> [DCItem] -> [DCItem]
    forall a. (a -> Bool) -> [a] -> [a]
    filter DCItem -> Bool
    isDate ([DCItem] -> [DCItem]) -> [DCItem] -> [DCItem]
    forall a b. (a -> b) -> a -> b
    $ Item -> [DCItem]
    RSS1.itemDC Item
    i
        Feed.XMLItem e :: Element
    e ->
          (Element -> Text) -> Maybe Element -> Maybe Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap Element -> Text
    strContent (Maybe Element -> Maybe Text) -> Maybe Element -> Maybe Text
    forall a b. (a -> b) -> a -> b
    $ Name -> Element -> Maybe Element
    findElement "pubDate" Element
    e Maybe Element -> Maybe Element -> Maybe Element
    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
    <|> Name -> Element -> Maybe Element
    findElement (Text -> Name
    atomName "published") Element
    e
      where
        isDate :: DCItem -> Bool
    isDate dc :: DCItem
    dc = DCItem -> DCInfo
    dcElt DCItem
    dc DCInfo -> DCInfo -> Bool
    forall a. Eq a => a -> a -> Bool
    == DCInfo
    DC_Date

    getItemDate :: ItemGetter DateString
    getItemDate :: ItemGetter Text
    getItemDate = ItemGetter Text
    getItemPublishDateString

    -- | 'getItemAuthor f' returns the optional author of the item.
    getItemAuthor :: ItemGetter Text
    getItemAuthor :: ItemGetter Text
    getItemAuthor it :: Item
    it =
      case Item
    it of
        Feed.AtomItem i :: Entry
    i -> (Person -> Text) -> Maybe Person -> Maybe Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap Person -> Text
    Atom.personName (Maybe Person -> Maybe Text) -> Maybe Person -> Maybe Text
    forall a b. (a -> b) -> a -> b
    $ [Person] -> Maybe Person
    forall a. [a] -> Maybe a
    listToMaybe ([Person] -> Maybe Person) -> [Person] -> Maybe Person
    forall a b. (a -> b) -> a -> b
    $ Entry -> [Person]
    Atom.entryAuthors Entry
    i
        Feed.RSSItem i :: RSSItem
    i -> RSSItem -> Maybe Text
    RSS.rssItemAuthor RSSItem
    i
        Feed.RSS1Item i :: Item
    i -> (DCItem -> Text) -> Maybe DCItem -> Maybe Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap DCItem -> Text
    dcText (Maybe DCItem -> Maybe Text) -> Maybe DCItem -> Maybe Text
    forall a b. (a -> b) -> a -> b
    $ [DCItem] -> Maybe DCItem
    forall a. [a] -> Maybe a
    listToMaybe ([DCItem] -> Maybe DCItem) -> [DCItem] -> Maybe DCItem
    forall a b. (a -> b) -> a -> b
    $ (DCItem -> Bool) -> [DCItem] -> [DCItem]
    forall a. (a -> Bool) -> [a] -> [a]
    filter DCItem -> Bool
    isAuthor ([DCItem] -> [DCItem]) -> [DCItem] -> [DCItem]
    forall a b. (a -> b) -> a -> b
    $ Item -> [DCItem]
    RSS1.itemDC Item
    i
        Feed.XMLItem e :: Element
    e ->
          (Element -> Text) -> Maybe Element -> Maybe Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap Element -> Text
    strContent (Maybe Element -> Maybe Text) -> Maybe Element -> Maybe Text
    forall a b. (a -> b) -> a -> b
    $
          Name -> Element -> Maybe Element
    findElement "author" Element
    e Maybe Element -> Maybe Element -> Maybe Element
    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
    <|>
          (Name -> Element -> Maybe Element
    findElement (Text -> Name
    atomName "author") Element
    e Maybe Element -> (Element -> Maybe Element) -> Maybe Element
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= Name -> Element -> Maybe Element
    findElement (Text -> Name
    atomName "name"))
      where
        isAuthor :: DCItem -> Bool
    isAuthor dc :: DCItem
    dc = DCItem -> DCInfo
    dcElt DCItem
    dc DCInfo -> DCInfo -> Bool
    forall a. Eq a => a -> a -> Bool
    == DCInfo
    DC_Creator

    getItemCommentLink :: ItemGetter URLString
    getItemCommentLink :: ItemGetter Text
    getItemCommentLink it :: Item
    it =
      case Item
    it
           -- look up the 'replies' HTML link relation on the entry:
            of
        Feed.AtomItem e :: Entry
    e -> (Link -> Text) -> Maybe Link -> Maybe Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap Link -> Text
    Atom.linkHref (Maybe Link -> Maybe Text) -> Maybe Link -> Maybe Text
    forall a b. (a -> b) -> a -> b
    $ [Link] -> Maybe Link
    forall a. [a] -> Maybe a
    listToMaybe ([Link] -> Maybe Link) -> [Link] -> Maybe Link
    forall a b. (a -> b) -> a -> b
    $ (Link -> Bool) -> [Link] -> [Link]
    forall a. (a -> Bool) -> [a] -> [a]
    filter Link -> Bool
    isReplies ([Link] -> [Link]) -> [Link] -> [Link]
    forall a b. (a -> b) -> a -> b
    $ Entry -> [Link]
    Atom.entryLinks Entry
    e
        Feed.RSSItem i :: RSSItem
    i -> RSSItem -> Maybe Text
    RSS.rssItemComments RSSItem
    i
        Feed.RSS1Item i :: Item
    i -> (DCItem -> Text) -> Maybe DCItem -> Maybe Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap DCItem -> Text
    dcText (Maybe DCItem -> Maybe Text) -> Maybe DCItem -> Maybe Text
    forall a b. (a -> b) -> a -> b
    $ [DCItem] -> Maybe DCItem
    forall a. [a] -> Maybe a
    listToMaybe ([DCItem] -> Maybe DCItem) -> [DCItem] -> Maybe DCItem
    forall a b. (a -> b) -> a -> b
    $ (DCItem -> Bool) -> [DCItem] -> [DCItem]
    forall a. (a -> Bool) -> [a] -> [a]
    filter DCItem -> Bool
    isRel ([DCItem] -> [DCItem]) -> [DCItem] -> [DCItem]
    forall a b. (a -> b) -> a -> b
    $ Item -> [DCItem]
    RSS1.itemDC Item
    i
        Feed.XMLItem i :: Element
    i ->
          (Element -> Text) -> Maybe Element -> Maybe Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap Element -> Text
    strContent (Name -> Element -> Maybe Element
    findElement "comments" Element
    i) Maybe Text -> Maybe Text -> Maybe Text
    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
    <|>
          (Name -> Element -> Maybe Element
    findElement (Text -> Name
    atomName "link") Element
    i Maybe Element -> (Element -> Maybe Text) -> Maybe Text
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= Name -> Element -> Maybe Text
    attributeText "href")
      where
        isReplies :: Link -> Bool
    isReplies lr :: Link
    lr = Maybe (Either Text Text) -> Text
    toStr (Link -> Maybe (Either Text Text)
    Atom.linkRel Link
    lr) Text -> Text -> Bool
    forall a. Eq a => a -> a -> Bool
    == "replies"
        isRel :: DCItem -> Bool
    isRel dc :: DCItem
    dc = DCItem -> DCInfo
    dcElt DCItem
    dc DCInfo -> DCInfo -> Bool
    forall a. Eq a => a -> a -> Bool
    == DCInfo
    DC_Relation

    getItemEnclosure :: ItemGetter (URI, Maybe Text, Maybe Integer)
    getItemEnclosure :: ItemGetter (Text, Maybe Text, Maybe Integer)
    getItemEnclosure it :: Item
    it =
      case Item
    it of
        Feed.AtomItem e :: Entry
    e ->
          case (Link -> Bool) -> [Link] -> [Link]
    forall a. (a -> Bool) -> [a] -> [a]
    filter Link -> Bool
    isEnc ([Link] -> [Link]) -> [Link] -> [Link]
    forall a b. (a -> b) -> a -> b
    $ Entry -> [Link]
    Atom.entryLinks Entry
    e of
            (l :: Link
    l:_) -> (Text, Maybe Text, Maybe Integer)
    -> Maybe (Text, Maybe Text, Maybe Integer)
    forall a. a -> Maybe a
    Just (Link -> Text
    Atom.linkHref Link
    l, Link -> Maybe Text
    Atom.linkType Link
    l, Maybe Text -> Maybe Integer
    forall a. Integral a => Maybe Text -> Maybe a
    readLength (Link -> Maybe Text
    Atom.linkLength Link
    l))
            _ -> Maybe (Text, Maybe Text, Maybe Integer)
    forall a. Maybe a
    Nothing
        Feed.RSSItem i :: RSSItem
    i ->
          (RSSEnclosure -> (Text, Maybe Text, Maybe Integer))
    -> Maybe RSSEnclosure -> Maybe (Text, Maybe Text, Maybe Integer)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap
            (\e :: RSSEnclosure
    e -> (RSSEnclosure -> Text
    RSS.rssEnclosureURL RSSEnclosure
    e, Text -> Maybe Text
    forall a. a -> Maybe a
    Just (RSSEnclosure -> Text
    RSS.rssEnclosureType RSSEnclosure
    e), RSSEnclosure -> Maybe Integer
    RSS.rssEnclosureLength RSSEnclosure
    e))
            (RSSItem -> Maybe RSSEnclosure
    RSS.rssItemEnclosure RSSItem
    i)
        Feed.RSS1Item i :: Item
    i ->
          case Item -> [ContentInfo]
    RSS1.itemContent Item
    i of
            [] -> Maybe (Text, Maybe Text, Maybe Integer)
    forall a. Maybe a
    Nothing
            (c :: ContentInfo
    c:_) -> (Text, Maybe Text, Maybe Integer)
    -> Maybe (Text, Maybe Text, Maybe Integer)
    forall a. a -> Maybe a
    Just (Text -> Maybe Text -> Text
    forall a. a -> Maybe a -> a
    fromMaybe "" (ContentInfo -> Maybe Text
    RSS1.contentURI ContentInfo
    c), ContentInfo -> Maybe Text
    RSS1.contentFormat ContentInfo
    c, Maybe Integer
    forall a. Maybe a
    Nothing)
        Feed.XMLItem e :: Element
    e ->
          (Element -> (Text, Maybe Text, Maybe Integer))
    -> Maybe Element -> Maybe (Text, Maybe Text, Maybe Integer)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap Element -> (Text, Maybe Text, Maybe Integer)
    forall a. Integral a => Element -> (Text, Maybe Text, Maybe a)
    xmlToEnclosure (Maybe Element -> Maybe (Text, Maybe Text, Maybe Integer))
    -> Maybe Element -> Maybe (Text, Maybe Text, Maybe Integer)
    forall a b. (a -> b) -> a -> b
    $ Name -> Element -> Maybe Element
    findElement "enclosure" Element
    e Maybe Element -> Maybe Element -> Maybe Element
    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
    <|> Name -> Element -> Maybe Element
    findElement (Text -> Name
    atomName "enclosure") Element
    e
      where
        isEnc :: Link -> Bool
    isEnc lr :: Link
    lr = Maybe (Either Text Text) -> Text
    toStr (Link -> Maybe (Either Text Text)
    Atom.linkRel Link
    lr) Text -> Text -> Bool
    forall a. Eq a => a -> a -> Bool
    == "enclosure"
        readLength :: Maybe Text -> Maybe a
    readLength Nothing = Maybe a
    forall a. Maybe a
    Nothing
        readLength (Just str :: Text
    str) =
          case Reader a
    forall a. Integral a => Reader a
    decimal Text
    str of
            Right (v :: a
    v, _) -> a -> Maybe a
    forall a. a -> Maybe a
    Just a
    v
            _ -> Maybe a
    forall a. Maybe a
    Nothing
        xmlToEnclosure :: Element -> (Text, Maybe Text, Maybe a)
    xmlToEnclosure e :: Element
    e =
          ( Text -> Maybe Text -> Text
    forall a. a -> Maybe a -> a
    fromMaybe "" (Name -> Element -> Maybe Text
    attributeText "url" Element
    e)
          , Name -> Element -> Maybe Text
    attributeText "type" Element
    e
          , Maybe Text -> Maybe a
    forall a. Integral a => Maybe Text -> Maybe a
    readLength (Maybe Text -> Maybe a) -> Maybe Text -> Maybe a
    forall a b. (a -> b) -> a -> b
    $ Name -> Element -> Maybe Text
    attributeText "length" Element
    e)

    getItemFeedLink :: ItemGetter URLString
    getItemFeedLink :: ItemGetter Text
    getItemFeedLink it :: Item
    it =
      case Item
    it of
        Feed.AtomItem e :: Entry
    e ->
          case Entry -> Maybe Source
    Atom.entrySource Entry
    e of
            Nothing -> Maybe Text
    forall a. Maybe a
    Nothing
            Just s :: Source
    s -> Source -> Maybe Text
    Atom.sourceId Source
    s
        Feed.RSSItem i :: RSSItem
    i ->
          case RSSItem -> Maybe RSSSource
    RSS.rssItemSource RSSItem
    i of
            Nothing -> Maybe Text
    forall a. Maybe a
    Nothing
            Just s :: RSSSource
    s -> Text -> Maybe Text
    forall a. a -> Maybe a
    Just (RSSSource -> Text
    RSS.rssSourceURL RSSSource
    s)
        Feed.RSS1Item _ -> Maybe Text
    forall a. Maybe a
    Nothing
        Feed.XMLItem e :: Element
    e ->
          case Name -> Element -> Maybe Element
    findElement "source" Element
    e of
            Nothing -> Maybe Text
    forall a. Maybe a
    Nothing
            Just s :: Element
    s -> (Element -> Text) -> Maybe Element -> Maybe Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap Element -> Text
    strContent (Name -> Element -> Maybe Element
    findElement "url" Element
    s)
          -- ToDo parse atom like tags too

    getItemId :: ItemGetter (Bool, Text)
    getItemId :: ItemGetter (Bool, Text)
    getItemId it :: Item
    it =
      case Item
    it of
        Feed.AtomItem e :: Entry
    e -> (Bool, Text) -> Maybe (Bool, Text)
    forall a. a -> Maybe a
    Just (Bool
    True, Entry -> Text
    Atom.entryId Entry
    e)
        Feed.RSSItem i :: RSSItem
    i ->
          case RSSItem -> Maybe RSSGuid
    RSS.rssItemGuid RSSItem
    i of
            Nothing -> Maybe (Bool, Text)
    forall a. Maybe a
    Nothing
            Just ig :: RSSGuid
    ig -> (Bool, Text) -> Maybe (Bool, Text)
    forall a. a -> Maybe a
    Just (Bool -> Maybe Bool -> Bool
    forall a. a -> Maybe a -> a
    fromMaybe Bool
    True (RSSGuid -> Maybe Bool
    RSS.rssGuidPermanentURL RSSGuid
    ig), RSSGuid -> Text
    RSS.rssGuidValue RSSGuid
    ig)
        Feed.RSS1Item i :: Item
    i ->
          case (DCItem -> Bool) -> [DCItem] -> [DCItem]
    forall a. (a -> Bool) -> [a] -> [a]
    filter DCItem -> Bool
    isId (Item -> [DCItem]
    RSS1.itemDC Item
    i) of
            (l :: DCItem
    l:_) -> (Bool, Text) -> Maybe (Bool, Text)
    forall a. a -> Maybe a
    Just (Bool
    True, DCItem -> Text
    dcText DCItem
    l)
            _ -> Maybe (Bool, Text)
    forall a. Maybe a
    Nothing
        Feed.XMLItem e :: Element
    e ->
          (Element -> (Bool, Text)) -> Maybe Element -> Maybe (Bool, Text)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (\e1 :: Element
    e1 -> (Bool
    True, Element -> Text
    strContent Element
    e1)) (Maybe Element -> Maybe (Bool, Text))
    -> Maybe Element -> Maybe (Bool, Text)
    forall a b. (a -> b) -> a -> b
    $ Name -> Element -> Maybe Element
    findElement "guid" Element
    e Maybe Element -> Maybe Element -> Maybe Element
    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
    <|> Name -> Element -> Maybe Element
    findElement (Text -> Name
    atomName "id") Element
    e
      where
        isId :: DCItem -> Bool
    isId dc :: DCItem
    dc = DCItem -> DCInfo
    dcElt DCItem
    dc DCInfo -> DCInfo -> Bool
    forall a. Eq a => a -> a -> Bool
    == DCInfo
    DC_Identifier

    getItemCategories :: Feed.Item -> [Text]
    getItemCategories :: Item -> [Text]
    getItemCategories it :: Item
    it =
      case Item
    it of
        Feed.AtomItem i :: Entry
    i -> (Category -> Text) -> [Category] -> [Text]
    forall a b. (a -> b) -> [a] -> [b]
    map Category -> Text
    Atom.catTerm ([Category] -> [Text]) -> [Category] -> [Text]
    forall a b. (a -> b) -> a -> b
    $ Entry -> [Category]
    Atom.entryCategories Entry
    i
        Feed.RSSItem i :: RSSItem
    i -> (RSSCategory -> Text) -> [RSSCategory] -> [Text]
    forall a b. (a -> b) -> [a] -> [b]
    map RSSCategory -> Text
    RSS.rssCategoryValue ([RSSCategory] -> [Text]) -> [RSSCategory] -> [Text]
    forall a b. (a -> b) -> a -> b
    $ RSSItem -> [RSSCategory]
    RSS.rssItemCategories RSSItem
    i
        Feed.RSS1Item i :: Item
    i -> [[Text]] -> [Text]
    forall (t :: * -> *) a. Foldable t => t [a] -> [a]
    concat ([[Text]] -> [Text]) -> [[Text]] -> [Text]
    forall a b. (a -> b) -> a -> b
    $ Item -> [[Text]]
    getCats1 Item
    i
       -- ToDo parse atom like tags too
        Feed.XMLItem i :: Element
    i -> (Element -> Text) -> [Element] -> [Text]
    forall a b. (a -> b) -> [a] -> [b]
    map Element -> Text
    strContent ([Element] -> [Text]) -> [Element] -> [Text]
    forall a b. (a -> b) -> a -> b
    $ Name -> Element -> [Element]
    findElements "category" Element
    i
        -- get RSS1 categories; either via DublinCore's subject (or taxonomy topics...not yet.)
      where
        getCats1 :: Item -> [[Text]]
    getCats1 i1 :: Item
    i1 = (DCItem -> [Text]) -> [DCItem] -> [[Text]]
    forall a b. (a -> b) -> [a] -> [b]
    map (Text -> [Text]
    T.words (Text -> [Text]) -> (DCItem -> Text) -> DCItem -> [Text]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . DCItem -> Text
    dcText) ([DCItem] -> [[Text]]) -> [DCItem] -> [[Text]]
    forall a b. (a -> b) -> a -> b
    $ (DCItem -> Bool) -> [DCItem] -> [DCItem]
    forall a. (a -> Bool) -> [a] -> [a]
    filter (\dc :: DCItem
    dc -> DCItem -> DCInfo
    dcElt DCItem
    dc DCInfo -> DCInfo -> Bool
    forall a. Eq a => a -> a -> Bool
    == DCInfo
    DC_Subject) ([DCItem] -> [DCItem]) -> [DCItem] -> [DCItem]
    forall a b. (a -> b) -> a -> b
    $ Item -> [DCItem]
    RSS1.itemDC Item
    i1

    getItemRights :: ItemGetter Text
    getItemRights :: ItemGetter Text
    getItemRights it :: Item
    it =
      case Item
    it of
        Feed.AtomItem e :: Entry
    e -> TextContent -> Text
    contentToStr (TextContent -> Text) -> Maybe TextContent -> Maybe Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Entry -> Maybe TextContent
    Atom.entryRights Entry
    e
        Feed.RSSItem _ -> Maybe Text
    forall a. Maybe a
    Nothing
        Feed.RSS1Item i :: Item
    i -> (DCItem -> Text) -> Maybe DCItem -> Maybe Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap DCItem -> Text
    dcText (Maybe DCItem -> Maybe Text) -> Maybe DCItem -> Maybe Text
    forall a b. (a -> b) -> a -> b
    $ [DCItem] -> Maybe DCItem
    forall a. [a] -> Maybe a
    listToMaybe ([DCItem] -> Maybe DCItem) -> [DCItem] -> Maybe DCItem
    forall a b. (a -> b) -> a -> b
    $ (DCItem -> Bool) -> [DCItem] -> [DCItem]
    forall a. (a -> Bool) -> [a] -> [a]
    filter DCItem -> Bool
    isRights (Item -> [DCItem]
    RSS1.itemDC Item
    i)
        Feed.XMLItem i :: Element
    i -> Element -> Text
    strContent (Element -> Text) -> Maybe Element -> Maybe Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Name -> Element -> Maybe Element
    findElement (Text -> Name
    atomName "rights") Element
    i
      where
        isRights :: DCItem -> Bool
    isRights dc :: DCItem
    dc = DCItem -> DCInfo
    dcElt DCItem
    dc DCInfo -> DCInfo -> Bool
    forall a. Eq a => a -> a -> Bool
    == DCInfo
    DC_Rights

    getItemSummary :: ItemGetter Text
    getItemSummary :: ItemGetter Text
    getItemSummary = ItemGetter Text
    getItemDescription

    getItemDescription :: ItemGetter Text
    getItemDescription :: ItemGetter Text
    getItemDescription it :: Item
    it =
      case Item
    it of
        Feed.AtomItem e :: Entry
    e -> TextContent -> Text
    contentToStr (TextContent -> Text) -> Maybe TextContent -> Maybe Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Entry -> Maybe TextContent
    Atom.entrySummary Entry
    e
        Feed.RSSItem e :: RSSItem
    e -> RSSItem -> Maybe Text
    RSS.rssItemDescription RSSItem
    e
        Feed.RSS1Item i :: Item
    i -> Item -> Maybe Text
    itemDesc Item
    i
        Feed.XMLItem i :: Element
    i -> Element -> Text
    strContent (Element -> Text) -> Maybe Element -> Maybe Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Name -> Element -> Maybe Element
    findElement (Text -> Name
    atomName "summary") Element
    i
     -- strip away

    toStr :: Maybe (Either Text Text) -> Text
    toStr :: Maybe (Either Text Text) -> Text
    toStr Nothing = ""
    toStr (Just (Left x :: Text
    x)) = Text
    x
    toStr (Just (Right x :: Text
    x)) = Text
    x

    contentToStr :: TextContent -> Text
    contentToStr :: TextContent -> Text
    contentToStr x :: TextContent
    x =
      case TextContent
    x of
        Atom.TextString s :: Text
    s -> Text
    s
        Atom.HTMLString s :: Text
    s -> Text
    s
        Atom.XHTMLString s :: Element
    s -> Element -> Text
    strContent Element
    s