-
Notifications
You must be signed in to change notification settings - Fork 0
/
podcastoftheday.hs
60 lines (47 loc) · 2.35 KB
/
podcastoftheday.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
{-# LANGUAGE OverloadedStrings #-}
import Data.List
import Data.Maybe
import Data.String
import Network.HTTP
import Network.URI
import System.Directory
import System.Environment
import System.FilePath
import qualified Data.ByteString.Lazy as L
openURL :: (HStream s, IsString s) => String -> IO s
openURL x = simpleHTTP (Request (fromJust $ parseURI x) GET [] "") >>= getResponseBody
potdURL :: String
potdURL = "http://www.bbc.co.uk/podcasts/series/podcastoftheday"
potdPrefix :: String
potdPrefix = "http://downloads.bbc.co.uk/podcasts/worldservice/podcastoftheday/podcastoftheday_"
findPodcasts :: String -> [String]
findPodcasts [] = []
findPodcasts s = case stripPrefix potdPrefix s of
(Just s') -> let (ident, rest) = helper s' in ident : findPodcasts rest
Nothing -> findPodcasts $ tail s
where helper [] = error "unexpected end of link name in function findPocasts"
helper ('.':'m':'p':'3':s'') = ([], s'')
helper (c:s'') = let (ident, rest) = helper s'' in (c:ident, rest)
toURL :: String -> String
toURL ident = podcastPrefix ++ ident ++ ".mp3"
toFilename :: String -> String
toFilename ident = let (year, rest) = splitAt 4 ident
(month, rest') = splitAt 2 rest
(day , _) = splitAt 2 rest'
in concat $ intersperse "_" ["新闻播客", day, month, year ++ ".mp3"]
filterNew :: FilePath -> [String] -> IO [String]
filterNew directory idents = do createDirectoryIfMissing True directory
old <- getDirectoryContents directory
return $ filter (not . (`elem` old) . toFilename) idents
allPodcastIdents :: IO [String]
allPodcastIdents = fmap findPodcasts $ openURL potdURL
slash :: String -> String -> String
directory `slash` filename = let directory' = helper directory last init
filename' = helper filename head tail
in directory' ++ pathSeparator : filename'
where helper s f g = if f s == pathSeparator then g s else s
main :: IO ()
main = do [directory] <- getArgs
idents <- allPodcastIdents >>= filterNew directory
bodies <- mapM (openURL . toURL) idents
mapM_ (\(ident, body) -> L.writeFile (directory `slash` toFilename ident) body) $ zip idents bodies