module Network.IPFS.Get
  ( getFile
  , getFileOrDirectory
  ) where

import qualified Network.IPFS.Internal.UTF8 as UTF8
import           Network.IPFS.Local.Class   as IPFS
import           Network.IPFS.Prelude

import           Data.ByteString.Lazy.Char8 as CL
import qualified RIO.ByteString.Lazy        as Lazy
import qualified RIO.Text                   as Text

import qualified Network.IPFS.File.Types    as File
import           Network.IPFS.Get.Error     as IPFS.Get
import qualified Network.IPFS.Process.Error as Process
import           Network.IPFS.Types         as IPFS

getFileOrDirectory :: MonadLocalIPFS m => IPFS.CID -> m (Either IPFS.Get.Error CL.ByteString)
getFileOrDirectory :: forall (m :: * -> *).
MonadLocalIPFS m =>
CID -> m (Either Error ByteString)
getFileOrDirectory cid :: CID
cid@(IPFS.CID Text
hash) = forall (m :: * -> *).
MonadLocalIPFS m =>
[Opt] -> ByteString -> m (Either Error ByteString)
IPFS.runLocal [Opt
"get", Text -> Opt
Text.unpack Text
hash] ByteString
"" forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
  Right ByteString
contents -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a b. b -> Either a b
Right ByteString
contents
  Left Error
err -> case Error
err of
    Process.Timeout Natural
secs   -> forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. a -> Either a b
Left forall a b. (a -> b) -> a -> b
$ CID -> Natural -> Error
TimedOut CID
cid Natural
secs
    Process.UnknownErr ByteString
raw -> forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. a -> Either a b
Left forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Error
UnknownErr forall a b. (a -> b) -> a -> b
$ forall a. Show a => a -> Text
UTF8.textShow ByteString
raw

getFile :: MonadLocalIPFS m => IPFS.CID -> m (Either IPFS.Get.Error File.Serialized)
getFile :: forall (m :: * -> *).
MonadLocalIPFS m =>
CID -> m (Either Error Serialized)
getFile cid :: CID
cid@(IPFS.CID Text
hash) = forall (m :: * -> *).
MonadLocalIPFS m =>
[Opt] -> ByteString -> m (Either Error ByteString)
IPFS.runLocal [Opt
"cat"] (Text -> ByteString
UTF8.textToLazyBS Text
hash) forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
  Right ByteString
contents -> forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. b -> Either a b
Right forall a b. (a -> b) -> a -> b
$ ByteString -> Serialized
File.Serialized ByteString
contents
  Left Error
err -> case Error
err of
    Process.Timeout Natural
secs -> forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. a -> Either a b
Left forall a b. (a -> b) -> a -> b
$ CID -> Natural -> Error
TimedOut CID
cid Natural
secs
    Process.UnknownErr ByteString
raw ->
      if ByteString -> ByteString -> Bool
Lazy.isPrefixOf ByteString
"Error: invalid 'ipfs ref' path" ByteString
raw
        then forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. a -> Either a b
Left forall a b. (a -> b) -> a -> b
$ Text -> Error
InvalidCID Text
hash
        else forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. a -> Either a b
Left forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Error
UnknownErr forall a b. (a -> b) -> a -> b
$ forall a. Show a => a -> Text
UTF8.textShow ByteString
raw