packages feed

hackage2hwn-0.3: Main.hs

--------------------------------------------------------------------
-- |
-- Module    : hackage2hwn
-- Copyright : (c) Galois, Inc. 2007
-- License   : BSD3
--
-- Maintainer: Don Stewart <dons@galois.com>
-- Stability : provisional
--
-- Pulls the RSS feed from Hackage, pretty prints it in a form suitable for
-- inclusion in the Haskell Weekly News.
--
--------------------------------------------------------------------

module Main (main) where

import Text.XML.Light
import Data.Maybe
import Data.List
import Data.Char

import Debug.Trace
import System.FilePath
import Text.HTML.Download
import Text.HTML.TagSoup
import Control.Applicative

url = "http://hackage.haskell.org/packages/archive/recent.rss"

main = do
    putStrLn "'''Recent Package Updates'''\n"
    mapM_ ppr . render . parseXMLDoc =<< openURL url
    putStrLn $ " [http://hackage.haskell.org/packages/archive/pkg-list.html More...]\n[http://hackage.haskell.org/packages/archive/recent.rss RSS]"

-- pretty print in human readable format
ppr (HackageItem title url _ _ synopsis) = putStrLn $
  unlines
    [(";" ++ "[" ++ url ++ " "++  title ++ "]")
    ,(":" ++ synopsis)]


-- parse xml into hackage items
render Nothing  = error "Unable to download hackage"
render (Just e) = map process items
    where v    = elContent e
          [es]      = [ x | Elem x <- v ]
          body      = elContent es
          items    = map onlyElems [ (elContent e) | Elem e <- drop 10 body ]


          process xs@[a,b,c,d,e] =
                HackageItem proj
                            projurl
                            name
                            author
                            synopsis
             where
               proj     = strContent a
               projurl  = strContent b
               name     = takeFileName projurl
               descr    = strContent e
               author   =
                    let (h:rest) =
                            reverse . takeWhile ( not . isSpace) . reverse
                                      . takeWhile (/= ',')
                                      $ head [ e |  TagText e <- parseTags descr ]

                        (first,last) = break isUpper rest
                    in (h:first ++ " " ++ last)

               synopsis = last [ e |  TagText e <- parseTags descr ]

-- hackage items in the haskell weekly news
data HackageItem =
    HackageItem
        Title
        Url
        CanonicalName
        Author
        Body

type Title         = String
type Url           = String
type Author        = String
type CanonicalName = String
type Body          = String