hablo/src/RSS.hs

96 lines
3.1 KiB
Haskell
Raw Normal View History

2020-03-25 19:47:28 +01:00
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE FlexibleContexts #-}
module RSS (
generate
) where
import Article (Article(..))
import ArticlesList (ArticlesList(..), getArticles)
import qualified ArticlesList (description, path)
import Blog (Blog(urls), Renderer, URLs(..))
import Blog.URL (AbsoluteURL, pathOn)
2020-03-25 19:47:28 +01:00
import Collection (Collection(..), getAll)
import qualified Collection (title)
2020-03-25 19:47:28 +01:00
import Control.Monad.IO.Class (MonadIO(..))
2021-02-21 22:08:36 +01:00
import Control.Monad.Reader (ReaderT, asks)
2020-03-25 19:47:28 +01:00
import Data.Text (Text)
import Data.Map ((!))
import qualified Data.Text.Lazy.IO as TextIO (writeFile)
import Data.Time (defaultTimeLocale, formatTime, rfc822DateFormat)
import Data.Time.Clock.POSIX (posixSecondsToUTCTime)
2021-07-01 09:01:08 +02:00
--import Lucid (Attribute, HtmlT, Term, ToHtml(..), term, renderTextT)
2020-03-25 19:47:28 +01:00
import Lucid.Base (makeAttribute)
import Markdown (Markdown(..))
2020-03-25 19:47:28 +01:00
import Pretty ((.$))
import System.FilePath.Posix ((</>), (<.>))
2021-07-01 09:01:08 +02:00
import Text.Blaze.Html (Html)
2020-03-25 19:47:28 +01:00
2021-07-01 09:01:08 +02:00
prolog :: Monad m => m Html
2020-03-25 19:47:28 +01:00
prolog = toHtmlRaw ("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>" :: String)
version_ :: Text -> Attribute
version_ = makeAttribute "version"
xmlns_content_ :: Text -> Attribute
xmlns_content_ = makeAttribute "xmlns:content"
xmlns_atom_ :: Text -> Attribute
xmlns_atom_ = makeAttribute "xmlns:atom"
rss_ :: Term arg result => arg -> result
rss_ = term "rss"
channel_ :: Term arg result => arg -> result
channel_ = term "channel"
title_ :: Term arg result => arg -> result
title_ = term "title"
link_ :: Term arg result => arg -> result
link_ = term "link"
description_ :: Term arg result => arg -> result
description_ = term "description"
item_ :: Term arg result => arg -> result
item_ = term "item"
pubDate_ :: Term arg result => arg -> result
pubDate_ = term "pubDate"
2021-07-01 09:01:08 +02:00
articleItem :: Monad m => AbsoluteURL -> Article -> m Html
articleItem siteURL (Article (Markdown {path, metadata, title})) =
2020-03-25 19:47:28 +01:00
item_ $ do
title_ $ toHtml title
link_ . toHtml $ pathOn siteURL (path <.> "html")
2020-03-25 19:47:28 +01:00
pubDate_ . toHtml . rfc822Date $ metadata ! "date"
where
rfc822Date =
formatTime defaultTimeLocale rfc822DateFormat
. posixSecondsToUTCTime . fromIntegral . (read :: String -> Int)
2021-07-01 09:01:08 +02:00
feed :: Renderer m => AbsoluteURL -> ArticlesList -> m Html
feed siteURL al@(ArticlesList {collection}) = do
2020-03-25 19:47:28 +01:00
prolog
rss_ [version, content, atom] $ do
channel_ $ do
title_ . toHtml =<< Collection.title collection
link_ . toHtml . pathOn siteURL $ ArticlesList.path al
2020-03-25 19:47:28 +01:00
description_ . toHtml =<< ArticlesList.description al
mapM_ (articleItem siteURL) =<< getArticles al
2020-03-25 19:47:28 +01:00
where
version = version_ "2.0"
content = xmlns_content_ "http://purl.org/rss/1.0/modules/content/"
atom = xmlns_atom_ "http://www.w3.org/2005/Atom"
2021-04-04 17:33:31 +02:00
generateCollection :: AbsoluteURL -> Collection -> ReaderT Blog IO ()
generateCollection siteURL collection =
renderTextT (feed siteURL $ ArticlesList {full = False, collection})
>>= liftIO . TextIO.writeFile (basePath collection </> "rss" <.> "xml")
2020-03-25 19:47:28 +01:00
generate :: ReaderT Blog IO ()
generate = (asks $urls.$rss) >>= maybe (return ()) generateAll
where
generateAll siteURL = Collection.getAll >>= mapM_ (generateCollection siteURL)