1 --------------------------------------------------------------------
    2 -- |
    3 -- Module    : hackage2hwn
    4 -- Copyright : (c) Galois, Inc. 2007
    5 -- License   : BSD3
    6 --
    7 -- Maintainer: Don Stewart <dons@galois.com>
    8 -- Stability : provisional
    9 --
   10 -- Pulls the RSS feed from Hackage, pretty prints it in a form suitable for
   11 -- inclusion in the Haskell Weekly News.
   12 --
   13 --------------------------------------------------------------------
   14 
   15 module Main (main) where
   16 
   17 import Text.XML.Light
   18 import Data.Maybe
   19 import Data.List
   20 import Data.Char
   21 
   22 import Text.HTML.Download
   23 import Text.HTML.TagSoup
   24 import Control.Applicative
   25 
   26 url = "http://hackage.haskell.org/packages/archive/recent.rss"
   27 
   28 main = mapM_ ppr . render . parseXMLDoc =<< openURL url
   29 
   30 -- pretty print in human readable format
   31 ppr (HackageItem a b c) = putStrLn $
   32     unlines [ "HackageItem"
   33             , show a
   34             , show b
   35             , show c ++ ","
   36             ]
   37 
   38 -- parse xml into hackage items
   39 render Nothing  = error "Unable to download hackage"
   40 render (Just e) = map process items
   41     where v    = elContent e
   42           [es]      = [ x | Elem x <- v ]
   43           body      = elContent es
   44           items    = map onlyElems [ (elContent e) | Elem e <- drop 10 body ]
   45 
   46 
   47           process [a,b,c,d,e] =
   48                 HackageItem proj
   49                             author
   50                             ("[" ++ projurl
   51                                  ++ " "
   52                                  ++ takeWhile (not.isSpace) proj
   53                                  ++ "]: " ++ synopsis ++ "."
   54                             )
   55              where
   56                proj     = strContent a
   57                projurl  = strContent b
   58                descr    = strContent e
   59                author   =
   60                     let (h:rest) =
   61                             reverse . takeWhile ( not . isSpace) . reverse
   62                                       . takeWhile (/= ',')
   63                                       $ head [ e |  TagText e <- parseTags descr ]
   64 
   65                         (first,last) = break isUpper rest
   66                     in (h:first ++ " " ++ last)
   67 
   68                synopsis = last [ e |  TagText e <- parseTags descr ]
   69 
   70 -- hackage items in the haskell weekly news
   71 data HackageItem = HackageItem Title Author Body
   72 type Title  = String
   73 type Author = String
   74 type Body   = String