{-# 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
  , getItemContent -- :: 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 Feed
fe =
  case Feed
fe of
    AtomFeed Feed
f -> forall a b. (a -> b) -> [a] -> [b]
map Entry -> Item
Feed.AtomItem (Feed -> [Entry]
Atom.feedEntries Feed
f)
    RSSFeed RSS
f -> forall a b. (a -> b) -> [a] -> [b]
map RSSItem -> Item
Feed.RSSItem (RSSChannel -> [RSSItem]
RSS.rssItems forall a b. (a -> b) -> a -> b
$ RSS -> RSSChannel
RSS.rssChannel RSS
f)
    RSS1Feed Feed
f -> forall a b. (a -> b) -> [a] -> [b]
map Item -> Item
Feed.RSS1Item (Feed -> [Item]
RSS1.feedItems Feed
f)
    XMLFeed Element
f ->
      case Name -> Element -> [Element]
findElements Name
"item" Element
f of
        [] -> forall a b. (a -> b) -> [a] -> [b]
map Element -> Item
Feed.XMLItem forall a b. (a -> b) -> a -> b
$ Name -> Element -> [Element]
findElements (Text -> Name
atomName Text
"entry") Element
f
        [Element]
l -> 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 Feed
ft =
  case Feed
ft of
    Feed.AtomFeed Feed
f -> forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Person -> Text
Atom.personName forall a b. (a -> b) -> a -> b
$ forall a. [a] -> Maybe a
listToMaybe forall a b. (a -> b) -> a -> b
$ Feed -> [Person]
Atom.feedAuthors Feed
f
    Feed.RSSFeed RSS
f -> RSSChannel -> Maybe Text
RSS.rssEditor (RSS -> RSSChannel
RSS.rssChannel RSS
f)
    Feed.RSS1Feed Feed
f ->
      forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap DCItem -> Text
dcText forall a b. (a -> b) -> a -> b
$ forall a. [a] -> Maybe a
listToMaybe forall a b. (a -> b) -> a -> b
$ forall a. (a -> Bool) -> [a] -> [a]
filter DCItem -> Bool
isAuthor forall a b. (a -> b) -> a -> b
$ Channel -> [DCItem]
RSS1.channelDC (Feed -> Channel
RSS1.feedChannel Feed
f)
    Feed.XMLFeed Element
f ->
      case Name -> Element -> Maybe Element
findElement Name
"channel" Element
f of
        Just Element
e1 -> Element -> Text
strContent forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Name -> Element -> Maybe Element
findElement Name
"editor" Element
e1
        Maybe Element
Nothing ->
          forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Element -> Text
strContent forall a b. (a -> b) -> a -> b
$ Name -> Element -> Maybe Element
findElement (Text -> Name
atomName Text
"name") forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Name -> Element -> Maybe Element
findChild (Text -> Name
atomName Text
"author") Element
f
  where
    isAuthor :: DCItem -> Bool
isAuthor DCItem
dc = DCItem -> DCInfo
dcElt DCItem
dc forall a. Eq a => a -> a -> Bool
== DCInfo
DC_Creator

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

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

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

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

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

getFeedLastUpdate :: FeedGetter Text
getFeedLastUpdate :: FeedGetter Text
getFeedLastUpdate Feed
ft =
  case Feed
ft of
    Feed.AtomFeed Feed
f -> forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ Feed -> Text
Atom.feedUpdated Feed
f
    Feed.RSSFeed RSS
f -> RSSChannel -> Maybe Text
RSS.rssPubDate (RSS -> RSSChannel
RSS.rssChannel RSS
f)
    Feed.RSS1Feed Feed
f ->
      forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap DCItem -> Text
dcText forall a b. (a -> b) -> a -> b
$ forall a. [a] -> Maybe a
listToMaybe forall a b. (a -> b) -> a -> b
$ forall a. (a -> Bool) -> [a] -> [a]
filter DCItem -> Bool
isDate (Channel -> [DCItem]
RSS1.channelDC forall a b. (a -> b) -> a -> b
$ Feed -> Channel
RSS1.feedChannel Feed
f)
    Feed.XMLFeed Element
f ->
      case Name -> Element -> Maybe Element
findElement Name
"channel" Element
f of
        Just Element
e1 -> Element -> Text
strContent forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Name -> Element -> Maybe Element
findElement Name
"pubDate" Element
e1
        Maybe Element
Nothing -> Element -> Text
strContent forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Name -> Element -> Maybe Element
findChild (Text -> Name
atomName Text
"updated") Element
f
  where
    isDate :: DCItem -> Bool
isDate DCItem
dc = DCItem -> DCInfo
dcElt DCItem
dc 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 Feed
ft =
  case Feed
ft of
    Feed.AtomFeed Feed
f -> Feed -> Maybe Text
Atom.feedLogo Feed
f
    Feed.RSSFeed RSS
f -> forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap RSSImage -> Text
RSS.rssImageURL (RSSChannel -> Maybe RSSImage
RSS.rssImage forall a b. (a -> b) -> a -> b
$ RSS -> RSSChannel
RSS.rssChannel RSS
f)
    Feed.RSS1Feed Feed
f -> Image -> Text
RSS1.imageURI forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Feed -> Maybe Image
RSS1.feedImage Feed
f
    Feed.XMLFeed Element
f ->
      case Name -> Element -> Maybe Element
findElement Name
"channel" Element
f of
        Just Element
ch -> do
          Element
e1 <- Name -> Element -> Maybe Element
findElement Name
"image" Element
ch
          Element
v <- Name -> Element -> Maybe Element
findElement Name
"url" Element
e1
          forall (m :: * -> *) a. Monad m => a -> m a
return (Element -> Text
strContent Element
v)
        Maybe Element
Nothing -> Element -> Text
strContent forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Name -> Element -> Maybe Element
findChild (Text -> Name
atomName Text
"logo") Element
f

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

getFeedCategories :: Feed.Feed -> [(Text, Maybe Text)]
getFeedCategories :: Feed -> [(Text, Maybe Text)]
getFeedCategories Feed
ft =
  case Feed
ft of
    Feed.AtomFeed Feed
f -> forall a b. (a -> b) -> [a] -> [b]
map (Category -> Text
Atom.catTerm 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 RSS
f ->
      forall a b. (a -> b) -> [a] -> [b]
map (RSSCategory -> Text
RSS.rssCategoryValue 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 Feed
f ->
      case forall a. (a -> Bool) -> [a] -> [a]
filter DCItem -> Bool
isCat (Channel -> [DCItem]
RSS1.channelDC forall a b. (a -> b) -> a -> b
$ Feed -> Channel
RSS1.feedChannel Feed
f) of
        [DCItem]
ls -> forall a b. (a -> b) -> [a] -> [b]
map (\DCItem
l -> (DCItem -> Text
dcText DCItem
l, forall a. Maybe a
Nothing)) [DCItem]
ls
    Feed.XMLFeed Element
f ->
      case forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] (Name -> Element -> [Element]
findElements Name
"category") (Name -> Element -> Maybe Element
findElement Name
"channel" Element
f) of
        [Element]
ls -> forall a b. (a -> b) -> [a] -> [b]
map (\Element
l -> (forall b a. b -> (a -> b) -> Maybe a -> b
maybe Text
"" Element -> Text
strContent (Name -> Element -> Maybe Element
findElement Name
"term" Element
l), Name -> Element -> Maybe Text
attributeText Name
"domain" Element
l)) [Element]
ls
       -- ToDo parse atom like tags too
  where
    isCat :: DCItem -> Bool
isCat DCItem
dc = DCItem -> DCInfo
dcElt DCItem
dc forall a. Eq a => a -> a -> Bool
== DCInfo
DC_Subject

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

type ItemGetter a = Feed.Item -> Maybe a

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

getItemLink :: ItemGetter Text
getItemLink :: ItemGetter Text
getItemLink 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 Entry
i -> forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Link -> Text
Atom.linkHref forall a b. (a -> b) -> a -> b
$ forall a. [a] -> Maybe a
listToMaybe forall a b. (a -> b) -> a -> b
$ forall a. (a -> Bool) -> [a] -> [a]
filter Link -> Bool
isSelf forall a b. (a -> b) -> a -> b
$ Entry -> [Link]
Atom.entryLinks Entry
i
    Feed.RSSItem RSSItem
i -> RSSItem -> Maybe Text
RSS.rssItemLink RSSItem
i
    Feed.RSS1Item Item
i -> forall a. a -> Maybe a
Just (Item -> Text
RSS1.itemLink Item
i)
    Feed.XMLItem Element
i ->
      forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Element -> Text
strContent (Name -> Element -> Maybe Element
findElement Name
"link" Element
i) forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>
      (Name -> Element -> Maybe Element
findChild (Text -> Name
atomName Text
"link") Element
i forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Name -> Element -> Maybe Text
attributeText Name
"href")
  where
    isSelf :: Link -> Bool
isSelf Link
lr =
      let rel :: Maybe (Either Text Text)
rel = Link -> Maybe (Either Text Text)
Atom.linkRel Link
lr
       in (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 forall a. Eq a => a -> a -> Bool
== Text
"alternate") Bool -> Bool -> Bool
&& Maybe Text -> Bool
isHTMLType (Link -> Maybe Text
linkType Link
lr)
    isHTMLType :: Maybe Text -> Bool
isHTMLType (Just Text
str) = Text
"html" Text -> Text -> Bool
`T.isSuffixOf` Text
str
    isHTMLType Maybe Text
_ = 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 :: forall t. ParseTime t => ItemGetter (Maybe t)
getItemPublishDate Item
it = do
  Text
ds <- ItemGetter Text
getItemPublishDateString Item
it
  let rfc3339DateFormat1 :: String
rfc3339DateFormat1 = Maybe String -> String
iso8601DateFormat (forall a. a -> Maybe a
Just String
"%H:%M:%S%Z")
      rfc3339DateFormat2 :: String
rfc3339DateFormat2 = Maybe String -> String
iso8601DateFormat (forall a. a -> Maybe a
Just String
"%H:%M:%S%Q%Z")
      formats :: [String]
formats = [String
rfc3339DateFormat1, String
rfc3339DateFormat2, String
rfc822DateFormat]
      date :: Maybe t
date = forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldl1 forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
mplus (forall a b. (a -> b) -> [a] -> [b]
map (\String
fmt -> TimeLocale -> String -> String -> Maybe t
parseTime TimeLocale
defaultTimeLocale String
fmt forall a b. (a -> b) -> a -> b
$ Text -> String
T.unpack Text
ds) [String]
formats)
  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 = 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 Item
it =
  case Item
it of
    Feed.AtomItem Entry
i -> forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ Entry -> Text
Atom.entryUpdated Entry
i
    Feed.RSSItem RSSItem
i -> RSSItem -> Maybe Text
RSS.rssItemPubDate RSSItem
i
    Feed.RSS1Item Item
i -> forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap DCItem -> Text
dcText forall a b. (a -> b) -> a -> b
$ forall a. [a] -> Maybe a
listToMaybe forall a b. (a -> b) -> a -> b
$ forall a. (a -> Bool) -> [a] -> [a]
filter DCItem -> Bool
isDate forall a b. (a -> b) -> a -> b
$ Item -> [DCItem]
RSS1.itemDC Item
i
    Feed.XMLItem Element
e ->
      forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Element -> Text
strContent forall a b. (a -> b) -> a -> b
$ Name -> Element -> Maybe Element
findElement Name
"pubDate" Element
e forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Name -> Element -> Maybe Element
findElement (Text -> Name
atomName Text
"published") Element
e
  where
    isDate :: DCItem -> Bool
isDate DCItem
dc = DCItem -> DCInfo
dcElt DCItem
dc 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 Item
it =
  case Item
it of
    Feed.AtomItem Entry
i -> forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Person -> Text
Atom.personName forall a b. (a -> b) -> a -> b
$ forall a. [a] -> Maybe a
listToMaybe forall a b. (a -> b) -> a -> b
$ Entry -> [Person]
Atom.entryAuthors Entry
i
    Feed.RSSItem RSSItem
i -> RSSItem -> Maybe Text
RSS.rssItemAuthor RSSItem
i
    Feed.RSS1Item Item
i -> forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap DCItem -> Text
dcText forall a b. (a -> b) -> a -> b
$ forall a. [a] -> Maybe a
listToMaybe forall a b. (a -> b) -> a -> b
$ forall a. (a -> Bool) -> [a] -> [a]
filter DCItem -> Bool
isAuthor forall a b. (a -> b) -> a -> b
$ Item -> [DCItem]
RSS1.itemDC Item
i
    Feed.XMLItem Element
e ->
      forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Element -> Text
strContent forall a b. (a -> b) -> a -> b
$
      Name -> Element -> Maybe Element
findElement Name
"author" Element
e forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>
      (Name -> Element -> Maybe Element
findElement (Text -> Name
atomName Text
"author") Element
e forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Name -> Element -> Maybe Element
findElement (Text -> Name
atomName Text
"name"))
  where
    isAuthor :: DCItem -> Bool
isAuthor DCItem
dc = DCItem -> DCInfo
dcElt DCItem
dc forall a. Eq a => a -> a -> Bool
== DCInfo
DC_Creator

getItemCommentLink :: ItemGetter URLString
getItemCommentLink :: ItemGetter Text
getItemCommentLink Item
it =
  case Item
it
       -- look up the 'replies' HTML link relation on the entry:
        of
    Feed.AtomItem Entry
e -> forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Link -> Text
Atom.linkHref forall a b. (a -> b) -> a -> b
$ forall a. [a] -> Maybe a
listToMaybe forall a b. (a -> b) -> a -> b
$ forall a. (a -> Bool) -> [a] -> [a]
filter Link -> Bool
isReplies forall a b. (a -> b) -> a -> b
$ Entry -> [Link]
Atom.entryLinks Entry
e
    Feed.RSSItem RSSItem
i -> RSSItem -> Maybe Text
RSS.rssItemComments RSSItem
i
    Feed.RSS1Item Item
i -> forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap DCItem -> Text
dcText forall a b. (a -> b) -> a -> b
$ forall a. [a] -> Maybe a
listToMaybe forall a b. (a -> b) -> a -> b
$ forall a. (a -> Bool) -> [a] -> [a]
filter DCItem -> Bool
isRel forall a b. (a -> b) -> a -> b
$ Item -> [DCItem]
RSS1.itemDC Item
i
    Feed.XMLItem Element
i ->
      forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Element -> Text
strContent (Name -> Element -> Maybe Element
findElement Name
"comments" Element
i) forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>
      (Name -> Element -> Maybe Element
findElement (Text -> Name
atomName Text
"link") Element
i forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Name -> Element -> Maybe Text
attributeText Name
"href")
  where
    isReplies :: Link -> Bool
isReplies Link
lr = Maybe (Either Text Text) -> Text
toStr (Link -> Maybe (Either Text Text)
Atom.linkRel Link
lr) forall a. Eq a => a -> a -> Bool
== Text
"replies"
    isRel :: DCItem -> Bool
isRel DCItem
dc = DCItem -> DCInfo
dcElt DCItem
dc 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 Item
it =
  case Item
it of
    Feed.AtomItem Entry
e ->
      case forall a. (a -> Bool) -> [a] -> [a]
filter Link -> Bool
isEnc forall a b. (a -> b) -> a -> b
$ Entry -> [Link]
Atom.entryLinks Entry
e of
        (Link
l:[Link]
_) -> forall a. a -> Maybe a
Just (Link -> Text
Atom.linkHref Link
l, Link -> Maybe Text
Atom.linkType Link
l, forall {a}. Integral a => Maybe Text -> Maybe a
readLength (Link -> Maybe Text
Atom.linkLength Link
l))
        [Link]
_ -> forall a. Maybe a
Nothing
    Feed.RSSItem RSSItem
i ->
      forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap
        (\RSSEnclosure
e -> (RSSEnclosure -> Text
RSS.rssEnclosureURL RSSEnclosure
e, 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 Item
i ->
      case Item -> [ContentInfo]
RSS1.itemContent Item
i of
        [] -> forall a. Maybe a
Nothing
        (ContentInfo
c:[ContentInfo]
_) -> forall a. a -> Maybe a
Just (forall a. a -> Maybe a -> a
fromMaybe Text
"" (ContentInfo -> Maybe Text
RSS1.contentURI ContentInfo
c), ContentInfo -> Maybe Text
RSS1.contentFormat ContentInfo
c, forall a. Maybe a
Nothing)
    Feed.XMLItem Element
e ->
      forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall {a}. Integral a => Element -> (Text, Maybe Text, Maybe a)
xmlToEnclosure forall a b. (a -> b) -> a -> b
$ Name -> Element -> Maybe Element
findElement Name
"enclosure" Element
e forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Name -> Element -> Maybe Element
findElement (Text -> Name
atomName Text
"enclosure") Element
e
  where
    isEnc :: Link -> Bool
isEnc Link
lr = Maybe (Either Text Text) -> Text
toStr (Link -> Maybe (Either Text Text)
Atom.linkRel Link
lr) forall a. Eq a => a -> a -> Bool
== Text
"enclosure"
    readLength :: Maybe Text -> Maybe a
readLength Maybe Text
Nothing = forall a. Maybe a
Nothing
    readLength (Just Text
str) =
      case forall a. Integral a => Reader a
decimal Text
str of
        Right (a
v, Text
_) -> forall a. a -> Maybe a
Just a
v
        Either String (a, Text)
_ -> forall a. Maybe a
Nothing
    xmlToEnclosure :: Element -> (Text, Maybe Text, Maybe a)
xmlToEnclosure Element
e =
      ( forall a. a -> Maybe a -> a
fromMaybe Text
"" (Name -> Element -> Maybe Text
attributeText Name
"url" Element
e)
      , Name -> Element -> Maybe Text
attributeText Name
"type" Element
e
      , forall {a}. Integral a => Maybe Text -> Maybe a
readLength forall a b. (a -> b) -> a -> b
$ Name -> Element -> Maybe Text
attributeText Name
"length" Element
e)

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

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

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

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

getItemContent :: ItemGetter Text
getItemContent :: ItemGetter Text
getItemContent Item
it =
  case Item
it of
    Feed.AtomItem Entry
e -> EntryContent -> Text
atomContentToStr forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Entry -> Maybe EntryContent
Atom.entryContent Entry
e
    Feed.RSSItem RSSItem
e -> RSSItem -> Maybe Text
RSS.rssItemContent RSSItem
e
    Feed.RSS1Item Item
_ -> forall a. Maybe a
Nothing
    Feed.XMLItem Element
i -> Element -> Text
strContent forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Name -> Element -> Maybe Element
findElement (Text -> Name
atomName Text
"content") Element
i

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

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

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

atomContentToStr :: EntryContent -> Text
atomContentToStr :: EntryContent -> Text
atomContentToStr EntryContent
entry =
  case EntryContent
entry of
    HTMLContent Text
e -> Text
e
    XHTMLContent Element
e -> [Text] -> Text
T.unlines forall a b. (a -> b) -> a -> b
$ Element -> [Text]
elementText Element
e
    MixedContent Maybe Text
text [Node]
_ -> forall a. a -> Maybe a -> a
fromMaybe Text
"" Maybe Text
text
    ExternalContent Maybe Text
_ Text
b -> Text
b
    TextContent Text
text -> Text
text

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