packages feed

google-drive 0.3.1 → 0.4.0

raw patch · 5 files changed

+91/−29 lines, 5 filesdep +unordered-containersdep −timerepPVP ok

version bump matches the API change (PVP)

Dependencies added: unordered-containers

Dependencies removed: timerep

API changes (from Hackage documentation)

- Network.Google.Api: instance Error ApiError
- Network.Google.Api: instance Exception ApiError
- Network.Google.Api: instance Show ApiError
- Network.Google.Api: instance Typeable ApiError
- Network.Google.Drive.File: fileData :: File -> FileData
- Network.Google.Drive.File: fileDownloadUrl :: FileData -> !(Maybe Text)
- Network.Google.Drive.File: fileId :: File -> FileId
- Network.Google.Drive.File: fileMimeType :: FileData -> !Text
- Network.Google.Drive.File: fileModified :: FileData -> !UTCTime
- Network.Google.Drive.File: fileParents :: FileData -> ![FileId]
- Network.Google.Drive.File: fileSize :: FileData -> !(Maybe Int)
- Network.Google.Drive.File: fileTitle :: FileData -> !FileTitle
- Network.Google.Drive.File: fileTrashed :: FileData -> !Bool
- Network.Google.Drive.File: instance Eq File
- Network.Google.Drive.File: instance FromJSON File
- Network.Google.Drive.File: instance FromJSON FileData
- Network.Google.Drive.File: instance Show File
- Network.Google.Drive.File: instance ToJSON FileData
- Network.Google.Drive.Search: instance FromJSON Items
- Network.Google.Drive.Search: instance QueryValue Bool
- Network.Google.Drive.Search: instance QueryValue Text
- Network.Google.Drive.Search: instance QueryValue UTCTime
- Network.Google.Drive.Search: instance Show Field
+ Network.Google.Api: instance GHC.Exception.Exception Network.Google.Api.ApiError
+ Network.Google.Api: instance GHC.Show.Show Network.Google.Api.ApiError
+ Network.Google.Drive.DateTime: formatDateTime :: UTCTime -> Text
+ Network.Google.Drive.File: [fileData] :: File -> FileData
+ Network.Google.Drive.File: [fileDownloadUrl] :: FileData -> !(Maybe Text)
+ Network.Google.Drive.File: [fileExportLinks] :: FileData -> !(HashMap MimeType Text)
+ Network.Google.Drive.File: [fileId] :: File -> FileId
+ Network.Google.Drive.File: [fileMimeType] :: FileData -> !MimeType
+ Network.Google.Drive.File: [fileModified] :: FileData -> !(Maybe UTCTime)
+ Network.Google.Drive.File: [fileParents] :: FileData -> ![FileId]
+ Network.Google.Drive.File: [fileSize] :: FileData -> !(Maybe Int)
+ Network.Google.Drive.File: [fileTitle] :: FileData -> !FileTitle
+ Network.Google.Drive.File: [fileTrashed] :: FileData -> !Bool
+ Network.Google.Drive.File: instance Data.Aeson.Types.Class.FromJSON Network.Google.Drive.File.File
+ Network.Google.Drive.File: instance Data.Aeson.Types.Class.FromJSON Network.Google.Drive.File.FileData
+ Network.Google.Drive.File: instance Data.Aeson.Types.Class.ToJSON Network.Google.Drive.File.FileData
+ Network.Google.Drive.File: instance GHC.Classes.Eq Network.Google.Drive.File.File
+ Network.Google.Drive.File: instance GHC.Show.Show Network.Google.Drive.File.File
+ Network.Google.Drive.File: type MimeType = Text
+ Network.Google.Drive.Search: (?&&) :: Query -> Query -> Query
+ Network.Google.Drive.Search: (?||) :: Query -> Query -> Query
+ Network.Google.Drive.Search: instance Data.Aeson.Types.Class.FromJSON Network.Google.Drive.Search.Items
+ Network.Google.Drive.Search: instance GHC.Show.Show Network.Google.Drive.Search.Field
+ Network.Google.Drive.Search: instance Network.Google.Drive.Search.QueryValue Data.Text.Internal.Text
+ Network.Google.Drive.Search: instance Network.Google.Drive.Search.QueryValue Data.Time.Clock.UTC.UTCTime
+ Network.Google.Drive.Search: instance Network.Google.Drive.Search.QueryValue GHC.Types.Bool
- Network.Google.Api: type Api = ReaderT (String, Manager) (ErrorT ApiError IO)
+ Network.Google.Api: type Api = ReaderT (String, Manager) (ExceptT ApiError IO)
- Network.Google.Drive.File: FileData :: !FileTitle -> !UTCTime -> ![FileId] -> !Bool -> !(Maybe Int) -> !(Maybe Text) -> !Text -> FileData
+ Network.Google.Drive.File: FileData :: !FileTitle -> !(Maybe UTCTime) -> ![FileId] -> !Bool -> !(Maybe Int) -> !(Maybe Text) -> !MimeType -> !(HashMap MimeType Text) -> FileData
- Network.Google.Drive.File: folderMimeType :: Text
+ Network.Google.Drive.File: folderMimeType :: MimeType
- Network.Google.Drive.File: newFile :: FileTitle -> UTCTime -> FileData
+ Network.Google.Drive.File: newFile :: FileTitle -> Maybe UTCTime -> FileData
- Network.Google.Drive.File: newFolder :: FileTitle -> UTCTime -> FileData
+ Network.Google.Drive.File: newFolder :: FileTitle -> Maybe UTCTime -> FileData
- Network.Google.Drive.File: setMimeType :: Text -> FileData -> FileData
+ Network.Google.Drive.File: setMimeType :: MimeType -> FileData -> FileData

Files

google-drive.cabal view
@@ -1,5 +1,5 @@ Name:                   google-drive-Version:                0.3.1+Version:                0.4.0 Author:                 Pat Brisbin <pbrisbin@gmail.com> Maintainer:             Pat Brisbin <pbrisbin@gmail.com> License:                MIT@@ -20,6 +20,7 @@   GHC-Options:          -Wall   Exposed-Modules:      Network.Google.Api                       , Network.Google.Drive+                      , Network.Google.Drive.DateTime                       , Network.Google.Drive.File                       , Network.Google.Drive.Search                       , Network.Google.Drive.Upload@@ -37,7 +38,7 @@                       , resourcet                       , text                       , time-                      , timerep+                      , unordered-containers  Test-Suite spec   Type:                 exitcode-stdio-1.0
src/Network/Google/Api.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE CPP #-} {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE OverloadedStrings #-} -- |@@ -49,8 +50,11 @@     , sinkFile     ) where +#if __GLASGOW_HASKELL__ < 710 import Control.Applicative ((<$>))-import Control.Monad.Error+#endif++import Control.Monad.Except import Control.Monad.Reader import Control.Monad.Trans.Resource import Data.Aeson (FromJSON(..), ToJSON(..), eitherDecode, encode)@@ -66,8 +70,6 @@     , RequestBody(..)     , Response(..)     , Manager-    , conduitManagerSettings-    , closeManager     , http     , httpLbs     , newManager@@ -75,6 +77,7 @@     , requestBodySource     , responseBody     , setQueryString+    , tlsManagerSettings     ) import Network.HTTP.Types     ( Header@@ -105,21 +108,18 @@     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, Manager) (ErrorT ApiError IO)+type Api = ReaderT (String, Manager) (ExceptT 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 =-    E.bracket (newManager conduitManagerSettings) closeManager $ \manager ->-        runErrorT $ runReaderT f (token, manager)+runApi token f = do+    manager <- newManager tlsManagerSettings+    runExceptT $ runReaderT f (token, manager)  -- | Like @runApi@ but discards the result and raises @ApiError@s as exceptions runApi_ :: String -> Api a -> IO ()
+ src/Network/Google/Drive/DateTime.hs view
@@ -0,0 +1,22 @@+{-# LANGUAGE CPP #-}+module Network.Google.Drive.DateTime+    ( formatDateTime+    ) where++#if __GLASGOW_HASKELL__ < 710+import Control.Applicative ((<$>))+#endif++import Data.Text (Text)+import Data.Time (UTCTime)+import Data.Time.Format (defaultTimeLocale, formatTime)++import qualified Data.Text as T++-- | Format @'UTCTime'@ values for the Drive API+--+-- The docs claim it must be RFC 3339 formatted, but in practice the fractional+-- seconds, @%Q@, (which the RFC states is optional) are required.+--+formatDateTime :: UTCTime -> Text+formatDateTime = T.pack . formatTime defaultTimeLocale "%FT%T%QZ"
src/Network/Google/Drive/File.hs view
@@ -1,3 +1,5 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RecordWildCards #-} -- |@@ -16,6 +18,7 @@     , FileId     , FileData(..)     , FileTitle+    , MimeType      -- * Building @File@s     , newFile@@ -38,10 +41,15 @@     ) where  import Network.Google.Api+import Network.Google.Drive.DateTime -import Control.Applicative ((<$>), (<*>))+#if __GLASGOW_HASKELL__ < 710+import Control.Applicative ((<$>), (<*>), pure)+#endif+ import Control.Monad (mzero, void) import Data.Aeson+import Data.HashMap.Strict (HashMap, empty) import Data.Maybe (isJust) import Data.Monoid ((<>)) import Data.Text (Text)@@ -54,16 +62,18 @@  type FileId = Text type FileTitle = Text+type MimeType = Text  -- | Metadata about Files on your Drive data FileData = FileData     { fileTitle :: !FileTitle-    , fileModified :: !UTCTime+    , fileModified :: !(Maybe UTCTime)     , fileParents :: ![FileId]     , fileTrashed :: !Bool     , fileSize :: !(Maybe Int)     , fileDownloadUrl :: !(Maybe Text)-    , fileMimeType :: !Text+    , fileMimeType :: !MimeType+    , fileExportLinks :: !(HashMap MimeType Text)     }  -- | An existing file@@ -87,13 +97,14 @@         <*> (fmap read <$> o .:? "fileSize") -- fileSize is a String!         <*> o .:? "downloadUrl"         <*> o .: "mimeType"+        <*> o .:? "exportLinks" .!= empty      parseJSON _ = mzero  instance ToJSON FileData where     toJSON FileData{..} = object         [ "title" .= fileTitle-        , "modifiedDate" .= fileModified+        , "modifiedDate" .= (formatDateTime <$> fileModified)         , "parents" .= map (\p -> object ["id" .= p]) fileParents         , "labels" .= object ["trashed" .= fileTrashed]         , "mimeType" .= fileMimeType@@ -123,12 +134,18 @@ -- | Create a @File@ from @FileData@ createFile :: FileData -> Api File createFile fd =-    postJSON (baseUrl <> "/files") [("setModifiedDate", Just "true")] fd+    postJSON (baseUrl <> "/files") (params $ fileModified fd) fd+      where+        params (Just _) = [("setModifiedDate", Just "true")]+        params Nothing = []  -- | Update a @File@ updateFile :: FileId -> FileData -> Api File updateFile fid fd =-    putJSON (fileUrl $ fid) [("setModifiedDate", Just "true")] fd+    putJSON (fileUrl $ fid) (params $ fileModified fd) fd+      where+        params (Just _) = [("setModifiedDate", Just "true")]+        params Nothing = []  -- | Delete a @File@ deleteFile :: File -> Api ()@@ -142,24 +159,25 @@ downloadFile f sink = F.forM (fileDownloadUrl $ fileData f) $ \url ->     getSource (T.unpack url) [] sink -newFile :: FileTitle -> UTCTime -> FileData-newFile title modified = FileData+newFile :: FileTitle -> Maybe UTCTime -> FileData+newFile title maybeModified = FileData     { fileTitle = title-    , fileModified = modified+    , fileModified = maybeModified     , fileParents = []     , fileTrashed = False     , fileSize = Nothing     , fileDownloadUrl = Nothing     , fileMimeType = ""+    , fileExportLinks = empty     } -newFolder :: FileTitle -> UTCTime -> FileData+newFolder :: FileTitle -> Maybe UTCTime -> FileData newFolder title = setMimeType folderMimeType . newFile title  setParent :: File -> FileData -> FileData setParent p f = f { fileParents = [fileId p] } -setMimeType :: Text -> FileData -> FileData+setMimeType :: MimeType -> FileData -> FileData setMimeType m f = f { fileMimeType = m }  -- | What to name this file if downloaded@@ -183,5 +201,5 @@ fileUrl :: FileId -> URL fileUrl fid = baseUrl <> "/files/" <> T.unpack fid -folderMimeType :: Text+folderMimeType :: MimeType folderMimeType = "application/vnd.google-apps.folder"
src/Network/Google/Drive/Search.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE CPP #-} {-# LANGUAGE OverloadedStrings #-} -- | --@@ -19,6 +20,8 @@     , (?<=)     , (?>)     , (?>=)+    , (?&&)+    , (?||)     , qIn     , qHas     , qContains@@ -28,17 +31,20 @@     ) where  import Network.Google.Api+import Network.Google.Drive.DateTime import Network.Google.Drive.File +#if __GLASGOW_HASKELL__ < 710 import Control.Applicative ((<$>), (<$>))+#endif+ import Control.Monad (mzero) import Data.Aeson import Data.Char (toLower) import Data.Monoid ((<>)) import Data.Text (Text) import Data.Text.Encoding (encodeUtf8)-import Data.Time (UTCTime, utc, utcToZonedTime)-import Data.Time.RFC3339 (showRFC3339)+import Data.Time (UTCTime)  import qualified Data.Text as T @@ -73,7 +79,7 @@     escapeValue False = "false"  instance QueryValue UTCTime where-    escapeValue = T.pack . showRFC3339 . utcToZonedTime utc+    escapeValue = formatDateTime  newtype Items = Items [File] @@ -143,17 +149,32 @@ qContains :: QueryValue a => Field -> a -> Query qContains = qOp "contains" +infixr 3 ?&&++-- | Return files that match both clauses+(?&&) :: Query -> Query -> Query+q ?&& p = "(" <> p <> ") and (" <> q <> ")"+ infixr 3 `qAnd`  -- | Return files that match both clauses qAnd :: Query -> Query -> Query-q `qAnd` p = "(" <> p <> ") and (" <> q <> ")"+qAnd = (?&&) +infixr 2 ?||++-- | Return files that match either clause+(?||) :: Query -> Query -> Query+q ?|| p = "(" <> p <> ") or (" <> q <> ")"+ infixr 2 `qOr`  -- | Return files that match either clause qOr :: Query -> Query -> Query-q `qOr` p = "(" <> p <> ") or (" <> q <> ")"+qOr = (?||)++{-# DEPRECATED qAnd "Use ?&& instead" #-}+{-# DEPRECATED qOr "Use ?|| instead" #-}  -- | Negates a search clause qNot :: Query -> Query