Add author to podcast template

This commit is contained in:
Raffaele Mignone 2021-01-24 19:11:10 +01:00
parent 549aec021e
commit 9690477272
Signed by: norangebit
GPG Key ID: F5255658CB220573
6 changed files with 67 additions and 27 deletions

View File

@ -10,8 +10,8 @@
<description>{{audiobook-description}}</description>
<language>it-it</language>
<lastBuildDate>{{pub-day}}</lastBuildDate>
<itunes:author>Ad Alta Voce - Rai Radio 3</itunes:author>
<itunes:summary>{{audiobook-description}}</itunes:summary>
<itunes:author>{{audiobook-author}}</itunes:author>
<itunes:summary>{{audiobook-summary}}</itunes:summary>
<itunes:subtitle>Ad Alta Voce</itunes:subtitle>
<itunes:explicit>No</itunes:explicit>
<itunes:image href="https://www.raiplayradio.it/{{audiobook-cover-url}}"/>

View File

@ -14,33 +14,36 @@ module Command.All(generateAll) where
import Control.Monad ( join )
import Data.Maybe ( catMaybes )
import Text.HTML.Scalpel ( scrapeURL, URL )
import Command.Single ( single )
import Command.Single ( singleWithAuthor )
import Scraper.Playlist
( playlistPageNumbersScraper, playlistsUrlScraper )
( playlistPageNumbersScraper, playlistInfosScraper )
baseUrl = "https://www.raiplayradio.it"
playlistBaseUrl = "https://www.raiplayradio.it/programmi/adaltavoce/archivio/audiolibri/tutte/"
scrapeAudiobooksUrl :: IO (Maybe [URL])
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])
scrapePlaylistPages :: Maybe [String] -> Maybe (IO [(URL, String)])
scrapePlaylistPages pageNumbers = do
pageNumbers' <- pageNumbers
let playlistUrls = map (playlistBaseUrl ++) pageNumbers'
audiobookUrls = mapM (`scrapeURL` playlistsUrlScraper) playlistUrls
flatAudiobookUrls = join . catMaybes <$> audiobookUrls
return $ map (baseUrl ++) <$> flatAudiobookUrls
audiobookInfos = mapM (`scrapeURL` playlistInfosScraper) playlistUrls
flatAudiobookInfos = join . catMaybes <$> audiobookInfos
return $ map (\(u, a) -> (concatBaseUrl u, a)) <$> flatAudiobookInfos
where
concatBaseUrl :: URL -> URL
concatBaseUrl = (++) baseUrl
generateAll :: String -> IO ()
generateAll outdir = do
urls <- scrapeAudiobooksUrl
case urls of
infos <- scrapeAudiobooksUrl
case infos of
Nothing -> putStrLn "Error"
Just urls' -> do
mapM_ (`single` outdir) urls'
Just infos' -> do
mapM_ (\(url, author) -> singleWithAuthor url outdir author) infos'
putStrLn "All done.\nEnjoy your books!"

View File

@ -9,7 +9,7 @@ This module exposes the command that generates podcast feed for an audiobooks
in Ad Alta Voce library.
-}
module Command.Single(single) where
module Command.Single(single, singleWithAuthor) where
import Data.Text (unpack)
import Data.Time.Clock ( UTCTime(utctDay), getCurrentTime )
@ -46,13 +46,21 @@ writePodcastTemplate (Right template) (Just podcast) outdir = do
fileName = outdir ++ "/" ++ generatePodcastFileName podcast
output = title ++ " done!"
single :: String -> String -> IO ()
single url outdir = do
single' :: Maybe Audiobook -> String -> String -> IO ()
single' audiobook url outdir = do
day <- utctDay <$> getCurrentTime
audiobook <- scrapeAudiobook url
compiled <- compilePodcastTemplate
let podcast = generatePodcast day url <$> audiobook
writePodcastTemplate compiled podcast outdir
single :: String -> String -> IO ()
single url outdir = do
audiobook <- scrapeAudiobook url
single' audiobook url outdir
singleWithAuthor :: String -> String -> String -> IO ()
singleWithAuthor url outdir author = do
audiobook <- scrapeAudiobook url
let abookDescription = (`toAudiobookWithAuthor` author) <$> audiobook
single' abookDescription url outdir

View File

@ -16,7 +16,7 @@ An example of a web page that can be scraped is available at the following
module Scraper.Audiobook(audiobookScraper) where
import Text.HTML.Scalpel
import Types ( Audiobook(Audiobook), Episode(Episode) )
import Types
audiobookHeaderSelector :: Selector
audiobookHeaderSelector = "div" @: [hasClass "descriptionProgramma"]
@ -75,4 +75,4 @@ audiobookScraper = do
description <- audiobookDescriptionScraper
coverUrl <- audiobookCoverUrlScraper
episodes <- episodesListScraper
return $ Audiobook title description coverUrl episodes
return $ makeAudiobook title description coverUrl episodes

View File

@ -14,8 +14,8 @@ An example of a web page that can be scraped is available at the following
{-# LANGUAGE OverloadedStrings #-}
module Scraper.Playlist
( playlistsUrlScraper
, playlistPageNumbersScraper
( playlistPageNumbersScraper
, playlistInfosScraper
) where
import Text.HTML.Scalpel
@ -26,10 +26,22 @@ playlistSelector = "div" @: [hasClass "bloccoPlaylist"]
playlistUrlScraper :: Scraper String String
playlistUrlScraper = attr "href" "a"
playlistAuthorSelector :: Selector
playlistAuthorSelector = "span" @: [hasClass "canale"]
playlistAuthorScraper :: Scraper String String
playlistAuthorScraper = text playlistAuthorSelector
playlistInfoScraper :: Scraper String (String, String)
playlistInfoScraper = do
url <- playlistUrlScraper
author <- playlistAuthorScraper
return (url, author)
-- |The 'playlistUrlScraper' function defines the scraper that retrieves all
-- audiobooks url cointains in the playlist page.
playlistsUrlScraper :: Scraper String [String]
playlistsUrlScraper = chroots playlistSelector playlistUrlScraper
-- audiobooks url and author cointains in the playlist page.
playlistInfosScraper :: Scraper String [(String, String)]
playlistInfosScraper = chroots playlistSelector playlistInfoScraper
playlistPageNumberSelector :: Selector
playlistPageNumberSelector = "ul" @: [hasClass "pagination"]

View File

@ -12,9 +12,12 @@ their fields.
{-# LANGUAGE OverloadedStrings #-}
module Types
( Audiobook(Audiobook)
( Audiobook
, Episode(Episode)
, Podcast(Podcast)
, makeAudiobook
, makeAudiobookWithAuthor
, toAudiobookWithAuthor
, generatePodcast
, episodeUrl
, episodeTitle
@ -25,6 +28,7 @@ module Types
, audiobookDescription
, audiobookCoverUrl
, audiobookEpisodes
, audiobookAuthor
, audiobook
, baseUrl
, pubDay
@ -49,12 +53,23 @@ data Episode = Episode { episodeUrl :: String
-- | The 'Audiobook' data type represents the audiobook of the podcast.
-- 'Audiobook' is an istance of 'ToMustache' typeclass.
data Audiobook = Audiobook { audiobookTitle :: String
, audiobookAuthor :: String
, audiobookDescription :: String
, audiobookCoverUrl :: String
, audiobookEpisodes :: [Episode]
}
deriving (Show)
makeAudiobook :: String -> String -> String -> [Episode] -> Audiobook
makeAudiobook title = Audiobook title "Ad Alta Voce - Rai Radio 3"
makeAudiobookWithAuthor :: String -> String -> String -> String -> [Episode] -> Audiobook
makeAudiobookWithAuthor title author = Audiobook title (author ++ " - Ad Alta Voce")
toAudiobookWithAuthor :: Audiobook -> String -> Audiobook
toAudiobookWithAuthor (Audiobook title _ description coverUrl episodes) author =
makeAudiobookWithAuthor title author description coverUrl episodes
-- | The 'Podcast' data type represents the podcast.
-- 'Podcast' is an istance of 'ToMustache' typeclass.
@ -70,6 +85,8 @@ toPairList audiobook =
, "audiobook-cover-url" ~> audiobookCoverUrl audiobook
, "audiobook-cover-title" ~> audiobookTitle audiobook
, "audiobook-description" ~> audiobookDescription audiobook
, "audiobook-summary" ~> audiobookDescription audiobook
, "audiobook-author" ~> audiobookAuthor audiobook
, "episodes" ~> audiobookEpisodes audiobook
]