rascal-1.1.6: src/Rascal/API.hs
module Rascal.API where
import Control.Applicative ((<$>))
import Text.Printf (printf)
import Control.Exception (handle)
import Data.Aeson (parseJSON, FromJSON)
import Network.Curl.Aeson (curlAeson, noData, CurlAesonException, errorMsg, curlCode)
import Network.Curl.Opts (CurlOption(CurlUserAgent))
import Network.Curl.Code (CurlCode(CurlOK))
import Rascal.Constants
import Rascal.Types
-- |get posts according to selection in argument's subreddit as a listing
getListing :: String -> String -> Int -> Maybe String -> IO NamedListing
getListing select subreddit cnt aftr =
let apiurl = "http://www.reddit.com/r/" ++ subreddit ++ "/%s.json?count="
++ show cnt ++ maybe "" ("&after=" ++) aftr
in NamedListing (subreddit ++ " -- " ++ select) cnt <$>
getThing apiurl select emptyListing
-- |get posts or comments from an apiurl, a sort order and a default in case
-- of error
getThing :: FromJSON a => String -> String -> a -> IO a
getThing apiurl sort emptyThing =
let sort' = if sort `notElem` map snd availableSorts
then snd . head $ availableSorts
else sort
apiurl' = printf apiurl sort'
in handle (handleCurlAesonException emptyThing) $ do
l <- curlAeson parseJSON "GET" apiurl' [CurlUserAgent userAgent] noData
return $! l
-- |print error message if there is a cURL exception
handleCurlAesonException :: a -> CurlAesonException -> IO a
handleCurlAesonException x e = do
putStrLn $ red ++ "Caught exception: " ++ reset ++ errorMsg e
putStrLn $ if curlCode e == CurlOK
then "(Might indicate a non-existing subreddit)"
else "cURL code: " ++ (drop 4 . show . curlCode) e
return x
-- |request comments for a given article
getComments :: String -> String -> String -> IO Comments
getComments subreddit article csort =
let apiurl = "http://www.reddit.com/r/" ++ subreddit ++
"/comments/" ++ article ++ ".json?sort=%s"
in getThing apiurl csort emptyComments