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