skylark-client (empty) → 0.1.0
raw patch · 5 files changed
+162/−0 lines, 5 filesdep +asyncdep +basedep +conduitsetup-changed
Dependencies added: async, base, conduit, conduit-extra, http-conduit, http-types, optparse-generic, preamble, resourcet, shakers, skylark-client
Files
- Setup.hs +2/−0
- Shakefile.hs +33/−0
- main/skylark-client.hs +21/−0
- skylark-client.cabal +44/−0
- src/Network/Skylark/Client.hs +62/−0
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ Shakefile.hs view
@@ -0,0 +1,33 @@+#!/usr/bin/env stack+{- stack+ runghc+ --package shakers+ -}++{-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE OverloadedStrings #-}++-- | Shake makefile for project.+--+import Development.Shakers++-- | Main entry point.+--+main :: IO ()+main = shakeMain $ do+ let pats =+ [ "stack.yaml"+ , "Shakefile.hs"+ , "main//*.hs"+ , "src//*.hs"+ ]++ -- | Imported rules.+ --+ hsRules "."+ stackRules "." pats+ cabalRules "." "skylark-client.cabal"++ -- | Default things to run.+ --+ want [ fakeFile "lint", fakeFile "format" ]
+ main/skylark-client.hs view
@@ -0,0 +1,21 @@+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE OverloadedStrings #-}++import Data.Conduit.Binary+import Network.Skylark.Client+import Options.Generic+import Preamble+import System.IO++data Args = Args+ { url :: String+ , device :: ByteString+ } deriving (Show, Generic)++instance ParseRecord Args++main :: IO ()+main = do+ args <- getRecord "NTRIP Client"+ runSkylark (url args) (device args) (sourceHandle stdin) (sinkHandle stdout)
+ skylark-client.cabal view
@@ -0,0 +1,44 @@+name: skylark-client+version: 0.1.0+synopsis: Skylark client.+description: Skylark network client.+homepage: https://github.com/githubuser/skylark-client#readme+license: BSD3+author: Swift Navigation Inc.+maintainer: Mark Fine <dev@swiftnav.com>+copyright: Copyright (C) 2017 Swift Navigation, Inc.+category: Network+build-type: Simple+cabal-version: >= 1.22++library+ hs-source-dirs: src+ exposed-modules: Network.Skylark.Client+ ghc-options: -Wall+ default-language: Haskell2010+ build-depends: async+ , base == 4.8.*+ , conduit+ , conduit-extra+ , http-conduit+ , http-types+ , preamble+ , resourcet++executable skylark-client+ hs-source-dirs: main+ main-is: skylark-client.hs+ ghc-options: -threaded -rtsopts -with-rtsopts=-N -Wall -O2+ default-language: Haskell2010+ build-depends: base+ , conduit-extra+ , optparse-generic+ , preamble+ , skylark-client++executable shake-skylark-client+ main-is: Shakefile.hs+ ghc-options: -threaded -rtsopts -with-rtsopts=-N -Wall -O2+ default-language: Haskell2010+ build-depends: base == 4.8.*+ , shakers
+ src/Network/Skylark/Client.hs view
@@ -0,0 +1,62 @@+{-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE OverloadedStrings #-}++module Network.Skylark.Client+ ( runSkylark+ ) where++import Control.Concurrent.Async+import Control.Monad.Trans.Resource+import Data.Conduit+import Network.HTTP.Conduit+import Network.HTTP.Types+import Network.HTTP.Types.Header+import Preamble++{-# ANN module ("HLint: ignore Redundant flip"::String) #-}++-- | Device-Uid Header+--+hDevice :: HeaderName+hDevice = "Device-Uid"++-- | SBPv2 Content-Type+--+sbpContentType :: ByteString+sbpContentType = "application/vnd.swiftnav.broker.v1+sbp2"++-- | Download data from Skylark to sink.+--+download :: MonadIO m => ByteString -> Manager -> Request -> Sink ByteString (ResourceT IO) () -> m ()+download device manager request sink =+ liftIO $ runResourceT $ do+ response <- flip http manager request+ { method = methodGet+ , requestHeaders =+ [ (hAccept, sbpContentType)+ , (hDevice, device)+ , (hPragma, "proxy")+ ]+ }+ responseBody response $$+- sink++-- | Upload data to Skylark from source.+--+upload :: MonadIO m => ByteString -> Manager -> Request -> Source (ResourceT IO) ByteString -> m ()+upload device manager request source =+ void $ flip httpLbs manager request+ { method = methodPut+ , requestHeaders =+ [ (hContentType, sbpContentType)+ , (hDevice, device)+ ]+ , requestBody = requestBodySourceChunked source+ }++-- | Run Skylark client.+--+runSkylark :: (MonadIO m, MonadThrow m) => String -> ByteString -> Source (ResourceT IO) ByteString -> Sink ByteString (ResourceT IO) () -> m ()+runSkylark url device source sink = do+ manager <- liftIO $ newManager tlsManagerSettings+ request <- parseRequest url+ liftIO $ void $ concurrently (upload device manager request source) (download device manager request sink)