{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE PartialTypeSignatures #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE UnicodeSyntax #-}
module Imm.Feed (
FeedLocation (..),
UID,
FeedQuery (..),
FeedDefinition (..),
FeedItem (..),
Author (..),
parseFeed,
feedC,
parseFeedItem,
getMainLink,
areSameItem,
)
where
import Conduit
import Control.Exception.Safe
import Data.Aeson.Extended
import Data.Text as Text (null)
import Data.Time
import Data.XML.Types
import Imm.Link
import Imm.Pretty
import Refined
import Safe
import Text.Atom.Conduit.Parse
import Text.Atom.Types
import Text.RSS.Conduit.Parse
import Text.RSS.Extensions.Content
import Text.RSS.Extensions.DublinCore
import Text.RSS.Types
import Text.RSS1.Conduit.Parse
import Text.XML.Stream.Parse as XML hiding (content)
import URI.ByteString.Extended
data FeedLocation = FeedLocation URI Text
deriving (FeedLocation -> FeedLocation -> Bool
(FeedLocation -> FeedLocation -> Bool)
-> (FeedLocation -> FeedLocation -> Bool) -> Eq FeedLocation
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: FeedLocation -> FeedLocation -> Bool
== :: FeedLocation -> FeedLocation -> Bool
$c/= :: FeedLocation -> FeedLocation -> Bool
/= :: FeedLocation -> FeedLocation -> Bool
Eq, (forall x. FeedLocation -> Rep FeedLocation x)
-> (forall x. Rep FeedLocation x -> FeedLocation)
-> Generic FeedLocation
forall x. Rep FeedLocation x -> FeedLocation
forall x. FeedLocation -> Rep FeedLocation x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. FeedLocation -> Rep FeedLocation x
from :: forall x. FeedLocation -> Rep FeedLocation x
$cto :: forall x. Rep FeedLocation x -> FeedLocation
to :: forall x. Rep FeedLocation x -> FeedLocation
Generic, Eq FeedLocation
Eq FeedLocation =>
(FeedLocation -> FeedLocation -> Ordering)
-> (FeedLocation -> FeedLocation -> Bool)
-> (FeedLocation -> FeedLocation -> Bool)
-> (FeedLocation -> FeedLocation -> Bool)
-> (FeedLocation -> FeedLocation -> Bool)
-> (FeedLocation -> FeedLocation -> FeedLocation)
-> (FeedLocation -> FeedLocation -> FeedLocation)
-> Ord FeedLocation
FeedLocation -> FeedLocation -> Bool
FeedLocation -> FeedLocation -> Ordering
FeedLocation -> FeedLocation -> FeedLocation
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: FeedLocation -> FeedLocation -> Ordering
compare :: FeedLocation -> FeedLocation -> Ordering
$c< :: FeedLocation -> FeedLocation -> Bool
< :: FeedLocation -> FeedLocation -> Bool
$c<= :: FeedLocation -> FeedLocation -> Bool
<= :: FeedLocation -> FeedLocation -> Bool
$c> :: FeedLocation -> FeedLocation -> Bool
> :: FeedLocation -> FeedLocation -> Bool
$c>= :: FeedLocation -> FeedLocation -> Bool
>= :: FeedLocation -> FeedLocation -> Bool
$cmax :: FeedLocation -> FeedLocation -> FeedLocation
max :: FeedLocation -> FeedLocation -> FeedLocation
$cmin :: FeedLocation -> FeedLocation -> FeedLocation
min :: FeedLocation -> FeedLocation -> FeedLocation
Ord, Int -> FeedLocation -> ShowS
[FeedLocation] -> ShowS
FeedLocation -> [Char]
(Int -> FeedLocation -> ShowS)
-> (FeedLocation -> [Char])
-> ([FeedLocation] -> ShowS)
-> Show FeedLocation
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> FeedLocation -> ShowS
showsPrec :: Int -> FeedLocation -> ShowS
$cshow :: FeedLocation -> [Char]
show :: FeedLocation -> [Char]
$cshowList :: [FeedLocation] -> ShowS
showList :: [FeedLocation] -> ShowS
Show, Typeable)
instance Pretty FeedLocation where
pretty :: forall ann. FeedLocation -> Doc ann
pretty (FeedLocation URI
uri Text
title) =
URI -> Doc ann
forall a b. URIRef a -> Doc b
prettyURI URI
uri
Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> if Text -> Bool
Text.null Text
title then Doc ann
forall a. Monoid a => a
mempty else Doc ann
forall ann. Doc ann
space Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann
brackets (Text -> Doc ann
forall ann. Text -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty Text
title)
instance ToJSON FeedLocation where
toJSON :: FeedLocation -> Value
toJSON (FeedLocation URI
uri Text
title) =
[Pair] -> Value
object
[ Key
"uri" Key -> Value -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= JsonURI -> Value
forall a. ToJSON a => a -> Value
toJSON (URI -> JsonURI
JsonURI URI
uri)
, Key
"title" Key -> Text -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Text
title
]
instance FromJSON FeedLocation where
parseJSON :: Value -> Parser FeedLocation
parseJSON = [Char]
-> (Object -> Parser FeedLocation) -> Value -> Parser FeedLocation
forall a. [Char] -> (Object -> Parser a) -> Value -> Parser a
withObject [Char]
"FeedLocation" ((Object -> Parser FeedLocation) -> Value -> Parser FeedLocation)
-> (Object -> Parser FeedLocation) -> Value -> Parser FeedLocation
forall a b. (a -> b) -> a -> b
$ \Object
v → do
URI -> Text -> FeedLocation
FeedLocation (URI -> Text -> FeedLocation)
-> Parser URI -> Parser (Text -> FeedLocation)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (JsonURI -> URI
_unwrapURI (JsonURI -> URI) -> Parser JsonURI -> Parser URI
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Object
v Object -> Key -> Parser JsonURI
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"uri")) Parser (Text -> FeedLocation) -> Parser Text -> Parser FeedLocation
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Object
v Object -> Key -> Parser Text
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"title")
type UID = Int
data FeedQuery = QueryByUID UID | QueryAll
deriving (FeedQuery -> FeedQuery -> Bool
(FeedQuery -> FeedQuery -> Bool)
-> (FeedQuery -> FeedQuery -> Bool) -> Eq FeedQuery
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: FeedQuery -> FeedQuery -> Bool
== :: FeedQuery -> FeedQuery -> Bool
$c/= :: FeedQuery -> FeedQuery -> Bool
/= :: FeedQuery -> FeedQuery -> Bool
Eq, Eq FeedQuery
Eq FeedQuery =>
(FeedQuery -> FeedQuery -> Ordering)
-> (FeedQuery -> FeedQuery -> Bool)
-> (FeedQuery -> FeedQuery -> Bool)
-> (FeedQuery -> FeedQuery -> Bool)
-> (FeedQuery -> FeedQuery -> Bool)
-> (FeedQuery -> FeedQuery -> FeedQuery)
-> (FeedQuery -> FeedQuery -> FeedQuery)
-> Ord FeedQuery
FeedQuery -> FeedQuery -> Bool
FeedQuery -> FeedQuery -> Ordering
FeedQuery -> FeedQuery -> FeedQuery
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: FeedQuery -> FeedQuery -> Ordering
compare :: FeedQuery -> FeedQuery -> Ordering
$c< :: FeedQuery -> FeedQuery -> Bool
< :: FeedQuery -> FeedQuery -> Bool
$c<= :: FeedQuery -> FeedQuery -> Bool
<= :: FeedQuery -> FeedQuery -> Bool
$c> :: FeedQuery -> FeedQuery -> Bool
> :: FeedQuery -> FeedQuery -> Bool
$c>= :: FeedQuery -> FeedQuery -> Bool
>= :: FeedQuery -> FeedQuery -> Bool
$cmax :: FeedQuery -> FeedQuery -> FeedQuery
max :: FeedQuery -> FeedQuery -> FeedQuery
$cmin :: FeedQuery -> FeedQuery -> FeedQuery
min :: FeedQuery -> FeedQuery -> FeedQuery
Ord, ReadPrec [FeedQuery]
ReadPrec FeedQuery
Int -> ReadS FeedQuery
ReadS [FeedQuery]
(Int -> ReadS FeedQuery)
-> ReadS [FeedQuery]
-> ReadPrec FeedQuery
-> ReadPrec [FeedQuery]
-> Read FeedQuery
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS FeedQuery
readsPrec :: Int -> ReadS FeedQuery
$creadList :: ReadS [FeedQuery]
readList :: ReadS [FeedQuery]
$creadPrec :: ReadPrec FeedQuery
readPrec :: ReadPrec FeedQuery
$creadListPrec :: ReadPrec [FeedQuery]
readListPrec :: ReadPrec [FeedQuery]
Read, Int -> FeedQuery -> ShowS
[FeedQuery] -> ShowS
FeedQuery -> [Char]
(Int -> FeedQuery -> ShowS)
-> (FeedQuery -> [Char])
-> ([FeedQuery] -> ShowS)
-> Show FeedQuery
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> FeedQuery -> ShowS
showsPrec :: Int -> FeedQuery -> ShowS
$cshow :: FeedQuery -> [Char]
show :: FeedQuery -> [Char]
$cshowList :: [FeedQuery] -> ShowS
showList :: [FeedQuery] -> ShowS
Show, Typeable)
instance Pretty FeedQuery where
pretty :: forall ann. FeedQuery -> Doc ann
pretty FeedQuery
QueryAll = Doc ann
"All subscribed feeds"
pretty (QueryByUID Int
k) = Doc ann
"Feed" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Int -> Doc ann
forall ann. Int -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty Int
k
newtype FeedDefinition = FeedDefinition
{ FeedDefinition -> Text
_feedTitle ∷ Text
}
deriving (FeedDefinition -> FeedDefinition -> Bool
(FeedDefinition -> FeedDefinition -> Bool)
-> (FeedDefinition -> FeedDefinition -> Bool) -> Eq FeedDefinition
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: FeedDefinition -> FeedDefinition -> Bool
== :: FeedDefinition -> FeedDefinition -> Bool
$c/= :: FeedDefinition -> FeedDefinition -> Bool
/= :: FeedDefinition -> FeedDefinition -> Bool
Eq, (forall x. FeedDefinition -> Rep FeedDefinition x)
-> (forall x. Rep FeedDefinition x -> FeedDefinition)
-> Generic FeedDefinition
forall x. Rep FeedDefinition x -> FeedDefinition
forall x. FeedDefinition -> Rep FeedDefinition x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. FeedDefinition -> Rep FeedDefinition x
from :: forall x. FeedDefinition -> Rep FeedDefinition x
$cto :: forall x. Rep FeedDefinition x -> FeedDefinition
to :: forall x. Rep FeedDefinition x -> FeedDefinition
Generic, Eq FeedDefinition
Eq FeedDefinition =>
(FeedDefinition -> FeedDefinition -> Ordering)
-> (FeedDefinition -> FeedDefinition -> Bool)
-> (FeedDefinition -> FeedDefinition -> Bool)
-> (FeedDefinition -> FeedDefinition -> Bool)
-> (FeedDefinition -> FeedDefinition -> Bool)
-> (FeedDefinition -> FeedDefinition -> FeedDefinition)
-> (FeedDefinition -> FeedDefinition -> FeedDefinition)
-> Ord FeedDefinition
FeedDefinition -> FeedDefinition -> Bool
FeedDefinition -> FeedDefinition -> Ordering
FeedDefinition -> FeedDefinition -> FeedDefinition
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: FeedDefinition -> FeedDefinition -> Ordering
compare :: FeedDefinition -> FeedDefinition -> Ordering
$c< :: FeedDefinition -> FeedDefinition -> Bool
< :: FeedDefinition -> FeedDefinition -> Bool
$c<= :: FeedDefinition -> FeedDefinition -> Bool
<= :: FeedDefinition -> FeedDefinition -> Bool
$c> :: FeedDefinition -> FeedDefinition -> Bool
> :: FeedDefinition -> FeedDefinition -> Bool
$c>= :: FeedDefinition -> FeedDefinition -> Bool
>= :: FeedDefinition -> FeedDefinition -> Bool
$cmax :: FeedDefinition -> FeedDefinition -> FeedDefinition
max :: FeedDefinition -> FeedDefinition -> FeedDefinition
$cmin :: FeedDefinition -> FeedDefinition -> FeedDefinition
min :: FeedDefinition -> FeedDefinition -> FeedDefinition
Ord, ReadPrec [FeedDefinition]
ReadPrec FeedDefinition
Int -> ReadS FeedDefinition
ReadS [FeedDefinition]
(Int -> ReadS FeedDefinition)
-> ReadS [FeedDefinition]
-> ReadPrec FeedDefinition
-> ReadPrec [FeedDefinition]
-> Read FeedDefinition
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS FeedDefinition
readsPrec :: Int -> ReadS FeedDefinition
$creadList :: ReadS [FeedDefinition]
readList :: ReadS [FeedDefinition]
$creadPrec :: ReadPrec FeedDefinition
readPrec :: ReadPrec FeedDefinition
$creadListPrec :: ReadPrec [FeedDefinition]
readListPrec :: ReadPrec [FeedDefinition]
Read, Int -> FeedDefinition -> ShowS
[FeedDefinition] -> ShowS
FeedDefinition -> [Char]
(Int -> FeedDefinition -> ShowS)
-> (FeedDefinition -> [Char])
-> ([FeedDefinition] -> ShowS)
-> Show FeedDefinition
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> FeedDefinition -> ShowS
showsPrec :: Int -> FeedDefinition -> ShowS
$cshow :: FeedDefinition -> [Char]
show :: FeedDefinition -> [Char]
$cshowList :: [FeedDefinition] -> ShowS
showList :: [FeedDefinition] -> ShowS
Show, Typeable)
feedDefinitionOptions ∷ Options
feedDefinitionOptions :: Options
feedDefinitionOptions =
Options
defaultOptions
{ fieldLabelModifier = camelTo2 '_' . drop (length @[] "_feed")
, omitNothingFields = True
}
instance ToJSON FeedDefinition where
toJSON :: FeedDefinition -> Value
toJSON = Options -> FeedDefinition -> Value
forall a.
(Generic a, GToJSON' Value Zero (Rep a)) =>
Options -> a -> Value
genericToJSON Options
feedDefinitionOptions
toEncoding :: FeedDefinition -> Encoding
toEncoding = Options -> FeedDefinition -> Encoding
forall a.
(Generic a, GToJSON' Encoding Zero (Rep a)) =>
Options -> a -> Encoding
genericToEncoding Options
feedDefinitionOptions
instance FromJSON FeedDefinition where
parseJSON :: Value -> Parser FeedDefinition
parseJSON = Options -> Value -> Parser FeedDefinition
forall a.
(Generic a, GFromJSON Zero (Rep a)) =>
Options -> Value -> Parser a
genericParseJSON Options
feedDefinitionOptions
instance Pretty FeedDefinition where
pretty :: forall ann. FeedDefinition -> Doc ann
pretty FeedDefinition
definition = Text -> Doc ann
forall ann. Text -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty (Text -> Doc ann) -> Text -> Doc ann
forall a b. (a -> b) -> a -> b
$ FeedDefinition -> Text
_feedTitle FeedDefinition
definition
instance Pretty (PrettyName FeedDefinition) where
pretty :: forall ann. PrettyName FeedDefinition -> Doc ann
pretty (PrettyName FeedDefinition
definition) = Text -> Doc ann
forall ann. Text -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty (Text -> Doc ann) -> Text -> Doc ann
forall a b. (a -> b) -> a -> b
$ FeedDefinition -> Text
_feedTitle FeedDefinition
definition
data Author = Author
{ Author -> Text
_authorName ∷ Text
, Author -> Text
_authorEmail ∷ Text
, Author -> Maybe AnyURI
_authorURI ∷ Maybe AnyURI
}
deriving (Author -> Author -> Bool
(Author -> Author -> Bool)
-> (Author -> Author -> Bool) -> Eq Author
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Author -> Author -> Bool
== :: Author -> Author -> Bool
$c/= :: Author -> Author -> Bool
/= :: Author -> Author -> Bool
Eq, (forall x. Author -> Rep Author x)
-> (forall x. Rep Author x -> Author) -> Generic Author
forall x. Rep Author x -> Author
forall x. Author -> Rep Author x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Author -> Rep Author x
from :: forall x. Author -> Rep Author x
$cto :: forall x. Rep Author x -> Author
to :: forall x. Rep Author x -> Author
Generic, Eq Author
Eq Author =>
(Author -> Author -> Ordering)
-> (Author -> Author -> Bool)
-> (Author -> Author -> Bool)
-> (Author -> Author -> Bool)
-> (Author -> Author -> Bool)
-> (Author -> Author -> Author)
-> (Author -> Author -> Author)
-> Ord Author
Author -> Author -> Bool
Author -> Author -> Ordering
Author -> Author -> Author
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Author -> Author -> Ordering
compare :: Author -> Author -> Ordering
$c< :: Author -> Author -> Bool
< :: Author -> Author -> Bool
$c<= :: Author -> Author -> Bool
<= :: Author -> Author -> Bool
$c> :: Author -> Author -> Bool
> :: Author -> Author -> Bool
$c>= :: Author -> Author -> Bool
>= :: Author -> Author -> Bool
$cmax :: Author -> Author -> Author
max :: Author -> Author -> Author
$cmin :: Author -> Author -> Author
min :: Author -> Author -> Author
Ord, Int -> Author -> ShowS
[Author] -> ShowS
Author -> [Char]
(Int -> Author -> ShowS)
-> (Author -> [Char]) -> ([Author] -> ShowS) -> Show Author
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Author -> ShowS
showsPrec :: Int -> Author -> ShowS
$cshow :: Author -> [Char]
show :: Author -> [Char]
$cshowList :: [Author] -> ShowS
showList :: [Author] -> ShowS
Show, Typeable)
authorOptions ∷ Options
authorOptions :: Options
authorOptions =
Options
defaultOptions
{ fieldLabelModifier = camelTo2 '_' . drop (length @[] "_author")
, omitNothingFields = True
}
instance ToJSON Author where
toJSON :: Author -> Value
toJSON = Options -> Author -> Value
forall a.
(Generic a, GToJSON' Value Zero (Rep a)) =>
Options -> a -> Value
genericToJSON Options
authorOptions
toEncoding :: Author -> Encoding
toEncoding = Options -> Author -> Encoding
forall a.
(Generic a, GToJSON' Encoding Zero (Rep a)) =>
Options -> a -> Encoding
genericToEncoding Options
authorOptions
instance FromJSON Author where
parseJSON :: Value -> Parser Author
parseJSON = Options -> Value -> Parser Author
forall a.
(Generic a, GFromJSON Zero (Rep a)) =>
Options -> Value -> Parser a
genericParseJSON Options
authorOptions
instance Pretty Author where
pretty :: forall ann. Author -> Doc ann
pretty Author{Maybe AnyURI
Text
_authorName :: Author -> Text
_authorEmail :: Author -> Text
_authorURI :: Author -> Maybe AnyURI
_authorName :: Text
_authorEmail :: Text
_authorURI :: Maybe AnyURI
..} = Text -> Doc ann
forall ann. Text -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty Text
_authorName Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann
brackets (Text -> Doc ann
forall ann. Text -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty Text
_authorEmail)
data FeedItem = FeedItem
{ FeedItem -> Maybe UTCTime
_itemDate ∷ Maybe UTCTime
, FeedItem -> Text
_itemTitle ∷ Text
, FeedItem -> Text
_itemContent ∷ Text
, FeedItem -> [Link]
_itemLinks ∷ [Link]
, FeedItem -> Text
_itemIdentifier ∷ Text
, FeedItem -> [Author]
_itemAuthors ∷ [Author]
}
deriving (FeedItem -> FeedItem -> Bool
(FeedItem -> FeedItem -> Bool)
-> (FeedItem -> FeedItem -> Bool) -> Eq FeedItem
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: FeedItem -> FeedItem -> Bool
== :: FeedItem -> FeedItem -> Bool
$c/= :: FeedItem -> FeedItem -> Bool
/= :: FeedItem -> FeedItem -> Bool
Eq, (forall x. FeedItem -> Rep FeedItem x)
-> (forall x. Rep FeedItem x -> FeedItem) -> Generic FeedItem
forall x. Rep FeedItem x -> FeedItem
forall x. FeedItem -> Rep FeedItem x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. FeedItem -> Rep FeedItem x
from :: forall x. FeedItem -> Rep FeedItem x
$cto :: forall x. Rep FeedItem x -> FeedItem
to :: forall x. Rep FeedItem x -> FeedItem
Generic, Eq FeedItem
Eq FeedItem =>
(FeedItem -> FeedItem -> Ordering)
-> (FeedItem -> FeedItem -> Bool)
-> (FeedItem -> FeedItem -> Bool)
-> (FeedItem -> FeedItem -> Bool)
-> (FeedItem -> FeedItem -> Bool)
-> (FeedItem -> FeedItem -> FeedItem)
-> (FeedItem -> FeedItem -> FeedItem)
-> Ord FeedItem
FeedItem -> FeedItem -> Bool
FeedItem -> FeedItem -> Ordering
FeedItem -> FeedItem -> FeedItem
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: FeedItem -> FeedItem -> Ordering
compare :: FeedItem -> FeedItem -> Ordering
$c< :: FeedItem -> FeedItem -> Bool
< :: FeedItem -> FeedItem -> Bool
$c<= :: FeedItem -> FeedItem -> Bool
<= :: FeedItem -> FeedItem -> Bool
$c> :: FeedItem -> FeedItem -> Bool
> :: FeedItem -> FeedItem -> Bool
$c>= :: FeedItem -> FeedItem -> Bool
>= :: FeedItem -> FeedItem -> Bool
$cmax :: FeedItem -> FeedItem -> FeedItem
max :: FeedItem -> FeedItem -> FeedItem
$cmin :: FeedItem -> FeedItem -> FeedItem
min :: FeedItem -> FeedItem -> FeedItem
Ord, Int -> FeedItem -> ShowS
[FeedItem] -> ShowS
FeedItem -> [Char]
(Int -> FeedItem -> ShowS)
-> (FeedItem -> [Char]) -> ([FeedItem] -> ShowS) -> Show FeedItem
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> FeedItem -> ShowS
showsPrec :: Int -> FeedItem -> ShowS
$cshow :: FeedItem -> [Char]
show :: FeedItem -> [Char]
$cshowList :: [FeedItem] -> ShowS
showList :: [FeedItem] -> ShowS
Show, Typeable)
feedItemOptions ∷ Options
feedItemOptions :: Options
feedItemOptions =
Options
defaultOptions
{ fieldLabelModifier = camelTo2 '_' . drop (length @[] "_item")
, omitNothingFields = True
}
instance ToJSON FeedItem where
toJSON :: FeedItem -> Value
toJSON = Options -> FeedItem -> Value
forall a.
(Generic a, GToJSON' Value Zero (Rep a)) =>
Options -> a -> Value
genericToJSON Options
feedItemOptions
toEncoding :: FeedItem -> Encoding
toEncoding = Options -> FeedItem -> Encoding
forall a.
(Generic a, GToJSON' Encoding Zero (Rep a)) =>
Options -> a -> Encoding
genericToEncoding Options
feedItemOptions
instance FromJSON FeedItem where
parseJSON :: Value -> Parser FeedItem
parseJSON = Options -> Value -> Parser FeedItem
forall a.
(Generic a, GFromJSON Zero (Rep a)) =>
Options -> Value -> Parser a
genericParseJSON Options
feedItemOptions
instance Pretty (PrettyName FeedItem) where
pretty :: forall ann. PrettyName FeedItem -> Doc ann
pretty (PrettyName FeedItem
item) = Text -> Doc ann
forall ann. Text -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty (FeedItem -> Text
_itemTitle FeedItem
item)
instance Pretty FeedItem where
pretty :: forall ann. FeedItem -> Doc ann
pretty FeedItem{[Link]
[Author]
Maybe UTCTime
Text
_itemDate :: FeedItem -> Maybe UTCTime
_itemTitle :: FeedItem -> Text
_itemContent :: FeedItem -> Text
_itemLinks :: FeedItem -> [Link]
_itemIdentifier :: FeedItem -> Text
_itemAuthors :: FeedItem -> [Author]
_itemDate :: Maybe UTCTime
_itemTitle :: Text
_itemContent :: Text
_itemLinks :: [Link]
_itemIdentifier :: Text
_itemAuthors :: [Author]
..} = Doc ann -> (UTCTime -> Doc ann) -> Maybe UTCTime -> Doc ann
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Doc ann
"<unknown>" UTCTime -> Doc ann
forall a. UTCTime -> Doc a
prettyTime Maybe UTCTime
_itemDate Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Text -> Doc ann
forall ann. Text -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty Text
_itemTitle
parseFeed ∷ MonadCatch m ⇒ Text → m (FeedDefinition, [FeedItem])
parseFeed :: forall (m :: * -> *).
MonadCatch m =>
Text -> m (FeedDefinition, [FeedItem])
parseFeed Text
text = ConduitT () Void m (FeedDefinition, [FeedItem])
-> m (FeedDefinition, [FeedItem])
forall (m :: * -> *) r. Monad m => ConduitT () Void m r -> m r
runConduit (ConduitT () Void m (FeedDefinition, [FeedItem])
-> m (FeedDefinition, [FeedItem]))
-> ConduitT () Void m (FeedDefinition, [FeedItem])
-> m (FeedDefinition, [FeedItem])
forall a b. (a -> b) -> a -> b
$ ParseSettings -> ByteString -> ConduitT () Event m ()
forall (m :: * -> *) i.
MonadThrow m =>
ParseSettings -> ByteString -> ConduitT i Event m ()
parseLBS ParseSettings
forall a. Default a => a
def (Text -> ByteString
forall a b. ConvertUtf8 a b => a -> b
encodeUtf8 Text
text) ConduitT () Event m ()
-> ConduitT Event Void m (FeedDefinition, [FeedItem])
-> ConduitT () Void m (FeedDefinition, [FeedItem])
forall (m :: * -> *) a b c r.
Monad m =>
ConduitT a b m () -> ConduitT b c m r -> ConduitT a c m r
.| [Char]
-> ConduitT Event Void m (Maybe (FeedDefinition, [FeedItem]))
-> ConduitT Event Void m (FeedDefinition, [FeedItem])
forall (m :: * -> *) a.
MonadThrow m =>
[Char] -> m (Maybe a) -> m a
XML.force [Char]
"Invalid feed" ConduitT Event Void m (Maybe (FeedDefinition, [FeedItem]))
forall (m :: * -> *) o.
MonadCatch m =>
ConduitT Event o m (Maybe (FeedDefinition, [FeedItem]))
feedC
parseAtomFeed ∷ AtomFeed → (FeedDefinition, [FeedItem])
parseAtomFeed :: AtomFeed -> (FeedDefinition, [FeedItem])
parseAtomFeed AtomFeed
feed = (FeedDefinition
definition, [FeedItem]
items)
where
definition :: FeedDefinition
definition = Text -> FeedDefinition
FeedDefinition (Doc Any -> Text
forall b a. (Show a, IsString b) => a -> b
show (Doc Any -> Text) -> Doc Any -> Text
forall a b. (a -> b) -> a -> b
$ AtomText -> Doc Any
forall a. AtomText -> Doc a
prettyAtomText (AtomText -> Doc Any) -> AtomText -> Doc Any
forall a b. (a -> b) -> a -> b
$ AtomFeed -> AtomText
feedTitle AtomFeed
feed)
items :: [FeedItem]
items = AtomEntry -> FeedItem
parseAtomItem (AtomEntry -> FeedItem) -> [AtomEntry] -> [FeedItem]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> AtomFeed -> [AtomEntry]
feedEntries AtomFeed
feed
parseRssFeed ∷ RssDocument (ContentModule (DublinCoreModule NoExtensions)) → (FeedDefinition, [FeedItem])
RssDocument (ContentModule (DublinCoreModule NoExtensions))
doc = (FeedDefinition
definition, [FeedItem]
items)
where
definition :: FeedDefinition
definition = Text -> FeedDefinition
FeedDefinition (RssDocument (ContentModule (DublinCoreModule NoExtensions)) -> Text
forall extensions. RssDocument extensions -> Text
channelTitle RssDocument (ContentModule (DublinCoreModule NoExtensions))
doc)
items :: [FeedItem]
items = RssItem (ContentModule (DublinCoreModule NoExtensions)) -> FeedItem
parseRssItem (RssItem (ContentModule (DublinCoreModule NoExtensions))
-> FeedItem)
-> [RssItem (ContentModule (DublinCoreModule NoExtensions))]
-> [FeedItem]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> RssDocument (ContentModule (DublinCoreModule NoExtensions))
-> [RssItem (ContentModule (DublinCoreModule NoExtensions))]
forall extensions. RssDocument extensions -> [RssItem extensions]
channelItems RssDocument (ContentModule (DublinCoreModule NoExtensions))
doc
feedC ∷ MonadCatch m ⇒ ConduitT Event o m (Maybe (FeedDefinition, [FeedItem]))
feedC :: forall (m :: * -> *) o.
MonadCatch m =>
ConduitT Event o m (Maybe (FeedDefinition, [FeedItem]))
feedC = [ConduitT Event o m (Maybe (FeedDefinition, [FeedItem]))]
-> ConduitT Event o m (Maybe (FeedDefinition, [FeedItem]))
forall (m :: * -> *) o a.
Monad m =>
[ConduitT Event o m (Maybe a)] -> ConduitT Event o m (Maybe a)
choose [ConduitT Event o m (Maybe (FeedDefinition, [FeedItem]))
forall {o}. ConduitT Event o m (Maybe (FeedDefinition, [FeedItem]))
atom, ConduitT Event o m (Maybe (FeedDefinition, [FeedItem]))
forall {o}. ConduitT Event o m (Maybe (FeedDefinition, [FeedItem]))
rss, ConduitT Event o m (Maybe (FeedDefinition, [FeedItem]))
forall {o}. ConduitT Event o m (Maybe (FeedDefinition, [FeedItem]))
rss1]
where
atom :: ConduitT Event o m (Maybe (FeedDefinition, [FeedItem]))
atom = (AtomFeed -> (FeedDefinition, [FeedItem]))
-> Maybe AtomFeed -> Maybe (FeedDefinition, [FeedItem])
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap AtomFeed -> (FeedDefinition, [FeedItem])
parseAtomFeed (Maybe AtomFeed -> Maybe (FeedDefinition, [FeedItem]))
-> ConduitT Event o m (Maybe AtomFeed)
-> ConduitT Event o m (Maybe (FeedDefinition, [FeedItem]))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ConduitT Event o m (Maybe AtomFeed)
forall (m :: * -> *) o.
MonadThrow m =>
ConduitM Event o m (Maybe AtomFeed)
atomFeed
rss :: ConduitT Event o m (Maybe (FeedDefinition, [FeedItem]))
rss = (RssDocument (ContentModule (DublinCoreModule NoExtensions))
-> (FeedDefinition, [FeedItem]))
-> Maybe
(RssDocument (ContentModule (DublinCoreModule NoExtensions)))
-> Maybe (FeedDefinition, [FeedItem])
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap RssDocument (ContentModule (DublinCoreModule NoExtensions))
-> (FeedDefinition, [FeedItem])
parseRssFeed (Maybe
(RssDocument (ContentModule (DublinCoreModule NoExtensions)))
-> Maybe (FeedDefinition, [FeedItem]))
-> ConduitT
Event
o
m
(Maybe
(RssDocument (ContentModule (DublinCoreModule NoExtensions))))
-> ConduitT Event o m (Maybe (FeedDefinition, [FeedItem]))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ConduitT
Event
o
m
(Maybe
(RssDocument (ContentModule (DublinCoreModule NoExtensions))))
forall e (m :: * -> *) o.
(ParseRssExtension e, MonadThrow m) =>
ConduitM Event o m (Maybe (RssDocument e))
rssDocument
rss1 :: ConduitT Event o m (Maybe (FeedDefinition, [FeedItem]))
rss1 = (RssDocument (ContentModule (DublinCoreModule NoExtensions))
-> (FeedDefinition, [FeedItem]))
-> Maybe
(RssDocument (ContentModule (DublinCoreModule NoExtensions)))
-> Maybe (FeedDefinition, [FeedItem])
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap RssDocument (ContentModule (DublinCoreModule NoExtensions))
-> (FeedDefinition, [FeedItem])
parseRssFeed (Maybe
(RssDocument (ContentModule (DublinCoreModule NoExtensions)))
-> Maybe (FeedDefinition, [FeedItem]))
-> ConduitT
Event
o
m
(Maybe
(RssDocument (ContentModule (DublinCoreModule NoExtensions))))
-> ConduitT Event o m (Maybe (FeedDefinition, [FeedItem]))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ConduitT
Event
o
m
(Maybe
(RssDocument (ContentModule (DublinCoreModule NoExtensions))))
forall e (m :: * -> *) o.
(ParseRssExtension e, MonadCatch m) =>
ConduitM Event o m (Maybe (RssDocument e))
rss1Document
parseFeedItem ∷ MonadCatch m ⇒ Text → m FeedItem
parseFeedItem :: forall (m :: * -> *). MonadCatch m => Text -> m FeedItem
parseFeedItem Text
text = ConduitT () Void m FeedItem -> m FeedItem
forall (m :: * -> *) r. Monad m => ConduitT () Void m r -> m r
runConduit (ConduitT () Void m FeedItem -> m FeedItem)
-> ConduitT () Void m FeedItem -> m FeedItem
forall a b. (a -> b) -> a -> b
$ ParseSettings -> ByteString -> ConduitT () Event m ()
forall (m :: * -> *) i.
MonadThrow m =>
ParseSettings -> ByteString -> ConduitT i Event m ()
parseLBS ParseSettings
forall a. Default a => a
def (Text -> ByteString
forall a b. ConvertUtf8 a b => a -> b
encodeUtf8 Text
text) ConduitT () Event m ()
-> ConduitT Event Void m FeedItem -> ConduitT () Void m FeedItem
forall (m :: * -> *) a b c r.
Monad m =>
ConduitT a b m () -> ConduitT b c m r -> ConduitT a c m r
.| [Char]
-> ConduitT Event Void m (Maybe FeedItem)
-> ConduitT Event Void m FeedItem
forall (m :: * -> *) a.
MonadThrow m =>
[Char] -> m (Maybe a) -> m a
XML.force [Char]
"Invalid feed element" ([ConduitT Event Void m (Maybe FeedItem)]
-> ConduitT Event Void m (Maybe FeedItem)
forall (m :: * -> *) o a.
Monad m =>
[ConduitT Event o m (Maybe a)] -> ConduitT Event o m (Maybe a)
choose [(AtomEntry -> FeedItem) -> Maybe AtomEntry -> Maybe FeedItem
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap AtomEntry -> FeedItem
parseAtomItem (Maybe AtomEntry -> Maybe FeedItem)
-> ConduitT Event Void m (Maybe AtomEntry)
-> ConduitT Event Void m (Maybe FeedItem)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ConduitT Event Void m (Maybe AtomEntry)
forall (m :: * -> *) o.
MonadThrow m =>
ConduitM Event o m (Maybe AtomEntry)
atomEntry, (RssItem (ContentModule (DublinCoreModule NoExtensions))
-> FeedItem)
-> Maybe (RssItem (ContentModule (DublinCoreModule NoExtensions)))
-> Maybe FeedItem
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap RssItem (ContentModule (DublinCoreModule NoExtensions)) -> FeedItem
parseRssItem (Maybe (RssItem (ContentModule (DublinCoreModule NoExtensions)))
-> Maybe FeedItem)
-> ConduitT
Event
Void
m
(Maybe (RssItem (ContentModule (DublinCoreModule NoExtensions))))
-> ConduitT Event Void m (Maybe FeedItem)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ConduitT
Event
Void
m
(Maybe (RssItem (ContentModule (DublinCoreModule NoExtensions))))
forall e (m :: * -> *) o.
(ParseRssExtension e, MonadThrow m) =>
ConduitM Event o m (Maybe (RssItem e))
rssItem, (RssItem (ContentModule (DublinCoreModule NoExtensions))
-> FeedItem)
-> Maybe (RssItem (ContentModule (DublinCoreModule NoExtensions)))
-> Maybe FeedItem
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap RssItem (ContentModule (DublinCoreModule NoExtensions)) -> FeedItem
parseRssItem (Maybe (RssItem (ContentModule (DublinCoreModule NoExtensions)))
-> Maybe FeedItem)
-> ConduitT
Event
Void
m
(Maybe (RssItem (ContentModule (DublinCoreModule NoExtensions))))
-> ConduitT Event Void m (Maybe FeedItem)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ConduitT
Event
Void
m
(Maybe (RssItem (ContentModule (DublinCoreModule NoExtensions))))
forall e (m :: * -> *) o.
(ParseRssExtension e, MonadCatch m) =>
ConduitM Event o m (Maybe (RssItem e))
rss1Item])
parseAtomItem ∷ AtomEntry → FeedItem
parseAtomItem :: AtomEntry -> FeedItem
parseAtomItem AtomEntry
entry = Maybe UTCTime
-> Text -> Text -> [Link] -> Text -> [Author] -> FeedItem
FeedItem Maybe UTCTime
date Text
title Text
content [Link]
links Text
identifier [Author]
authors
where
date :: Maybe UTCTime
date = UTCTime -> Maybe UTCTime
forall a. a -> Maybe a
Just (UTCTime -> Maybe UTCTime) -> UTCTime -> Maybe UTCTime
forall a b. (a -> b) -> a -> b
$ AtomEntry -> UTCTime
entryUpdated AtomEntry
entry
title :: Text
title = Doc Any -> Text
forall b a. (Show a, IsString b) => a -> b
show (Doc Any -> Text) -> Doc Any -> Text
forall a b. (a -> b) -> a -> b
$ AtomText -> Doc Any
forall a. AtomText -> Doc a
prettyAtomText (AtomText -> Doc Any) -> AtomText -> Doc Any
forall a b. (a -> b) -> a -> b
$ AtomEntry -> AtomText
entryTitle AtomEntry
entry
content :: Text
content = Text -> Maybe Text -> Text
forall a. a -> Maybe a -> a
fromMaybe Text
"<empty>" (Maybe Text -> Text) -> Maybe Text -> Text
forall a b. (a -> b) -> a -> b
$ Maybe Text
rawContent Maybe Text -> Maybe Text -> Maybe Text
forall a. Maybe a -> Maybe a -> Maybe a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Maybe Text
summary
rawContent :: Maybe Text
rawContent = Doc Any -> Text
forall b a. (Show a, IsString b) => a -> b
show (Doc Any -> Text)
-> (AtomContent -> Doc Any) -> AtomContent -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AtomContent -> Doc Any
forall a. AtomContent -> Doc a
prettyAtomContent (AtomContent -> Text) -> Maybe AtomContent -> Maybe Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> AtomEntry -> Maybe AtomContent
entryContent AtomEntry
entry
summary :: Maybe Text
summary = Doc Any -> Text
forall b a. (Show a, IsString b) => a -> b
show (Doc Any -> Text) -> (AtomText -> Doc Any) -> AtomText -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AtomText -> Doc Any
forall a. AtomText -> Doc a
prettyAtomText (AtomText -> Text) -> Maybe AtomText -> Maybe Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> AtomEntry -> Maybe AtomText
entrySummary AtomEntry
entry
links :: [Link]
links = AtomLink -> Link
parseLink (AtomLink -> Link) -> [AtomLink] -> [Link]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> AtomEntry -> [AtomLink]
entryLinks AtomEntry
entry
parseLink :: AtomLink -> Link
parseLink AtomLink
link = Maybe Relation -> Text -> Maybe MediaType -> AnyURI -> Link
Link (Relation -> Maybe Relation
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Relation -> Maybe Relation) -> Relation -> Maybe Relation
forall a b. (a -> b) -> a -> b
$ Relation -> Maybe Relation -> Relation
forall a. a -> Maybe a -> a
fromMaybe Relation
Alternate (Maybe Relation -> Relation) -> Maybe Relation -> Relation
forall a b. (a -> b) -> a -> b
$ Text -> Maybe Relation
parseRelation (Text -> Maybe Relation) -> Text -> Maybe Relation
forall a b. (a -> b) -> a -> b
$ AtomLink -> Text
linkRel AtomLink
link) (AtomLink -> Text
linkTitle AtomLink
link) (Text -> Maybe MediaType
forall s. Stream s Identity Char => s -> Maybe MediaType
parseMediaType (Text -> Maybe MediaType) -> Text -> Maybe MediaType
forall a b. (a -> b) -> a -> b
$ AtomLink -> Text
linkType AtomLink
link) ((forall a. URIRef a -> AnyURI) -> AtomURI -> AnyURI
forall b. (forall a. URIRef a -> b) -> AtomURI -> b
withAtomURI URIRef a -> AnyURI
forall a. URIRef a -> AnyURI
AnyURI (AtomURI -> AnyURI) -> AtomURI -> AnyURI
forall a b. (a -> b) -> a -> b
$ AtomLink -> AtomURI
linkHref AtomLink
link)
identifier :: Text
identifier = AtomEntry -> Text
entryId AtomEntry
entry
authors :: [Author]
authors = [Text -> Text -> Maybe AnyURI -> Author
Author (Refined (Not Null) Text -> Text
forall {k} (p :: k) x. Refined p x -> x
unrefine Refined (Not Null) Text
name) Text
email ((forall a. URIRef a -> AnyURI) -> AtomURI -> AnyURI
forall b. (forall a. URIRef a -> b) -> AtomURI -> b
withAtomURI URIRef a -> AnyURI
forall a. URIRef a -> AnyURI
AnyURI (AtomURI -> AnyURI) -> Maybe AtomURI -> Maybe AnyURI
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe AtomURI
uri) | AtomPerson Refined (Not Null) Text
name Text
email Maybe AtomURI
uri ← AtomEntry -> [AtomPerson]
entryAuthors AtomEntry
entry]
parseRssItem ∷ RssItem (ContentModule (DublinCoreModule NoExtensions)) → FeedItem
RssItem (ContentModule (DublinCoreModule NoExtensions))
item = Maybe UTCTime
-> Text -> Text -> [Link] -> Text -> [Author] -> FeedItem
FeedItem Maybe UTCTime
date Text
title Text
content [Link]
links Text
identifier [Author]
authors
where
date :: Maybe UTCTime
date = RssItem (ContentModule (DublinCoreModule NoExtensions))
-> Maybe UTCTime
forall extensions. RssItem extensions -> Maybe UTCTime
itemPubDate RssItem (ContentModule (DublinCoreModule NoExtensions))
item Maybe UTCTime -> Maybe UTCTime -> Maybe UTCTime
forall a. Maybe a -> Maybe a -> Maybe a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (RssItem (ContentModule (DublinCoreModule NoExtensions))
item RssItem (ContentModule (DublinCoreModule NoExtensions))
-> (RssItem (ContentModule (DublinCoreModule NoExtensions))
-> RssItemExtension
(ContentModule (DublinCoreModule NoExtensions)))
-> RssItemExtension (ContentModule (DublinCoreModule NoExtensions))
forall a b. a -> (a -> b) -> b
& RssItem (ContentModule (DublinCoreModule NoExtensions))
-> RssItemExtension (ContentModule (DublinCoreModule NoExtensions))
forall extensions.
RssItem extensions -> RssItemExtension extensions
itemExtensions RssItemExtension (ContentModule (DublinCoreModule NoExtensions))
-> (RssItemExtension
(ContentModule (DublinCoreModule NoExtensions))
-> RssItemExtension (DublinCoreModule NoExtensions))
-> RssItemExtension (DublinCoreModule NoExtensions)
forall a b. a -> (a -> b) -> b
& RssItemExtension (ContentModule (DublinCoreModule NoExtensions))
-> RssItemExtension (DublinCoreModule NoExtensions)
forall a. RssItemExtension (ContentModule a) -> RssItemExtension a
itemContentOther RssItemExtension (DublinCoreModule NoExtensions)
-> (RssItemExtension (DublinCoreModule NoExtensions) -> DcMetaData)
-> DcMetaData
forall a b. a -> (a -> b) -> b
& RssItemExtension (DublinCoreModule NoExtensions) -> DcMetaData
forall a. RssItemExtension (DublinCoreModule a) -> DcMetaData
itemDcMetaData DcMetaData -> (DcMetaData -> Maybe UTCTime) -> Maybe UTCTime
forall a b. a -> (a -> b) -> b
& DcMetaData -> Maybe UTCTime
elementDate)
title :: Text
title = RssItem (ContentModule (DublinCoreModule NoExtensions)) -> Text
forall extensions. RssItem extensions -> Text
itemTitle RssItem (ContentModule (DublinCoreModule NoExtensions))
item
content :: Text
content = if Bool -> Bool
not (Text -> Bool
Text.null Text
rawContent) then Text
rawContent else RssItem (ContentModule (DublinCoreModule NoExtensions)) -> Text
forall extensions. RssItem extensions -> Text
itemDescription RssItem (ContentModule (DublinCoreModule NoExtensions))
item
rawContent :: Text
rawContent = RssItem (ContentModule (DublinCoreModule NoExtensions))
item RssItem (ContentModule (DublinCoreModule NoExtensions))
-> (RssItem (ContentModule (DublinCoreModule NoExtensions))
-> RssItemExtension
(ContentModule (DublinCoreModule NoExtensions)))
-> RssItemExtension (ContentModule (DublinCoreModule NoExtensions))
forall a b. a -> (a -> b) -> b
& RssItem (ContentModule (DublinCoreModule NoExtensions))
-> RssItemExtension (ContentModule (DublinCoreModule NoExtensions))
forall extensions.
RssItem extensions -> RssItemExtension extensions
itemExtensions RssItemExtension (ContentModule (DublinCoreModule NoExtensions))
-> (RssItemExtension
(ContentModule (DublinCoreModule NoExtensions))
-> Text)
-> Text
forall a b. a -> (a -> b) -> b
& RssItemExtension (ContentModule (DublinCoreModule NoExtensions))
-> Text
forall a. RssItemExtension (ContentModule a) -> Text
itemContent
links :: [Link]
links = [Maybe Relation -> Text -> Maybe MediaType -> AnyURI -> Link
Link (Relation -> Maybe Relation
forall a. a -> Maybe a
Just Relation
Alternate) Text
forall a. Monoid a => a
mempty Maybe MediaType
forall a. Maybe a
forall (m :: * -> *) a. MonadPlus m => m a
mzero ((forall a. URIRef a -> AnyURI) -> RssURI -> AnyURI
forall b. (forall a. URIRef a -> b) -> RssURI -> b
withRssURI URIRef a -> AnyURI
forall a. URIRef a -> AnyURI
AnyURI RssURI
uri) | RssURI
uri ← Maybe RssURI -> [RssURI]
forall a. Maybe a -> [a]
maybeToList (Maybe RssURI -> [RssURI]) -> Maybe RssURI -> [RssURI]
forall a b. (a -> b) -> a -> b
$ RssItem (ContentModule (DublinCoreModule NoExtensions))
-> Maybe RssURI
forall extensions. RssItem extensions -> Maybe RssURI
itemLink RssItem (ContentModule (DublinCoreModule NoExtensions))
item]
identifier :: Text
identifier = RssItem (ContentModule (DublinCoreModule NoExtensions))
-> Maybe RssGuid
forall extensions. RssItem extensions -> Maybe RssGuid
itemGuid RssItem (ContentModule (DublinCoreModule NoExtensions))
item Maybe RssGuid -> (RssGuid -> Doc Any) -> Maybe (Doc Any)
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> RssGuid -> Doc Any
forall a. RssGuid -> Doc a
prettyGuid Maybe (Doc Any) -> (Maybe (Doc Any) -> Text) -> Text
forall a b. a -> (a -> b) -> b
& Text -> (Doc Any -> Text) -> Maybe (Doc Any) -> Text
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Text
forall a. Monoid a => a
mempty Doc Any -> Text
forall b a. (Show a, IsString b) => a -> b
show
authors :: [Author]
authors = [Text -> Text -> Maybe AnyURI -> Author
Author (RssItem (ContentModule (DublinCoreModule NoExtensions)) -> Text
forall extensions. RssItem extensions -> Text
itemAuthor RssItem (ContentModule (DublinCoreModule NoExtensions))
item) Text
forall a. Monoid a => a
mempty Maybe AnyURI
forall a. Maybe a
forall (m :: * -> *) a. MonadPlus m => m a
mzero]
getMainLink ∷ FeedItem → Maybe Link
getMainLink :: FeedItem -> Maybe Link
getMainLink FeedItem
item = FeedItem -> [Link]
_itemLinks FeedItem
item [Link] -> ([Link] -> [Link]) -> [Link]
forall a b. a -> (a -> b) -> b
& (Link -> Bool) -> [Link] -> [Link]
forall a. (a -> Bool) -> [a] -> [a]
filter (\Link
l → Link -> Maybe Relation
_linkRelation Link
l Maybe Relation -> Maybe Relation -> Bool
forall a. Eq a => a -> a -> Bool
== Relation -> Maybe Relation
forall a. a -> Maybe a
Just Relation
Alternate) [Link] -> ([Link] -> Maybe Link) -> Maybe Link
forall a b. a -> (a -> b) -> b
& [Link] -> Maybe Link
forall a. [a] -> Maybe a
headMay
haveSameIdentifier ∷ FeedItem → FeedItem → Maybe Bool
haveSameIdentifier :: FeedItem -> FeedItem -> Maybe Bool
haveSameIdentifier FeedItem
item1 FeedItem
item2 = case (FeedItem -> Text
_itemIdentifier FeedItem
item1, FeedItem -> Text
_itemIdentifier FeedItem
item2) of
(Text
"", Text
"") → Maybe Bool
forall a. Maybe a
Nothing
(Text
a, Text
b) → Bool -> Maybe Bool
forall a. a -> Maybe a
Just (Text
a Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
b)
haveSameLink ∷ FeedItem → FeedItem → Maybe Bool
haveSameLink :: FeedItem -> FeedItem -> Maybe Bool
haveSameLink FeedItem
item1 FeedItem
item2 = case (FeedItem -> Maybe Link
getMainLink FeedItem
item1, FeedItem -> Maybe Link
getMainLink FeedItem
item2) of
(Just Link
a, Just Link
b) → Bool -> Maybe Bool
forall a. a -> Maybe a
Just (Link
a Link -> Link -> Bool
forall a. Eq a => a -> a -> Bool
== Link
b)
(Maybe Link
Nothing, Maybe Link
Nothing) → Maybe Bool
forall a. Maybe a
Nothing
(Maybe Link, Maybe Link)
_ → Bool -> Maybe Bool
forall a. a -> Maybe a
Just Bool
False
haveSameTitle ∷ FeedItem → FeedItem → Maybe Bool
haveSameTitle :: FeedItem -> FeedItem -> Maybe Bool
haveSameTitle FeedItem
item1 FeedItem
item2 = case (FeedItem -> Text
_itemTitle FeedItem
item1, FeedItem -> Text
_itemTitle FeedItem
item2) of
(Text
"" ∷ Text, Text
"" ∷ Text) → Maybe Bool
forall a. Maybe a
Nothing
(Text
a, Text
b) → Bool -> Maybe Bool
forall a. a -> Maybe a
Just (Text
a Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
b)
areSameItem ∷ FeedItem → FeedItem → Bool
areSameItem :: FeedItem -> FeedItem -> Bool
areSameItem FeedItem
a FeedItem
b = Bool -> Maybe Bool -> Bool
forall a. a -> Maybe a -> a
fromMaybe ((FeedItem -> Text) -> FeedItem -> FeedItem -> Ordering
forall a b. Ord a => (b -> a) -> b -> b -> Ordering
comparing FeedItem -> Text
_itemContent FeedItem
a FeedItem
b Ordering -> Ordering -> Bool
forall a. Eq a => a -> a -> Bool
== Ordering
EQ) (Maybe Bool -> Bool) -> Maybe Bool -> Bool
forall a b. (a -> b) -> a -> b
$ FeedItem -> FeedItem -> Maybe Bool
haveSameIdentifier FeedItem
a FeedItem
b Maybe Bool -> Maybe Bool -> Maybe Bool
forall a. Maybe a -> Maybe a -> Maybe a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> FeedItem -> FeedItem -> Maybe Bool
haveSameLink FeedItem
a FeedItem
b Maybe Bool -> Maybe Bool -> Maybe Bool
forall a. Maybe a -> Maybe a -> Maybe a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> FeedItem -> FeedItem -> Maybe Bool
haveSameTitle FeedItem
a FeedItem
b