packages feed

DAV 1.2 → 1.3

raw patch · 3 files changed

+102/−71 lines, 3 filesdep +haskelinedep ~mtlPVP ok

version bump matches the API change (PVP)

Dependencies added: haskeline

Dependency ranges changed: mtl

API changes (from Hackage documentation)

- Network.Protocol.HTTP.DAV: _allowedMethods :: DAVContext -> [ByteString]
- Network.Protocol.HTTP.DAV: _baseRequest :: DAVContext -> Request
- Network.Protocol.HTTP.DAV: _basicpassword :: DAVContext -> ByteString
- Network.Protocol.HTTP.DAV: _basicusername :: DAVContext -> ByteString
- Network.Protocol.HTTP.DAV: _complianceClasses :: DAVContext -> [ByteString]
- Network.Protocol.HTTP.DAV: _depth :: DAVContext -> Maybe Depth
- Network.Protocol.HTTP.DAV: _httpManager :: DAVContext -> Maybe Manager
- Network.Protocol.HTTP.DAV: _lockToken :: DAVContext -> Maybe ByteString
- Network.Protocol.HTTP.DAV: _userAgent :: DAVContext -> ByteString
- Network.Protocol.HTTP.DAV: instance (Monad m, Functor m) => Alternative (DAVT m)
- Network.Protocol.HTTP.DAV: instance (Monad m, Functor m) => Applicative (DAVT m)
- Network.Protocol.HTTP.DAV: instance Default DAVContext
- Network.Protocol.HTTP.DAV: instance Functor m => Functor (DAVT m)
- Network.Protocol.HTTP.DAV: instance Monad m => Monad (DAVT m)
- Network.Protocol.HTTP.DAV: instance Monad m => MonadError String (DAVT m)
- Network.Protocol.HTTP.DAV: instance Monad m => MonadPlus (DAVT m)
- Network.Protocol.HTTP.DAV: instance Monad m => MonadState DAVContext (DAVT m)
- Network.Protocol.HTTP.DAV: instance MonadBase b m => MonadBase b (DAVT m)
- Network.Protocol.HTTP.DAV: instance MonadCatch m => MonadCatch (DAVT m)
- Network.Protocol.HTTP.DAV: instance MonadFix m => MonadFix (DAVT m)
- Network.Protocol.HTTP.DAV: instance MonadIO m => MonadIO (DAVT m)
- Network.Protocol.HTTP.DAV: instance MonadThrow m => MonadThrow (DAVT m)
- Network.Protocol.HTTP.DAV: instance MonadTrans DAVT
- Network.Protocol.HTTP.DAV: runDAVT :: DAVT m a -> ExceptT String (StateT DAVContext m) a
+ Network.Protocol.HTTP.DAV: [_allowedMethods] :: DAVContext -> [ByteString]
+ Network.Protocol.HTTP.DAV: [_baseRequest] :: DAVContext -> Request
+ Network.Protocol.HTTP.DAV: [_basicpassword] :: DAVContext -> ByteString
+ Network.Protocol.HTTP.DAV: [_basicusername] :: DAVContext -> ByteString
+ Network.Protocol.HTTP.DAV: [_complianceClasses] :: DAVContext -> [ByteString]
+ Network.Protocol.HTTP.DAV: [_depth] :: DAVContext -> Maybe Depth
+ Network.Protocol.HTTP.DAV: [_httpManager] :: DAVContext -> Maybe Manager
+ Network.Protocol.HTTP.DAV: [_lockToken] :: DAVContext -> Maybe ByteString
+ Network.Protocol.HTTP.DAV: [_userAgent] :: DAVContext -> ByteString
+ Network.Protocol.HTTP.DAV: [runDAVT] :: DAVT m a -> ExceptT String (StateT DAVContext m) a
+ Network.Protocol.HTTP.DAV: instance Control.Monad.Base.MonadBase b m => Control.Monad.Base.MonadBase b (Network.Protocol.HTTP.DAV.DAVT m)
+ Network.Protocol.HTTP.DAV: instance Control.Monad.Catch.MonadCatch m => Control.Monad.Catch.MonadCatch (Network.Protocol.HTTP.DAV.DAVT m)
+ Network.Protocol.HTTP.DAV: instance Control.Monad.Catch.MonadThrow m => Control.Monad.Catch.MonadThrow (Network.Protocol.HTTP.DAV.DAVT m)
+ Network.Protocol.HTTP.DAV: instance Control.Monad.Fix.MonadFix m => Control.Monad.Fix.MonadFix (Network.Protocol.HTTP.DAV.DAVT m)
+ Network.Protocol.HTTP.DAV: instance Control.Monad.IO.Class.MonadIO m => Control.Monad.IO.Class.MonadIO (Network.Protocol.HTTP.DAV.DAVT m)
+ Network.Protocol.HTTP.DAV: instance Control.Monad.Trans.Class.MonadTrans Network.Protocol.HTTP.DAV.DAVT
+ Network.Protocol.HTTP.DAV: instance Data.Default.Class.Default Network.Protocol.HTTP.DAV.TH.DAVContext
+ Network.Protocol.HTTP.DAV: instance GHC.Base.Functor m => GHC.Base.Functor (Network.Protocol.HTTP.DAV.DAVT m)
+ Network.Protocol.HTTP.DAV: instance GHC.Base.Monad m => Control.Monad.Error.Class.MonadError GHC.Base.String (Network.Protocol.HTTP.DAV.DAVT m)
+ Network.Protocol.HTTP.DAV: instance GHC.Base.Monad m => Control.Monad.State.Class.MonadState Network.Protocol.HTTP.DAV.TH.DAVContext (Network.Protocol.HTTP.DAV.DAVT m)
+ Network.Protocol.HTTP.DAV: instance GHC.Base.Monad m => GHC.Base.Alternative (Network.Protocol.HTTP.DAV.DAVT m)
+ Network.Protocol.HTTP.DAV: instance GHC.Base.Monad m => GHC.Base.Applicative (Network.Protocol.HTTP.DAV.DAVT m)
+ Network.Protocol.HTTP.DAV: instance GHC.Base.Monad m => GHC.Base.Monad (Network.Protocol.HTTP.DAV.DAVT m)
+ Network.Protocol.HTTP.DAV: instance GHC.Base.Monad m => GHC.Base.MonadPlus (Network.Protocol.HTTP.DAV.DAVT m)

Files

DAV.cabal view
@@ -1,5 +1,5 @@ name:                DAV-version:             1.2+version:             1.3 synopsis:            RFC 4918 WebDAV support description:    This is a library for the Web Distributed Authoring and Versioning@@ -15,7 +15,7 @@ license-file:        LICENSE author:              Clint Adams maintainer:          clint@debian.org-copyright:           Copyright (C) 2012-2015  Clint Adams+copyright:           Copyright (C) 2012-2016  Clint Adams category:            Web build-type:          Simple cabal-version:       >=1.8@@ -25,6 +25,10 @@   description: Get Network.URI from the network-uri package   default: True +flag mtl-compat+  description: Get Control.Monad.Except from the mtl-compat package+  default: False+ library   exposed-modules:  Network.Protocol.HTTP.DAV   other-modules:    Network.Protocol.HTTP.DAV.TH@@ -39,14 +43,17 @@                      , http-client-tls >= 0.2                      , http-types >= 0.7                      , lens >= 3.0-                     , mtl >= 2.1-                     , mtl-compat                      , transformers >= 0.3                      , transformers-base                      , transformers-compat >= 0.3                      , utf8-string                      , xml-conduit >= 1.0                      , xml-hamlet >= 0.4           && < 0.5+  if flag(mtl-compat)+    build-depends: mtl >= 2.1 && < 2.2.1, mtl-compat+  else+    build-depends: mtl >= 2.2.1+ executable hdav   main-is:           hdav.hs   ghc-options:       -Wall@@ -57,12 +64,11 @@                      , containers                      , data-default                      , exceptions >= 0.7+                     , haskeline                      , http-client >= 0.4                      , http-client-tls >= 0.2                      , http-types >= 0.7                      , lens >= 3.0-                     , mtl >= 2.1-                     , mtl-compat                      , optparse-applicative >= 0.10.0                      , transformers >= 0.3                      , transformers-base@@ -70,6 +76,10 @@                      , utf8-string                      , xml-conduit >= 1.0                      , xml-hamlet >= 0.4           && < 0.5+  if flag(mtl-compat)+    build-depends: mtl >= 2.1 && < 2.2.1, mtl-compat+  else+    build-depends: mtl >= 2.2.1   if flag(network-uri)     build-depends: network-uri >= 2.6, network >= 2.6   else@@ -83,4 +93,4 @@ source-repository this   type:     git   location: git://anonscm.debian.org/users/clint/DAV.git-  tag:      DAV/1.2+  tag:      DAV/1.3
Network/Protocol/HTTP/DAV.hs view
@@ -1,5 +1,5 @@ -- DAV.hs: WebDAV client library--- Copyright © 2012-2015  Clint Adams+-- Copyright © 2012-2016  Clint Adams -- -- vim: softtabstop=4:shiftwidth=4:expandtab --@@ -19,7 +19,7 @@ {-# LANGUAGE OverloadedStrings, ConstraintKinds, FlexibleContexts,              QuasiQuotes, RankNTypes, GeneralizedNewtypeDeriving,              FlexibleInstances, MultiParamTypeClasses, UndecidableInstances,-             TypeFamilies #-}+             TypeFamilies, CPP #-}  module Network.Protocol.HTTP.DAV (     DAVT(..)@@ -52,12 +52,15 @@  import Network.Protocol.HTTP.DAV.TH -import Control.Applicative (liftA2, Alternative, Applicative)+#if !MIN_VERSION_base(4,8,0)+import Control.Applicative (Applicative)+#endif+import Control.Applicative (liftA2, Alternative) import Control.Monad.Trans.Except (ExceptT(..), throwE, runExceptT) import Control.Lens ((^.), (.=), (%=), (.~)) import Control.Monad (when, MonadPlus) import Control.Monad.Base (MonadBase(..))-import Control.Monad.Catch (bracket, bracketOnError, catchJust, finally, throwM, mask, uninterruptibleMask, MonadCatch, MonadThrow)+import Control.Monad.Catch (catchJust, throwM, MonadCatch, MonadThrow) import qualified Control.Monad.Catch as MonadCatch import Control.Monad.Except (MonadError, catchError, throwError) import Control.Monad.Fix (MonadFix)@@ -76,7 +79,7 @@  import Network.HTTP.Client (RequestBody(..), httpLbs, parseUrl, applyBasicAuth, Request(..), Response(..), newManager, HttpException(..), BodyReader, withResponse, path) import Network.HTTP.Client.TLS (tlsManagerSettings)-import Network.HTTP.Types (hContentType, Method, Status, RequestHeaders, unauthorized401, conflict409)+import Network.HTTP.Types (hContentType, Method, Status, RequestHeaders, conflict409)  import qualified Text.XML as XML import Text.XML.Cursor (($/), (&/), element, node, fromDocument, checkName)
hdav.hs view
@@ -1,7 +1,5 @@-{-# LANGUAGE FlexibleContexts #-}- -- hdav.hs: WebDAV client--- Copyright © 2012-2014  Clint Adams+-- Copyright © 2012-2016  Clint Adams -- -- vim: softtabstop=4:shiftwidth=4:expandtab --@@ -18,20 +16,23 @@ -- You should have received a copy of the GNU General Public License -- along with this program.  If not, see <http://www.gnu.org/licenses/>. -import qualified Data.ByteString.Char8 as BC8+{-# LANGUAGE CPP #-}+{-# LANGUAGE FlexibleContexts #-}  import Paths_DAV (version)-import Control.Applicative ((<$>),(<*>), optional, pure)+import qualified Data.ByteString as B+import qualified Data.ByteString.Lazy as BL+import qualified Data.ByteString.UTF8 as BU+#if !MIN_VERSION_base(4,8,0)+import Control.Applicative ((<$>),(<*>), pure)+#endif+import Control.Applicative (optional) import Control.Monad (liftM2, unless) import Control.Monad.IO.Class (MonadIO) import Data.Version (showVersion)-import Data.Maybe (fromMaybe) import Data.Monoid ((<>))-import Text.XML (renderLBS, def)-import qualified Data.ByteString.Lazy.Char8 as B  import Network (withSocketsDo)- import Network.URI (normalizePathSegments)  import Network.Protocol.HTTP.DAV (DAVT, evalDAVT, setCreds, setDepth, setUserAgent, getPropsM, getContentM, putContentM, putPropsM, delContentM, moveContentM, mkCol, Depth(..), caldavReportM, withLockIfPossible, withLockIfPossibleForDelete)@@ -40,13 +41,18 @@ import Options.Applicative.Extra (customExecParser) import Options.Applicative.Types (Parser) +import System.Console.Haskeline (runInputT, getPassword)+import qualified System.Console.Haskeline as SCH++import Text.XML (renderLBS, def)+ data Options = Options {     url :: String   , url2 :: String-  , username :: String-  , password :: String-  , username2 :: String-  , password2 :: String+  , username :: Maybe String+  , password :: Maybe String+  , username2 :: Maybe String+  , password2 :: Maybe String }  data Command = Copy Options | Move Options | Delete Options | MakeCollection Options | GetProps Options (Maybe Depth) | Put FilePath Options | CaldavReport Options@@ -55,104 +61,108 @@ oneUUP = Options     <$> argument str ( metavar "URL" )     <*> pure ""-    <*> (fromMaybe "" <$> (optional $ strOption+    <*> (optional $ strOption         ( long "username"        <> metavar "USERNAME"-       <> help "username for URL" )))-    <*> (fromMaybe "" <$> (optional $ strOption+       <> help "username for URL" ))+    <*> (optional $ strOption         ( long "password"        <> metavar "PASSWORD"-       <> help "password for URL" )))-    <*> pure ""-    <*> pure ""+       <> help "password for URL" ))+    <*> pure Nothing+    <*> pure Nothing  twoUUP :: Parser Options twoUUP = Options     <$> argument str ( metavar "SOURCEURL" )     <*> argument str ( metavar "TARGETURL" )-    <*> (fromMaybe "" <$> (optional $ strOption+    <*> (optional $ strOption         ( long "source-username"        <> metavar "USERNAME"-       <> help "username for source URL" )))-    <*> (fromMaybe "" <$> (optional $ strOption+       <> help "username for source URL" ))+    <*> (optional $ strOption         ( long "source-password"        <> metavar "PASSWORD"-       <> help "password for source URL" )))-    <*> (fromMaybe "" <$> (optional $ strOption+       <> help "password for source URL" ))+    <*> (optional $ strOption         ( long "target-username"        <> metavar "USERNAME"-       <> help "username for target URL" )))-    <*> (fromMaybe "" <$> (optional $ strOption+       <> help "username for target URL" ))+    <*> (optional $ strOption         ( long "target-password"        <> metavar "PASSWORD"-       <> help "password for target URL" )))+       <> help "password for target URL" ))  twoUoneUP :: Parser Options twoUoneUP = Options     <$> argument str ( metavar "SOURCEURL" )     <*> argument str ( metavar "TARGETURL" )-    <*> (fromMaybe "" <$> (optional $ strOption+    <*> (optional $ strOption         ( long "username"        <> metavar "USERNAME"-       <> help "username for URL" )))-    <*> (fromMaybe "" <$> (optional $ strOption+       <> help "username for URL" ))+    <*> (optional $ strOption         ( long "password"        <> metavar "PASSWORD"-       <> help "password for URL" )))-    <*> pure ""-    <*> pure ""+       <> help "password for URL" ))+    <*> pure Nothing+    <*> pure Nothing  doCopy :: Options -> IO () doCopy o = do+     (sourceUsername, sourcePassword) <- ingestCreds ("source URL " ++ sourceurl) (username o) (password o)+     (targetUsername, targetPassword) <- ingestCreds ("target URL " ++ targeturl) (username2 o) (password2 o)      (p, b) <- runDAV sourceurl $ setCreds sourceUsername sourcePassword >> setDepth (Just Depth0) >> withLockIfPossible True (liftM2 (,) getPropsM getContentM)      runDAV targeturl $ setCreds targetUsername targetPassword >> withLockIfPossible False (putContentM b >> putPropsM p)      where          sourceurl = url o          targeturl = url2 o-         sourceUsername = BC8.pack $ username o-         sourcePassword = BC8.pack $ password o-         targetUsername = BC8.pack $ username2 o-         targetPassword = BC8.pack $ password2 o  doDelete :: Options -> IO ()-doDelete o = runDAV (url o) $ setCreds (BC8.pack $ username o) (BC8.pack $ password o) >> withLockIfPossibleForDelete False delContentM+doDelete o = do+    (u, p) <- ingestCreds ("URL " ++ url o) (username o) (password o)+    runDAV (url o) $ setCreds u p >> withLockIfPossibleForDelete False delContentM  doMove :: Options -> IO ()-doMove o = runDAV (url o) $ setCreds (BC8.pack $ username o) (BC8.pack $ password o) >> moveContentM (BC8.pack $ url2 o)+doMove o = do+    (u, p) <- ingestCreds ("URL " ++ url o) (username o) (password o)+    runDAV (url o) $ setCreds u p >> moveContentM (BU.fromString $ url2 o)  doMakeCollection :: Options -> IO ()-doMakeCollection o = go (url o)+doMakeCollection o = do+    (u, p) <- ingestCreds ("URL " ++ url o) (username o) (password o)+    go (url o) (u, p)   where-     u = BC8.pack . username $ o-     p = BC8.pack . password $ o--     go url' = do-       ok <- makeCollection url'+     go url' (u, p) = do+       ok <- makeCollection url' (u, p)        unless ok $ do-         go (parent url')-         ok' <- makeCollection url'+         go (parent url') (u, p)+         ok' <- makeCollection url' (u, p)          unless ok' $            error $ "failed creating " ++ url'       parent url' = reverse $ dropWhile (== '/')$ reverse $         normalizePathSegments (url' ++ "/..") -     makeCollection url' = runDAV url' $ setCreds u p >> mkCol+     makeCollection url' (u, p) = runDAV url' $ setCreds u p >> mkCol  doGetProps :: Options -> Maybe Depth -> IO () doGetProps o md = do-     doc <- runDAV (url o) $ setCreds (BC8.pack $ username o) (BC8.pack $ password o) >> setDepth md >> getPropsM-     B.putStrLn (renderLBS def doc)+    (u, p) <- ingestCreds ("URL " ++ url o) (username o) (password o)+    doc <- runDAV (url o) $ setCreds u p >> setDepth md >> getPropsM+    BL.putStr (renderLBS def doc)  doPut :: FilePath -> Options -> IO () doPut file o = do-     bs <- B.readFile file-     runDAV (url o) $ setCreds (BC8.pack $ username o) (BC8.pack $ password o) >> putContentM (Nothing, bs)+    (u, p) <- ingestCreds ("URL " ++ url o) (username o) (password o)+    bs <- BL.readFile file+    runDAV (url o) $ setCreds u p >> putContentM (Nothing, bs)  doReport :: Options -> IO () doReport o = do-     doc <- runDAV (url o) $ setCreds (BC8.pack $ username o) (BC8.pack $ password o) >> setDepth (Just Depth1) >> caldavReportM-     B.putStrLn (renderLBS def doc)+    (u, p) <- ingestCreds ("URL " ++ url o) (username o) (password o)+    doc <- runDAV (url o) $ setCreds u p >> setDepth (Just Depth1) >> caldavReportM+    BL.putStr (renderLBS def doc)  dispatch :: Command -> IO () dispatch (Copy o) = doCopy o@@ -165,10 +175,11 @@  main :: IO () main = withSocketsDo $ do-    putStrLn $ "hDAV version " ++ showVersion version ++ ", Copyright (C) 2012-2014  Clint Adams\n\-   \hDAV comes with ABSOLUTELY NO WARRANTY.\n\-   \This is free software, and you are welcome to redistribute it\n\-   \under certain conditions.\n"+    putStrLn $ concat [+      "hDAV version ", showVersion version, ", Copyright (C) 2012-2016  Clint Adams\n",+      "hDAV comes with ABSOLUTELY NO WARRANTY.\n",+      "This is free software, and you are welcome to redistribute it\n",+      "under certain conditions.\n"]      customExecParser (prefs showHelpOnError) (info cmd idm) >>= dispatch @@ -187,6 +198,13 @@    depth = option auto ( long "depth" <> metavar "DEPTH" <> help "depth" ) :: Parser Depth  runDAV :: MonadIO m => String -> DAVT m a -> m a-runDAV u f = evalDAVT u (setUserAgent (BC8.pack $ "hDAV/" ++ showVersion version) >> f) >>= \x -> case x of+runDAV u f = evalDAVT u (setUserAgent (BU.fromString $ "hDAV/" ++ showVersion version) >> f) >>= \x -> case x of     Left e -> error e     Right r -> return r++ingestCreds :: String -> Maybe String -> Maybe String -> IO (B.ByteString, B.ByteString)+ingestCreds _ Nothing _ = return (B.empty, B.empty)+ingestCreds _ (Just u) (Just p) = return (BU.fromString u, BU.fromString p)+ingestCreds q (Just u) Nothing = do+    mnewp <- runInputT SCH.defaultSettings $ getPassword (Just '*') (concat ["Password for ", u, " at ", q, ": "])+    return (BU.fromString u, maybe B.empty BU.fromString mnewp)