packages feed

rezoom-0.0.3: Main.hs

import Network.HTTP
import Network.Stream
import Rezoom.JSON
import Rezoom.Builder
import System.IO
import System.Environment (getArgs)
import System.Console.GetOpt
import Control.Monad (join)
import Control.Applicative ((<$>))
import Control.Monad.Reader
import Paths_rezoom (getDataFileName)
import qualified Data.Map as M

version = "0.0.1"

data Flag = Version |
            Output String |
            Realname String |
            Email String |
            Facebook String |
            Twitter String |
            Username String
            deriving (Show, Eq)

-- Content of the API response
getAPI :: String -> IO String
getAPI username = join $ do
    let url = "http://github.com/api/v2/json/repos/show/" ++ username
    req <- simpleHTTP $ getRequest url
    putStrLn "Connected to API..."
    case req of
        Left err -> do error "Couldn't ping API. Try again later."
        x -> do return $ getResponseBody x
        
options :: [OptDescr Flag]
options = [
            Option ['v'] ["version"] (NoArg Version) "show rezoom's version number and exit",
            Option ['o'] ["output"] (ReqArg Output "FILE") "where to put the generated resume (default ./resume.html)",
            Option ['e'] ["email"] (ReqArg Email "ADDR") "your email address (also needed for your gravatar)",
            Option ['n'] ["name"] (ReqArg Realname "NAME") "your real name",
            Option ['f'] ["facebook"] (ReqArg Facebook "URL") "your Facebook profile URL",
            Option ['t'] ["twitter"] (ReqArg Twitter "URL") "your Twitter URL"
          ]
          
saneOpts :: [Flag] -> [(String, String)]
saneOpts [] = []
saneOpts (x:xs) = flip (:) (saneOpts xs) $ case x of
    Version -> ("version", "")
    Output str -> ("output", str)
    Realname str -> ("realname", str)
    Email str -> ("email", str)
    Facebook str -> ("facebook", str)
    Twitter str -> ("twitter", str)
    Username str -> ("username", str)
    

header :: String
header = "Usage: rezoom [username] [options...]"

main :: IO ()
main = do
    args <- getArgs
    case getOpt Permute options args of
        (flags, [], []) -> if Version `elem` flags then do putStrLn ("rezoom " ++ version)
            else do error $ usageInfo header options
        (_, [], _) -> error $ "Username required!\n" ++ usageInfo header options
        (flags, username:_, []) -> do
            let sane = M.fromList $ saneOpts $ (Username username):flags;
                filename = M.findWithDefault "resume.html" "output" sane
            cssfile <- getDataFileName "Rezoom/rezoom.css"
            css <- readFile cssfile
            json <- parse <$> getAPI username
            case json of
                Left err -> do error "Unable to parse API response, sorry."
                Right res -> do
                    putStrLn "Building resume..."
                    let html = runReader build $ Resume sane res css
                    writeFile filename html
                    putStrLn "All done."
        (_, _, msgs) -> error $ concat msgs ++ usageInfo header options