packages feed

azurify 0.1.0.0 → 0.2.0.0

raw patch · 5 files changed

+141/−74 lines, 5 filesdep +data-defaultdep +textdep ~basePVP ok

version bump matches the API change (PVP)

Dependencies added: data-default, text

Dependency ranges changed: base

API changes (from Hackage documentation)

- Azure.BlobDataTypes: Blob :: ByteString -> ByteString -> ByteString -> ByteString -> Integer -> ByteString -> ByteString -> ByteString -> ByteString -> ByteString -> BlobType -> Blob
- Azure.BlobDataTypes: BlobPublic :: AccessControl
- Azure.BlobDataTypes: BlobSettings :: ByteString -> Maybe ByteString -> Maybe ByteString -> Maybe ByteString -> Maybe ByteString -> Maybe ByteString -> BlobType -> Maybe Integer -> Maybe ByteString -> BlobSettings
- Azure.BlobDataTypes: BlockBlob :: BlobType
- Azure.BlobDataTypes: ContainerPublic :: AccessControl
- Azure.BlobDataTypes: PageBlob :: BlobType
- Azure.BlobDataTypes: Private :: AccessControl
- Azure.BlobDataTypes: blobCacheControl :: Blob -> ByteString
- Azure.BlobDataTypes: blobContentEncoding :: Blob -> ByteString
- Azure.BlobDataTypes: blobContentLanguage :: Blob -> ByteString
- Azure.BlobDataTypes: blobContentLength :: Blob -> Integer
- Azure.BlobDataTypes: blobContentMD5 :: Blob -> ByteString
- Azure.BlobDataTypes: blobContentType :: Blob -> ByteString
- Azure.BlobDataTypes: blobETag :: Blob -> ByteString
- Azure.BlobDataTypes: blobLastModified :: Blob -> ByteString
- Azure.BlobDataTypes: blobName :: Blob -> ByteString
- Azure.BlobDataTypes: blobSettingsCacheControl :: BlobSettings -> Maybe ByteString
- Azure.BlobDataTypes: blobSettingsContentEncoding :: BlobSettings -> Maybe ByteString
- Azure.BlobDataTypes: blobSettingsContentLanguage :: BlobSettings -> Maybe ByteString
- Azure.BlobDataTypes: blobSettingsContentLength :: BlobSettings -> Maybe Integer
- Azure.BlobDataTypes: blobSettingsContentMD5 :: BlobSettings -> Maybe ByteString
- Azure.BlobDataTypes: blobSettingsContentType :: BlobSettings -> Maybe ByteString
- Azure.BlobDataTypes: blobSettingsContents :: BlobSettings -> Maybe ByteString
- Azure.BlobDataTypes: blobSettingsName :: BlobSettings -> ByteString
- Azure.BlobDataTypes: blobSettingsType :: BlobSettings -> BlobType
- Azure.BlobDataTypes: blobType :: Blob -> BlobType
- Azure.BlobDataTypes: blobUrl :: Blob -> ByteString
- Azure.BlobDataTypes: data AccessControl
- Azure.BlobDataTypes: data Blob
- Azure.BlobDataTypes: data BlobSettings
- Azure.BlobDataTypes: data BlobType
- Azure.BlobDataTypes: instance Show Blob
- Azure.BlobDataTypes: instance Show BlobType
- Azure.BlobListParser: getBlobs :: ArrowXml a => a XmlTree XmlTree
- Azure.BlobListParser: parse :: String -> IO [Blob]
- Azure.BlobListParser: xmlBlob :: ArrowXml a => a XmlTree Blob
+ Azure: Blob :: ByteString -> ByteString -> ByteString -> ByteString -> Integer -> ByteString -> ByteString -> ByteString -> ByteString -> ByteString -> BlobType -> Blob
+ Azure: BlobPublic :: AccessControl
+ Azure: BlobSettings :: Maybe ByteString -> Maybe ByteString -> Maybe ByteString -> Maybe ByteString -> Maybe ByteString -> [(Text, Text)] -> CommonBlobSettings
+ Azure: BlockBlob :: BlobType
+ Azure: BlockBlobSettings :: ByteString -> ByteString -> CommonBlobSettings -> BlobSettings
+ Azure: ContainerPublic :: AccessControl
+ Azure: PageBlob :: BlobType
+ Azure: PageBlobSettings :: ByteString -> Integer -> CommonBlobSettings -> BlobSettings
+ Azure: Private :: AccessControl
+ Azure: blobCacheControl :: Blob -> ByteString
+ Azure: blobContentEncoding :: Blob -> ByteString
+ Azure: blobContentLanguage :: Blob -> ByteString
+ Azure: blobContentLength :: Blob -> Integer
+ Azure: blobContentMD5 :: Blob -> ByteString
+ Azure: blobContentType :: Blob -> ByteString
+ Azure: blobETag :: Blob -> ByteString
+ Azure: blobLastModified :: Blob -> ByteString
+ Azure: blobName :: Blob -> ByteString
+ Azure: blobSettingsCacheControl :: CommonBlobSettings -> Maybe ByteString
+ Azure: blobSettingsContentEncoding :: CommonBlobSettings -> Maybe ByteString
+ Azure: blobSettingsContentLanguage :: CommonBlobSettings -> Maybe ByteString
+ Azure: blobSettingsContentMD5 :: CommonBlobSettings -> Maybe ByteString
+ Azure: blobSettingsContentType :: CommonBlobSettings -> Maybe ByteString
+ Azure: blobSettingsMetaData :: CommonBlobSettings -> [(Text, Text)]
+ Azure: blobType :: Blob -> BlobType
+ Azure: blobUrl :: Blob -> ByteString
+ Azure: blockBlobContents :: BlobSettings -> ByteString
+ Azure: blockBlobName :: BlobSettings -> ByteString
+ Azure: blockBlobSettings :: BlobSettings -> CommonBlobSettings
+ Azure: data AccessControl
+ Azure: data Blob
+ Azure: data BlobSettings
+ Azure: data BlobType
+ Azure: data CommonBlobSettings
+ Azure: pageBlobContentLength :: BlobSettings -> Integer
+ Azure: pageBlobName :: BlobSettings -> ByteString
+ Azure: pageBlobSettings :: BlobSettings -> CommonBlobSettings

Files

Azure.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE OverloadedStrings, CPP #-}  {-|     Azurify is an incomplete yet sort-of-functional library and command line client to access the Azure Blob Storage API@@ -19,7 +19,9 @@ -} module Azure ( createContainer              , deleteContainer+#ifndef NO_XML              , listContainer+#endif              , changeContainerACL              , createBlob              , deleteBlob@@ -28,23 +30,21 @@              , module Azure.BlobDataTypes) where  import Azure.BlobDataTypes+#ifndef NO_XML import Azure.BlobListParser+#endif  import Network.HTTP.Conduit-import Network.HTTP.Date import Network.HTTP.Types.Header import Network.HTTP.Types.Status import System.Locale import Data.List import Data.Time-import Data.Time.Clock.POSIX import Data.Char (isSpace) import Data.CaseInsensitive (foldedCase) import Data.Maybe (fromJust, isJust) import Network (withSocketsDo) -import Data.Conduit- import qualified Data.ByteString as B import qualified Data.ByteString.Char8 as B8 import qualified Data.ByteString.Lazy as L@@ -89,6 +89,7 @@     rsp <- doRequest account authKey resource [("restype", "container")] "DELETE" "" []     return $ maybeResponseError rsp +#ifndef NO_XML -- |List all blobs in a given container listContainer :: B.ByteString -- ^ The account name               -> B.ByteString -- ^ Authorisation key@@ -102,6 +103,7 @@       Nothing -> do           blobs <- parse $ L8.unpack $ responseBody rsp           return $ Right blobs+#endif  -- |Set the access control on a container changeContainerACL :: B.ByteString -- ^ The account name@@ -125,37 +127,39 @@            -> BlobSettings -- ^ The blob itself, note that Page blobs are *not supported*            -> IO (Maybe (Int, L.ByteString)) -- ^ Nothing when successful, HTTP error code and content otherwise createBlob account authKey containerName blobSettings =-    case blobSettingsType blobSettings of-        BlockBlob -> createBlockBlob account authKey containerName blobSettings-        PageBlob -> error "Page blob not implemented yet"--createBlockBlob :: B.ByteString -> B.ByteString -> B.ByteString -> BlobSettings -> IO (Maybe (Int, L.ByteString))-createBlockBlob account authKey containerName blobSettings = do-    let resource = "/" +++ containerName +++ "/" +++ blobSettingsName blobSettings-    rsp <- doRequest account authKey resource [] "PUT" (fromJust $ blobSettingsContents blobSettings) hdrs-    return $ maybeResponseError rsp-    where hdrs = map (second fromJust) $ filter (\(_,a) -> isJust a)-                [ ("Content-Type", blobSettingsContentType blobSettings)-                , ("Content-Encoding", blobSettingsContentEncoding blobSettings)-                , ("Content-Language", blobSettingsContentLanguage blobSettings)-                , ("Content-MD5", blobSettingsContentMD5 blobSettings)-                , ("Cache-Control", blobSettingsCacheControl blobSettings)-                , ("x-ms-blob-type", Just "BlockBlob") ]+    case blobSettings of+      BlockBlobSettings name contents common ->+        createBlockBlob name contents common+      PageBlobSettings name contentLength common ->+        createPageBlob name contentLength common+  where+    createBlockBlob :: B.ByteString -> B.ByteString -> CommonBlobSettings -> IO (Maybe (Int, L.ByteString))+    createBlockBlob name content conf = do+        let resource = "/" +++ containerName +++ "/" +++ name+        rsp <- doRequest account authKey resource [] "PUT" content hdrs+        return $ maybeResponseError rsp+        where hdrs = map (second fromJust) $ filter (\(_,a) -> isJust a)+                    [ ("Content-Type", blobSettingsContentType conf)+                    , ("Content-Encoding", blobSettingsContentEncoding conf)+                    , ("Content-Language", blobSettingsContentLanguage conf)+                    , ("Content-MD5", blobSettingsContentMD5 conf)+                    , ("Cache-Control", blobSettingsCacheControl conf)+                    , ("x-ms-blob-type", Just "BlockBlob") ] -createPageBlob :: B.ByteString -> B.ByteString -> B.ByteString -> BlobSettings -> IO (Maybe (Int, L.ByteString))-createPageBlob account authKey containerName blobSettings = do-    let resource = "/" +++ containerName +++ "/" +++ blobSettingsName blobSettings-    rsp <- doRequest account authKey resource [] "PUT" "" hdrs-    return $ maybeResponseError rsp-    where hdrs = map (second fromJust) $ filter (\(_,a) -> isJust a)-                [ ("Content-Type", blobSettingsContentType blobSettings)-                , ("Content-Encoding", blobSettingsContentEncoding blobSettings)-                , ("Content-Language", blobSettingsContentLanguage blobSettings)-                , ("Content-MD5", blobSettingsContentMD5 blobSettings)-                , ("Cache-Control", blobSettingsCacheControl blobSettings)-                , ("x-ms-blob-type", Just "PageBlob")-                , ("x-ms-blob-content-length", Just $ B8.pack $ show $ B.length $ fromJust $ blobSettingsContents blobSettings)-                ]+    createPageBlob :: B.ByteString -> Integer -> CommonBlobSettings -> IO (Maybe (Int, L.ByteString))+    createPageBlob name contentLength conf = do+        let resource = "/" +++ containerName +++ "/" +++ name+        rsp <- doRequest account authKey resource [] "PUT" "" hdrs+        return $ maybeResponseError rsp+        where hdrs = map (second fromJust) $ filter (\(_,a) -> isJust a)+                    [ ("Content-Type", blobSettingsContentType conf)+                    , ("Content-Encoding", blobSettingsContentEncoding conf)+                    , ("Content-Language", blobSettingsContentLanguage conf)+                    , ("Content-MD5", blobSettingsContentMD5 conf)+                    , ("Cache-Control", blobSettingsCacheControl conf)+                    , ("x-ms-blob-type", Just "PageBlob")+                    , ("x-ms-blob-content-length", Just $ B8.pack $ show $ contentLength)+                    ]  -- |Delete a blob from a container deleteBlob :: B.ByteString -- ^ The account name
Azure/BlobDataTypes.hs view
@@ -1,24 +1,36 @@ module Azure.BlobDataTypes where  import qualified Data.ByteString as B+import Data.Text (Text)+import Data.Default  data AccessControl = ContainerPublic -- ^ the container can be enumerated and all blobs can be read by anonymous users                    | BlobPublic      -- ^ blobs can be read by anonymous users, but the container cannot be enumerated                    | Private         -- ^ blobs can't be read by anonymous users and the container cannot be enumerated -data BlobType = PageBlob | BlockBlob deriving (Show)+data CommonBlobSettings = BlobSettings {+                           blobSettingsContentType :: Maybe B.ByteString+                         , blobSettingsContentEncoding :: Maybe B.ByteString+                         , blobSettingsContentLanguage :: Maybe B.ByteString+                         , blobSettingsContentMD5 :: Maybe B.ByteString+                         , blobSettingsCacheControl :: Maybe B.ByteString+                         , blobSettingsMetaData :: [(Text, Text)]+                         } -data BlobSettings = BlobSettings { blobSettingsName :: B.ByteString-                                 , blobSettingsContentType :: Maybe B.ByteString-                                 , blobSettingsContentEncoding :: Maybe B.ByteString-                                 , blobSettingsContentLanguage :: Maybe B.ByteString-                                 , blobSettingsContentMD5 :: Maybe B.ByteString-                                 , blobSettingsCacheControl :: Maybe B.ByteString-                                 , blobSettingsType :: BlobType-                                 , blobSettingsContentLength :: Maybe Integer -- ^ only for page blobs, set to Nothing for block blob-                                 , blobSettingsContents :: Maybe B.ByteString -- ^ only for block blobs, set to Empty for page blob-                                 }+instance Default CommonBlobSettings where+  def = BlobSettings Nothing Nothing Nothing Nothing Nothing [] +data BlobSettings =+        BlockBlobSettings { blockBlobName :: B.ByteString+                          , blockBlobContents :: B.ByteString+                          , blockBlobSettings :: CommonBlobSettings+                          }+      | PageBlobSettings  { pageBlobName :: B.ByteString+                          , pageBlobContentLength :: Integer+                          , pageBlobSettings :: CommonBlobSettings+                          }++data BlobType = PageBlob | BlockBlob deriving (Show) data Blob = Blob { blobName :: B.ByteString                  , blobUrl :: B.ByteString                  , blobLastModified :: B.ByteString
Azure/BlobListParser.hs view
@@ -4,10 +4,10 @@  import Azure.BlobDataTypes -import qualified Data.ByteString as B import qualified Data.ByteString.Char8 as B8 import Text.XML.HXT.Core hiding (Blob) +parse :: String -> IO [Blob] parse xml = runX (readString [] xml >>> getBlobs >>> xmlBlob)  getBlobs :: (ArrowXml a) => a XmlTree XmlTree
azurify.cabal view
@@ -1,5 +1,5 @@ name:                azurify-version:             0.1.0.0+version:             0.2.0.0 synopsis:            A simple library for accessing Azure blob storage description:         An interface for a few basic functions of the Microsoft Azure blob storage. Creating and deleting containers as well as uploading, downloading and breaking leases of blobs is supported. homepage:            http://arnovanlumig.com/azurify.html@@ -13,10 +13,39 @@  extra-source-files: Azure/BlobDataTypes.hs, Azure/BlobListParser.hs, readme.md -Library-  Exposed-Modules: Azure+Flag no-hxt+  Description: no xml parsing, and no hxt dependency+  Default: False++Flag library-only+  Description: don't build the executable+  Default: False++library+  ghc-options: -Wall++  if flag(no-hxt)+      cpp-options:   -DNO_XML++  extensions:+    OverloadedStrings+    CPP++  exposed-modules:+    Azure++  if flag(no-hxt)+    other-modules:+      Azure.BlobDataTypes+  else+    other-modules:+      Azure.BlobDataTypes+      Azure.BlobListParser+   build-depends:-    base >= 4.5,+    base >= 4.5 && < 5,+    text,+    data-default,     bytestring >= 0.9.2.1,     http-conduit >= 1.5.0.3,     http-types >= 0.7.0,@@ -25,20 +54,28 @@     network >= 2.3.0.13,     http-date >= 0.0.2,     time >= 1.4,-    old-locale >= 1.0.0.4,     SHA >= 1.5.1,     base64-bytestring >= 0.1.2.0,     case-insensitive >= 0.4.0.1,     utf8-string >= 0.3.7,-    hxt >= 9.2.2,-    cmdargs >= 0.10,-    directory >= 1.1.0.2+    old-locale >= 1.0.0.4 +  if !flag(no-hxt)+    build-depends:+      hxt >= 9.2.2+ executable azurify+  if flag(library-only)+      Buildable: False++  if flag(no-hxt)+      cpp-options:   -DNO_XML+   main-is: azurify.hs-  hs-source-dirs: . Azure/   build-depends:-    base >= 4.5 && < 5,+    base >= 4.5,+    text,+    data-default,     bytestring >= 0.9.2.1,     http-conduit >= 1.5.0.3,     http-types >= 0.7.0,@@ -52,6 +89,9 @@     base64-bytestring >= 0.1.2.0,     case-insensitive >= 0.4.0.1,     utf8-string >= 0.3.7,-    hxt >= 9.2.2,     cmdargs >= 0.10,     directory >= 1.1.0.2++  if !flag(no-hxt)+    build-depends:+      hxt >= 9.2.2
azurify.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE OverloadedStrings, DeriveDataTypeable #-}+{-# LANGUAGE OverloadedStrings, CPP, DeriveDataTypeable #-}  module Main where @@ -69,21 +69,33 @@                                 , breakLeaseBlobName = def &= typ "blobname" &= argPos 2                                 } +#ifndef NO_XML listContainer = ListContainer { listContainerStorageName = def &= typ "accountname" &= argPos 0                               , listContainerContainerName = def &= typ "containername" &= argPos 1                               } &= help "List all blobs in a container"+#endif  createContainer = CreateContainer { createContainerStorageName = def &= typ "accountname" &= argPos 0                                   , createContainerContainerName = def &= typ "containername" &= argPos 1                                   , createContainerACL = def &= typ "blobpublic|containerpublic|private" &= argPos 2                                   } &= help "Create a container with the specified access control" +#ifndef NO_XML deleteContainer = DeleteContainer { deleteContainerStorageName = def &= typ "accountname" &= argPos 0                                   , deleteContainerContainerName = def &= typ "containername" &= argPos 1                                   , deleteContainerForce = def &= name "force"                                   } &= help "Delete the container and all the blobs inside it"+#endif -mode = cmdArgsMode $ modes [uploadBlob, downloadBlob, deleteBlob, breakBlobLease, listContainer, createContainer, deleteContainer] &= help "Access the Azure blob storage" &= program "azurify" &= summary "Azurify v1.0"+mode = cmdArgsMode $ modes [uploadBlob, downloadBlob, deleteBlob, breakBlobLease+#ifndef NO_XML+         , listContainer+#endif+         , createContainer+#ifndef NO_XML+         , deleteContainer+#endif+         ] &= help "Access the Azure blob storage" &= program "azurify" &= summary "Azurify v1.0"  main :: IO () main = do@@ -93,18 +105,15 @@     case m of         UploadBlob path account container name contType contEnc contLang contCache -> do             contents <- B.readFile path-            res <- Az.createBlob (B8.pack account)-                                 azureKey (B8.pack container)-                                 (Az.BlobSettings (B8.pack name)-                                                  (B8.pack `fmap` contType)-                                                  (B8.pack `fmap` contEnc)-                                                  (B8.pack `fmap` contLang)-                                                  Nothing-                                                  (B8.pack `fmap` contCache)-                                                  Az.BlockBlob-                                                  Nothing-                                                  (Just contents)-                                                  )+            res <- Az.createBlob (B8.pack account) azureKey (B8.pack container) $+                       Az.BlockBlobSettings (B8.pack name) contents $+                         Az.BlobSettings+                            (B8.pack `fmap` contType)+                            (B8.pack `fmap` contEnc)+                            (B8.pack `fmap` contLang)+                            Nothing+                            (B8.pack `fmap` contCache)+                            []             case res of                 Just (stat, err) -> putStrLn "error" >> print stat >> putStrLn "\n" >> print err                 Nothing -> return ()@@ -126,11 +135,13 @@             case res of                 Just (stat, err) -> putStrLn "error" >> print stat >> putStrLn "\n" >> print err                 _ -> return ()+#ifndef NO_XML         ListContainer account container -> do -- TODO: output formatting             res <- Az.listContainer (B8.pack account) azureKey (B8.pack container)             case res of                 Left (stat, err) -> putStrLn "error" >> print stat >> putStrLn "\n" >> print err                 Right blobs -> mapM_ print blobs+#endif         CreateContainer account container access -> do             let acl = case access of {                 Just "blobpublic" -> Az.BlobPublic;@@ -143,6 +154,7 @@             case res of                 Just (stat, err) -> putStrLn "error" >> print stat >> putStrLn "\n" >> print err                 Nothing -> return ()+#ifndef NO_XML         DeleteContainer account container force -> do             if force == (Just True) then do                 res <- Az.listContainer (B8.pack account) azureKey (B8.pack container)@@ -154,5 +166,4 @@                     case res of                         Just (stat, err) -> putStrLn "error" >> print stat >> putStrLn "\n" >> print err                         Nothing -> return ()--+#endif