ad-alta-voce/src/Command/All.hs

82 lines
3.0 KiB
Haskell

{-|
Module : Command.All
Description : Generate podcast for all audiobooks
Copyright : (c) Raffaele Mignone 2021
License : GPL-3
Maintainer : git@norangeb.it
This module exposes the command that generates podcast feeds for all the
audiobooks in Ad Alta Voce library.
-}
module Command.All(generateAll) where
import Control.Monad ( join )
import Data.Text (unpack)
import Data.Maybe ( catMaybes )
import Text.Mustache
import Text.Parsec.Error ( ParseError )
import System.Directory ( createDirectoryIfMissing )
import System.IO
import Text.HTML.Scalpel ( scrapeURL, URL )
import Command.Single ( singleWithAuthor )
import Paths_ad_alta_voce ( getDataFileName )
import Scraper.Playlist
( playlistPageNumbersScraper, playlistInfosScraper )
import Types
baseUrl = "https://www.raiplayradio.it"
playlistBaseUrl = "https://www.raiplayradio.it/programmi/adaltavoce/archivio/audiolibri/tutte/"
scrapeAudiobooksUrl :: IO (Maybe [(URL, String)])
scrapeAudiobooksUrl = do
pageNumbers <- scrapeURL playlistBaseUrl playlistPageNumbersScraper
case scrapePlaylistPages pageNumbers of
Nothing -> return Nothing
Just urls -> Just <$> urls
scrapePlaylistPages :: Maybe [String] -> Maybe (IO [(URL, String)])
scrapePlaylistPages pageNumbers = do
pageNumbers' <- pageNumbers
let playlistUrls = map (playlistBaseUrl ++) pageNumbers'
audiobookInfos = mapM (`scrapeURL` playlistInfosScraper) playlistUrls
flatAudiobookInfos = join . catMaybes <$> audiobookInfos
return $ map (\(u, a) -> (concatBaseUrl u, a)) <$> flatAudiobookInfos
where
concatBaseUrl :: URL -> URL
concatBaseUrl = (++) baseUrl
writeIndex :: [Maybe Podcast] -> String -> String -> IO ()
writeIndex podcasts templateName outdir = do
let index = Index $ catMaybes podcasts
template <- compileIndexTemplate templateName
writeIndexTemplate template index outputFile outdir
where
outputFile = outdir ++ "/" ++ take (length templateName - 9) templateName
compileIndexTemplate :: String -> IO (Either ParseError Template)
compileIndexTemplate templateName = do
templateDir <- getDataFileName "templates"
automaticCompile [".", templateDir] templateName
writeIndexTemplate :: Either ParseError Template -> Index -> String -> String -> IO ()
writeIndexTemplate (Left err) _ _ _ = print err
writeIndexTemplate (Right template) index fileName outdir = do
createDirectoryIfMissing True outdir
withFile fileName WriteMode (\handle -> do
hPutStr handle $ unpack indexContent
putStrLn "Index done!\nAll done, enjoy your books!")
where
indexContent = substitute template index
generateAll :: String -> Bool -> String -> IO ()
generateAll outdir indexMode indexTemplate = do
infos <- scrapeAudiobooksUrl
case infos of
Nothing -> putStrLn "Error"
Just infos' -> do
podcasts <- mapM (\(url, author) -> singleWithAuthor url outdir author) infos'
if indexMode
then writeIndex podcasts indexTemplate outdir
else putStrLn "All done.\nEnjoy your books!"