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> <description>{{audiobook-description}}</description>
<language>it-it</language> <language>it-it</language>
<lastBuildDate>{{pub-day}}</lastBuildDate> <lastBuildDate>{{pub-day}}</lastBuildDate>
<itunes:author>Ad Alta Voce - Rai Radio 3</itunes:author> <itunes:author>{{audiobook-author}}</itunes:author>
<itunes:summary>{{audiobook-description}}</itunes:summary> <itunes:summary>{{audiobook-summary}}</itunes:summary>
<itunes:subtitle>Ad Alta Voce</itunes:subtitle> <itunes:subtitle>Ad Alta Voce</itunes:subtitle>
<itunes:explicit>No</itunes:explicit> <itunes:explicit>No</itunes:explicit>
<itunes:image href="https://www.raiplayradio.it/{{audiobook-cover-url}}"/> <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 Control.Monad ( join )
import Data.Maybe ( catMaybes ) import Data.Maybe ( catMaybes )
import Text.HTML.Scalpel ( scrapeURL, URL ) import Text.HTML.Scalpel ( scrapeURL, URL )
import Command.Single ( single ) import Command.Single ( singleWithAuthor )
import Scraper.Playlist import Scraper.Playlist
( playlistPageNumbersScraper, playlistsUrlScraper ) ( playlistPageNumbersScraper, playlistInfosScraper )
baseUrl = "https://www.raiplayradio.it" baseUrl = "https://www.raiplayradio.it"
playlistBaseUrl = "https://www.raiplayradio.it/programmi/adaltavoce/archivio/audiolibri/tutte/" playlistBaseUrl = "https://www.raiplayradio.it/programmi/adaltavoce/archivio/audiolibri/tutte/"
scrapeAudiobooksUrl :: IO (Maybe [URL]) scrapeAudiobooksUrl :: IO (Maybe [(URL, String)])
scrapeAudiobooksUrl = do scrapeAudiobooksUrl = do
pageNumbers <- scrapeURL playlistBaseUrl playlistPageNumbersScraper pageNumbers <- scrapeURL playlistBaseUrl playlistPageNumbersScraper
case scrapePlaylistPages pageNumbers of case scrapePlaylistPages pageNumbers of
Nothing -> return Nothing Nothing -> return Nothing
Just urls -> Just <$> urls Just urls -> Just <$> urls
scrapePlaylistPages :: Maybe [String] -> Maybe (IO [URL]) scrapePlaylistPages :: Maybe [String] -> Maybe (IO [(URL, String)])
scrapePlaylistPages pageNumbers = do scrapePlaylistPages pageNumbers = do
pageNumbers' <- pageNumbers pageNumbers' <- pageNumbers
let playlistUrls = map (playlistBaseUrl ++) pageNumbers' let playlistUrls = map (playlistBaseUrl ++) pageNumbers'
audiobookUrls = mapM (`scrapeURL` playlistsUrlScraper) playlistUrls audiobookInfos = mapM (`scrapeURL` playlistInfosScraper) playlistUrls
flatAudiobookUrls = join . catMaybes <$> audiobookUrls flatAudiobookInfos = join . catMaybes <$> audiobookInfos
return $ map (baseUrl ++) <$> flatAudiobookUrls return $ map (\(u, a) -> (concatBaseUrl u, a)) <$> flatAudiobookInfos
where
concatBaseUrl :: URL -> URL
concatBaseUrl = (++) baseUrl
generateAll :: String -> IO () generateAll :: String -> IO ()
generateAll outdir = do generateAll outdir = do
urls <- scrapeAudiobooksUrl infos <- scrapeAudiobooksUrl
case urls of case infos of
Nothing -> putStrLn "Error" Nothing -> putStrLn "Error"
Just urls' -> do Just infos' -> do
mapM_ (`single` outdir) urls' mapM_ (\(url, author) -> singleWithAuthor url outdir author) infos'
putStrLn "All done.\nEnjoy your books!" 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. in Ad Alta Voce library.
-} -}
module Command.Single(single) where module Command.Single(single, singleWithAuthor) where
import Data.Text (unpack) import Data.Text (unpack)
import Data.Time.Clock ( UTCTime(utctDay), getCurrentTime ) import Data.Time.Clock ( UTCTime(utctDay), getCurrentTime )
@ -46,13 +46,21 @@ writePodcastTemplate (Right template) (Just podcast) outdir = do
fileName = outdir ++ "/" ++ generatePodcastFileName podcast fileName = outdir ++ "/" ++ generatePodcastFileName podcast
output = title ++ " done!" output = title ++ " done!"
single :: String -> String -> IO () single' :: Maybe Audiobook -> String -> String -> IO ()
single url outdir = do single' audiobook url outdir = do
day <- utctDay <$> getCurrentTime day <- utctDay <$> getCurrentTime
audiobook <- scrapeAudiobook url
compiled <- compilePodcastTemplate compiled <- compilePodcastTemplate
let podcast = generatePodcast day url <$> audiobook let podcast = generatePodcast day url <$> audiobook
writePodcastTemplate compiled podcast outdir 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 module Scraper.Audiobook(audiobookScraper) where
import Text.HTML.Scalpel import Text.HTML.Scalpel
import Types ( Audiobook(Audiobook), Episode(Episode) ) import Types
audiobookHeaderSelector :: Selector audiobookHeaderSelector :: Selector
audiobookHeaderSelector = "div" @: [hasClass "descriptionProgramma"] audiobookHeaderSelector = "div" @: [hasClass "descriptionProgramma"]
@ -75,4 +75,4 @@ audiobookScraper = do
description <- audiobookDescriptionScraper description <- audiobookDescriptionScraper
coverUrl <- audiobookCoverUrlScraper coverUrl <- audiobookCoverUrlScraper
episodes <- episodesListScraper 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 #-} {-# LANGUAGE OverloadedStrings #-}
module Scraper.Playlist module Scraper.Playlist
( playlistsUrlScraper ( playlistPageNumbersScraper
, playlistPageNumbersScraper , playlistInfosScraper
) where ) where
import Text.HTML.Scalpel import Text.HTML.Scalpel
@ -26,10 +26,22 @@ playlistSelector = "div" @: [hasClass "bloccoPlaylist"]
playlistUrlScraper :: Scraper String String playlistUrlScraper :: Scraper String String
playlistUrlScraper = attr "href" "a" 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 -- |The 'playlistUrlScraper' function defines the scraper that retrieves all
-- audiobooks url cointains in the playlist page. -- audiobooks url and author cointains in the playlist page.
playlistsUrlScraper :: Scraper String [String] playlistInfosScraper :: Scraper String [(String, String)]
playlistsUrlScraper = chroots playlistSelector playlistUrlScraper playlistInfosScraper = chroots playlistSelector playlistInfoScraper
playlistPageNumberSelector :: Selector playlistPageNumberSelector :: Selector
playlistPageNumberSelector = "ul" @: [hasClass "pagination"] playlistPageNumberSelector = "ul" @: [hasClass "pagination"]

View File

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