forked from haskell-github/github
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPrivate.hs
More file actions
77 lines (68 loc) · 2.95 KB
/
Private.hs
File metadata and controls
77 lines (68 loc) · 2.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
{-# LANGUAGE OverloadedStrings, StandaloneDeriving #-}
module Github.Private where
import Github.Data
import Data.Aeson
import Data.Attoparsec.ByteString.Lazy
import Control.Applicative
import Data.List
import qualified Data.ByteString.Char8 as BS
import qualified Data.ByteString.Lazy.Char8 as LBS
import qualified Network.HTTP.Types as Types
import Network.HTTP.Conduit
import Text.URI
import Control.Failure hiding (Error(..))
import qualified Control.Exception as E
import Data.Maybe (fromMaybe)
githubGet :: (FromJSON b, Show b) => [String] -> IO (Either Error b)
githubGet paths =
githubAPI (BS.pack "GET")
(buildUrl paths)
(Nothing :: Maybe Value)
githubGetWithQueryString :: (FromJSON b, Show b) => [String] -> String -> IO (Either Error b)
githubGetWithQueryString paths queryString =
githubAPI (BS.pack "GET")
(buildUrl paths ++ "?" ++ queryString)
(Nothing :: Maybe Value)
githubPost :: (ToJSON a, Show a, FromJSON b, Show b) => [String] -> a -> IO (Either Error b)
githubPost paths body =
githubAPI (BS.pack "POST")
(buildUrl paths)
(Just body)
buildUrl :: [String] -> String
buildUrl paths = "https://api.github.com/" ++ intercalate "/" paths
githubAPI :: (ToJSON a, Show a, FromJSON b, Show b) => BS.ByteString -> String -> Maybe a -> IO (Either Error b)
githubAPI method url body = do
result <- doHttps method url encodedBody
return $ either (Left . HTTPConnectionError)
(parseJson . responseBody)
result
where encodedBody = (RequestBodyLBS . encode . toJSON) `fmap` body
doHttps :: BS.ByteString -> String -> Maybe (RequestBody IO) -> IO (Either E.IOException (Response LBS.ByteString))
doHttps method url body = do
let (Just uri) = parseURI url
(Just host) = uriRegName uri
requestBody = fromMaybe (RequestBodyBS $ BS.pack "") body
queryString = BS.pack $ fromMaybe "" $ uriQuery uri
request = def { method = method
, secure = False
, host = BS.pack host
, port = 443
, path = BS.pack $ uriPath uri
, requestBody = requestBody
, queryString = queryString
, requestHeaders = [
Types.headerAccept "*/*"
,Types.headerContentType "application/x-www-form-urlencoded" ]
}
(getResponse request >>= return . Right) `catch` (return . Left)
where
getResponse request = withManager $ \manager -> httpLbs request manager
parseJson :: (FromJSON b, Show b) => LBS.ByteString -> Either Error b
parseJson jsonString =
let parsed = parse (fromJSON <$> json) jsonString in
case parsed of
Data.Attoparsec.ByteString.Lazy.Done _ jsonResult -> do
case jsonResult of
(Success s) -> Right s
(Error e) -> Left $ JsonError $ e ++ " on the JSON: " ++ LBS.unpack jsonString
(Fail _ _ e) -> Left $ ParseError e