google-drive 0.1.0 → 0.2.0
raw patch · 4 files changed
+38/−17 lines, 4 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
+ Network.Google.Api: instance Exception ApiError
+ Network.Google.Api: instance Typeable ApiError
+ Network.Google.Api: runApi_ :: String -> Api a -> IO ()
- Network.Google.Api: type Api = ReaderT String (ErrorT ApiError IO)
+ Network.Google.Api: type Api = ReaderT (String, Manager) (ErrorT ApiError IO)
Files
- google-drive.cabal +1/−1
- src/Network/Google/Api.hs +32/−11
- src/Network/Google/Drive/File.hs +4/−4
- src/Network/Google/Drive/Upload.hs +1/−1
google-drive.cabal view
@@ -1,5 +1,5 @@ Name: google-drive-Version: 0.1.0+Version: 0.2.0 Author: Pat Brisbin <pbrisbin@gmail.com> Maintainer: Pat Brisbin <pbrisbin@gmail.com> License: MIT
src/Network/Google/Api.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE OverloadedStrings #-} -- | --@@ -11,6 +12,7 @@ Api , ApiError(..) , runApi+ , runApi_ , throwApiError -- * HTTP-related types@@ -55,19 +57,23 @@ import Data.Conduit import Data.Conduit.Binary (sinkFile) import Data.Monoid ((<>))+import Data.Typeable import GHC.Int (Int64) import Network.HTTP.Conduit ( HttpException(..) , Request(..) , RequestBody(..) , Response(..)+ , Manager+ , conduitManagerSettings+ , closeManager , http , httpLbs+ , newManager , parseUrl , requestBodySource , responseBody , setQueryString- , withManager ) import Network.HTTP.Types ( Header@@ -91,24 +97,33 @@ = HttpError HttpException -- ^ Exceptions raised by http-conduit | InvalidJSON String -- ^ Failure to parse a response as JSON | GenericError String -- ^ All other errors--instance Error ApiError where- strMsg = GenericError+ deriving Typeable instance Show ApiError where show (HttpError ex) = "HTTP Exception: " <> show ex show (InvalidJSON msg) = "failure parsing JSON: " <> msg show (GenericError msg) = msg +instance Error ApiError where+ strMsg = GenericError++instance E.Exception ApiError+ -- | A transformer stack for providing the access token and rescuing errors-type Api = ReaderT String (ErrorT ApiError IO)+type Api = ReaderT (String, Manager) (ErrorT ApiError IO) -- | Run an @Api@ computation with the given Access token runApi :: String -- ^ OAuth2 access token -> Api a -> IO (Either ApiError a)-runApi token f = runErrorT $ runReaderT f token+runApi token f =+ E.bracket (newManager conduitManagerSettings) closeManager $ \manager ->+ runErrorT $ runReaderT f (token, manager) +-- | Like @runApi@ but discards the result and raises @ApiError@s as exceptions+runApi_ :: String -> Api a -> IO ()+runApi_ token f = either E.throw (const $ return ()) =<< runApi token f+ -- | Abort an @Api@ computation with the given message throwApiError :: String -> Api a throwApiError = throwError . GenericError@@ -126,7 +141,7 @@ getSource url params withSource = do request <- setQueryString params <$> authorize url - tryHttp $ withManager $ \manager -> do+ withManager' $ \manager -> do response <- http request manager withSource $ responseBody response @@ -150,12 +165,13 @@ requestLbs url modify = do request <- authorize url - tryHttp $ withManager $ httpLbs $ modify request+ withManager' $ httpLbs $ modify request -- | Create an authorized request for the given URL authorize :: URL -> Api Request authorize url = do- token <- ask+ (token, _) <- ask+ request <- parseUrl' url let authorization = C8.pack $ "Bearer " <> token@@ -196,5 +212,10 @@ Just request -> return request Nothing -> throwApiError $ "Invalid URL: " <> url -tryHttp :: IO a -> Api a-tryHttp = either (throwError . HttpError) return <=< liftIO . E.try+withManager' :: (Manager -> ResourceT IO a) -> Api a+withManager' f = do+ (_, manager) <- ask++ result <- liftIO $ E.try $ runResourceT $ f manager++ either (throwError . HttpError) return result
src/Network/Google/Drive/File.hs view
@@ -182,7 +182,7 @@ , ("maxResults", Just "1000") ] - return $ items+ return items where toParam :: Query -> ByteString@@ -208,7 +208,7 @@ newFile parent filePath = do modified <- liftIO $ getModificationTime filePath - return $ New $ FileData+ return $ New FileData { fileTitle = T.pack $ takeFileName filePath , fileModified = modified , fileParents = [parent]@@ -223,9 +223,9 @@ -> Text -- ^ Title to give the folder -> Api File createFolder parent title = do- modified <- liftIO $ getCurrentTime+ modified <- liftIO getCurrentTime - postJSON (baseUrl <> "/files") [] $ FileData+ postJSON (baseUrl <> "/files") [] FileData { fileTitle = title , fileModified = modified , fileParents = [parent]
src/Network/Google/Drive/Upload.hs view
@@ -59,7 +59,7 @@ -> UploadSource -> Api File uploadFile file fileLength mkSource =- withSessionUrl file $ \url -> do+ withSessionUrl file $ \url -> retryWithBackoff 1 $ do completed <- getUploadedBytes url resumeUpload url completed fileLength mkSource