syncthing-hs 0.1.1.0 → 0.1.2.0
raw patch · 18 files changed
+274/−192 lines, 18 filesdep +exceptionsdep ~aesondep ~connectiondep ~eitherPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependencies added: exceptions
Dependency ranges changed: aeson, connection, either, http-client, http-client-tls, text, transformers, unordered-containers
API changes (from Hackage documentation)
- Network.Syncthing: instance MonadSync IO
- Network.Syncthing.Internal: _pApiKey :: SyncConfig -> Maybe Text
- Network.Syncthing.Internal: _pAuth :: SyncConfig -> Maybe Auth
- Network.Syncthing.Internal: _pHttps :: SyncConfig -> Bool
- Network.Syncthing.Internal: _pManager :: SyncConfig -> Either ManagerSettings Manager
- Network.Syncthing.Internal: _pServer :: SyncConfig -> Server
+ Network.Syncthing: SyncConfig :: Server -> Maybe Text -> Maybe Auth -> Bool -> Either ManagerSettings Manager -> SyncConfig
+ Network.Syncthing: apiKey :: SyncConfig -> Maybe Text
+ Network.Syncthing: auth :: SyncConfig -> Maybe Auth
+ Network.Syncthing: https :: SyncConfig -> Bool
+ Network.Syncthing: manager :: SyncConfig -> Either ManagerSettings Manager
+ Network.Syncthing: server :: SyncConfig -> Server
+ Network.Syncthing.Get: report :: MonadSync m => SyncM m UsageReport
+ Network.Syncthing.Internal: apiKey :: SyncConfig -> Maybe Text
+ Network.Syncthing.Internal: auth :: SyncConfig -> Maybe Auth
+ Network.Syncthing.Internal: https :: SyncConfig -> Bool
+ Network.Syncthing.Internal: manager :: SyncConfig -> Either ManagerSettings Manager
+ Network.Syncthing.Internal: pApiKey :: Lens' SyncConfig (Maybe Text)
+ Network.Syncthing.Internal: pAuth :: Lens' SyncConfig (Maybe Auth)
+ Network.Syncthing.Internal: pHttps :: Lens' SyncConfig Bool
+ Network.Syncthing.Internal: pManager :: Lens' SyncConfig (Either ManagerSettings Manager)
+ Network.Syncthing.Internal: pServer :: Lens' SyncConfig Server
+ Network.Syncthing.Internal: server :: SyncConfig -> Server
+ Network.Syncthing.Internal: syncErrHandler :: MonadThrow m => HttpException -> m (Either SyncError a)
+ Network.Syncthing.Internal: syncthingM :: MonadCatch m => SyncConfig -> SyncM m a -> m (SyncResult a)
+ Network.Syncthing.Types: UsageReport :: Integer -> Integer -> Text -> Integer -> Integer -> Int -> Int -> Text -> Double -> Integer -> Integer -> Text -> Text -> UsageReport
+ Network.Syncthing.Types: data UsageReport
+ Network.Syncthing.Types: getFolderMaxFiles :: UsageReport -> Integer
+ Network.Syncthing.Types: getFolderMaxMiB :: UsageReport -> Integer
+ Network.Syncthing.Types: getLongVersionR :: UsageReport -> Text
+ Network.Syncthing.Types: getMemorySize :: UsageReport -> Integer
+ Network.Syncthing.Types: getMemoryUsageMiB :: UsageReport -> Integer
+ Network.Syncthing.Types: getNumDevices :: UsageReport -> Int
+ Network.Syncthing.Types: getNumFolders :: UsageReport -> Int
+ Network.Syncthing.Types: getPlatform :: UsageReport -> Text
+ Network.Syncthing.Types: getSHA256Perf :: UsageReport -> Double
+ Network.Syncthing.Types: getTotFiles :: UsageReport -> Integer
+ Network.Syncthing.Types: getTotMiB :: UsageReport -> Integer
+ Network.Syncthing.Types: getUniqueId :: UsageReport -> Text
+ Network.Syncthing.Types: getVersionR :: UsageReport -> Text
Files
- Network/Syncthing.hs +33/−99
- Network/Syncthing/Get.hs +7/−2
- Network/Syncthing/Internal/Config.hs +69/−10
- Network/Syncthing/Internal/Error.hs +11/−1
- Network/Syncthing/Internal/Lens.hs +0/−16
- Network/Syncthing/Internal/Monad.hs +23/−10
- Network/Syncthing/Internal/Request.hs +8/−9
- Network/Syncthing/Internal/Types.hs +19/−18
- Network/Syncthing/Session.hs +6/−6
- Network/Syncthing/Types.hs +1/−0
- Network/Syncthing/Types/DeviceId.hs +4/−2
- Network/Syncthing/Types/UsageReport.hs +47/−0
- changelog.md +6/−0
- syncthing-hs.cabal +20/−19
- tests/Properties/JsonArbitrary.hs +1/−0
- tests/Properties/JsonInstances.hs +17/−0
- tests/Properties/JsonProperties.hs +1/−0
- tests/UnitTests/Requests.hs +1/−0
Network/Syncthing.hs view
@@ -26,7 +26,7 @@ -- import "Control.Monad" ('Control.Monad.liftM2') -- import "Control.Lens" (('Control.Lens.&'), ('Control.Lens..~'), ('Control.Lens.?~')) -- import "Network.Syncthing"--- import qualified "Network.Syncthing.Get" as Get +-- import qualified "Network.Syncthing.Get" as Get -- -- \-\- A single Syncthing request. -- single = 'syncthing' 'defaultConfig' Get.'Network.Syncthing.Get.ping'@@ -59,7 +59,7 @@ , withManager' -- * Configuration- , SyncConfig+ , SyncConfig(..) , pServer , pApiKey , pAuth@@ -73,44 +73,37 @@ -- * Manager Settings , defaultManagerSettings , noSSLVerifyManagerSettings- , setResponseTimeout + , setResponseTimeout -- * Error Handling , DeviceError(..) , SyncError(..) + -- * Manual Session Handling+ , module Network.Syncthing.Session+ -- * Utility functions , module Network.Syncthing.Utils -- * Types- , module Network.Syncthing.Types + , module Network.Syncthing.Types ) where -import Control.Applicative ((<$>))-import Control.Exception (catch, throwIO)-import Control.Lens (Lens', (&), (.~), (^.))-import Control.Monad ((<=<))-import Control.Monad.Trans.Either (runEitherT)-import Control.Monad.Trans.Reader (runReaderT)-import Data.ByteString.Lazy (fromStrict)-import Data.Text (Text)-import Network.Connection (TLSSettings (..))-import qualified Network.HTTP.Client as HTTP-import Network.HTTP.Client.TLS (mkManagerSettings, tlsManagerSettings)-import qualified Network.Wreq as W+import Network.Connection (TLSSettings(..))+import qualified Network.HTTP.Client as HTTP+import Network.HTTP.Client.TLS (mkManagerSettings, tlsManagerSettings) import Network.Syncthing.Internal.Config import Network.Syncthing.Internal.Error-import qualified Network.Syncthing.Internal.Lens as PL import Network.Syncthing.Internal.Monad+import Network.Syncthing.Session import Network.Syncthing.Types import Network.Syncthing.Utils --- | Use Wreq's getWith and postWith functions when running in IO-instance MonadSync IO where- getMethod o s = (^. W.responseBody) <$> W.getWith o s- postMethod o s p = (^. W.responseBody) <$> W.postWith o s p+-- | Run Syncthing requests.+syncthing :: SyncConfig -> SyncM IO a -> IO (SyncResult a)+syncthing = syncthingM -- | Create a default configuration with a new manager for connection -- sharing. The manager is released after running the Syncthing actions(s).@@ -134,7 +127,7 @@ withManager :: (SyncConfig -> IO a) -> IO a withManager = withManager' defaultManagerSettings --- | Create a manager with disabled SSL certificate verification. +-- | Create a manager with disabled SSL certificate verification. -- This is equivalent to: -- -- @@@ -163,42 +156,36 @@ withManager' :: HTTP.ManagerSettings -> (SyncConfig -> IO a) -> IO a withManager' settings act = HTTP.withManager settings $ \mgr ->- act $ defaultConfig & pManager .~ Right mgr---- | Run Syncthing requests.-syncthing :: SyncConfig -> SyncM IO a -> IO (SyncResult a)-syncthing config action =- runReaderT (runEitherT $ runSyncthing action) config `catch` handler- where- handler e@(HTTP.StatusCodeException _ headers _) =- maybe (throwIO e) (return . Left) $ maybeSyncError headers- handler unhandledErr = throwIO unhandledErr- maybeSyncError = decodeError . fromStrict <=< lookup "X-Response-Body-Start"+ act $ defaultConfig { manager = Right mgr } -- | The default Syncthing configuration. Customize it to your needs by using--- the SyncConfig lenses.+-- record syntax or the SyncConfig lenses. -- -- /Example:/ -- -- >>> defaultConfig--- SyncConfig { pServer = "127.0.0.1:8080", pApiKey = Nothing, pAuth = Nothing, pHttps = False, pManager = Left _ }+-- SyncConfig { server = "127.0.0.1:8080", apiKey = Nothing, auth = Nothing, https = False, manager = Left _ }+--+-- >>> defaultConfig { server = "192.168.0.10:8080", apiKey = Just "XXXX" }+-- SyncConfig { server = "192.168.0.10:8080", apiKey = Just "XXXX", auth = Nothing, https = False, manager = Left _ }+-- -- >>> defaultConfig & pServer .~ "192.168.0.10:8080" & pApiKey ?~ "XXXX"--- SyncConfig { pServer = "192.168.0.10:8080", pApiKey = Just "XXXX", pAuth = Nothing, pHttps = False, pManager = Left _ }+-- SyncConfig { server = "192.168.0.10:8080", apiKey = Just "XXXX", auth = Nothing, https = False, manager = Left _ } defaultConfig :: SyncConfig defaultConfig = SyncConfig {- _pServer = "127.0.0.1:8080"- , _pApiKey = Nothing- , _pAuth = Nothing- , _pHttps = False- , _pManager = Left defaultManagerSettings+ server = "127.0.0.1:8080"+ , apiKey = Nothing+ , auth = Nothing+ , https = False+ , manager = Left defaultManagerSettings } --- | The default folder name.+-- | The Syncthing default folder (-> "default"). defaultFolder :: FolderName defaultFolder = "default" defaultResponseTimeout :: Int-defaultResponseTimeout = 300000000 +defaultResponseTimeout = 300000000 -- | Set the response timeout (in microseconds). Default is 300 seconds. setResponseTimeout :: HTTP.ManagerSettings -> Int -> HTTP.ManagerSettings@@ -206,64 +193,11 @@ -- | The default manager settings used by 'defaultConfig'. defaultManagerSettings :: HTTP.ManagerSettings-defaultManagerSettings = - tlsManagerSettings `setResponseTimeout` defaultResponseTimeout +defaultManagerSettings =+ tlsManagerSettings `setResponseTimeout` defaultResponseTimeout -- | Alternative manager settings with disabled SSL certificate verification. noSSLVerifyManagerSettings :: HTTP.ManagerSettings-noSSLVerifyManagerSettings = ms `setResponseTimeout` defaultResponseTimeout +noSSLVerifyManagerSettings = ms `setResponseTimeout` defaultResponseTimeout where ms = mkManagerSettings (TLSSettingsSimple True False False) Nothing---- | A lens for configuring the server address. Use the ADDRESS:PORT format.------ /Example:/------ @--- let cfg = 'defaultConfig' 'Control.Lens.&' 'pApiKey' 'Control.Lens..~' \"192.168.0.10:8080\"--- 'syncthing' cfg Get.'Network.Syncthing.Get.ping'--- @-pServer :: Lens' SyncConfig Server-pServer = PL.pServer---- | A lens for specifying the Syncthing API Key.------ /Example:/------ @--- let cfg = 'defaultConfig' 'Control.Lens.&' 'pApiKey' 'Control.Lens.?~' \"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\"--- 'syncthing' cfg Get.'Network.Syncthing.Get.ping'--- @-pApiKey :: Lens' SyncConfig (Maybe Text)-pApiKey = PL.pApiKey---- | A lens for configuring request authentication provided by the --- 'Network.Wreq' package (see 'Network.Wreq.Auth').------ /Example:/------ @--- import qualified "Network.Wreq" as Wreq------ let cfg = 'defaultConfig' 'Control.Lens.&' 'pHttps' 'Control.Lens..~' True--- 'Control.Lens.&' 'pAuth' 'Control.Lens.?~' Wreq.'Network.Wreq.basicAuth' \"user\" \"pass\"--- 'syncthing' cfg Get.'Network.Syncthing.Get.ping'--- @-pAuth :: Lens' SyncConfig (Maybe W.Auth)-pAuth = PL.pAuth---- | A lens for enabling HTTPS usage.------ /Example:/------ @--- let cfg = 'defaultConfig' 'Control.Lens.&' 'pHttps' 'Control.Lens..~' True--- 'syncthing' cfg Get.'Network.Syncthing.Get.ping'--- @-pHttps :: Lens' SyncConfig Bool-pHttps = PL.pHttps---- | A lens for specifying your own ManagerSettings/Manager. For more--- information, please refer to the "Network.HTTP.Client" package.-pManager :: Lens' SyncConfig (Either HTTP.ManagerSettings HTTP.Manager)-pManager = PL.pManager
Network/Syncthing/Get.hs view
@@ -28,6 +28,7 @@ , ignores , model , need+ , report , sync , system , tree@@ -99,7 +100,7 @@ -- | Fetch the ignores list. ignores :: MonadSync m => FolderName -> SyncM m Ignore ignores folder = query $ getRequest { path = "/rest/ignores"- , params = [ ("folder", folder) ]+ , params = [("folder", folder)] } -- | Get information about the current status of a folder.@@ -112,8 +113,12 @@ -- to become in sync. need :: MonadSync m => FolderName -> SyncM m Need need folder = query $ getRequest { path = "/rest/need"- , params = [ ("folder", folder) ]+ , params = [("folder", folder)] }++-- | Returns the data sent in the anonymous usage report.+report :: MonadSync m => SyncM m UsageReport+report = query $ getRequest { path = "/rest/report" } -- | Determine whether the config is in sync. sync :: MonadSync m => SyncM m Bool
Network/Syncthing/Internal/Config.hs view
@@ -4,8 +4,14 @@ module Network.Syncthing.Internal.Config ( SyncConfig(..)+ , pServer+ , pApiKey+ , pAuth+ , pHttps+ , pManager ) where +import Control.Lens (Lens', lens) import qualified Data.Text as T import Network.HTTP.Client (Manager, ManagerSettings) import qualified Network.Wreq as W@@ -16,23 +22,76 @@ -- | The Syncthing configuration for specifying the Syncthing server, -- authentication, the API Key etc. data SyncConfig = SyncConfig {- _pServer :: Server- , _pApiKey :: Maybe T.Text- , _pAuth :: Maybe W.Auth- , _pHttps :: Bool- , _pManager :: Either ManagerSettings Manager+ server :: Server+ , apiKey :: Maybe T.Text+ , auth :: Maybe W.Auth+ , https :: Bool+ , manager :: Either ManagerSettings Manager } instance Show SyncConfig where show SyncConfig{..} = concat [ "SyncConfig { "- , "pServer = ", show _pServer- , ", pApiKey = ", show _pApiKey- , ", pAuth = ", show _pAuth- , ", pHttps = ", show _pHttps- , ", pManager = ", case _pManager of+ , "server = ", show server+ , ", apiKey = ", show apiKey+ , ", auth = ", show auth+ , ", https = ", show https+ , ", manager = ", case manager of Left _ -> "Left _" Right _ -> "Right _" , " }" ]++-- | A lens for configuring the server address. Use the ADDRESS:PORT format.+--+-- /Example:/+--+-- @+-- let cfg = 'defaultConfig' 'Control.Lens.&' 'pServer' 'Control.Lens..~' \"192.168.0.10:8080\"+-- 'syncthing' cfg Get.'Network.Syncthing.Get.ping'+-- @+pServer :: Lens' SyncConfig Server+pServer = lens server (\f new -> f { server = new })++-- | A lens for specifying the Syncthing API Key.+--+-- /Example:/+--+-- @+-- let cfg = 'defaultConfig' 'Control.Lens.&' 'pApiKey' 'Control.Lens.?~' \"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\"+-- 'syncthing' cfg Get.'Network.Syncthing.Get.ping'+-- @+pApiKey :: Lens' SyncConfig (Maybe T.Text)+pApiKey = lens apiKey (\f new -> f { apiKey = new })++-- | A lens for configuring request authentication provided by the+-- 'Network.Wreq' package (see 'Network.Wreq.Auth').+--+-- /Example:/+--+-- @+-- import qualified "Network.Wreq" as Wreq+--+-- let cfg = 'defaultConfig' 'Control.Lens.&' 'pHttps' 'Control.Lens..~' True+-- 'Control.Lens.&' 'pAuth' 'Control.Lens.?~' Wreq.'Network.Wreq.basicAuth' \"user\" \"pass\"+-- 'syncthing' cfg Get.'Network.Syncthing.Get.ping'+-- @+pAuth :: Lens' SyncConfig (Maybe W.Auth)+pAuth = lens auth (\f new -> f { auth = new })++-- | A lens for enabling HTTPS usage.+--+-- /Example:/+--+-- @+-- let cfg = 'defaultConfig' 'Control.Lens.&' 'pHttps' 'Control.Lens..~' True+-- 'syncthing' cfg Get.'Network.Syncthing.Get.ping'+-- @+pHttps :: Lens' SyncConfig Bool+pHttps = lens https (\f new -> f { https = new })++-- | A lens for specifying your own ManagerSettings/Manager. For more+-- information, please refer to the "Network.HTTP.Client" package.+pManager :: Lens' SyncConfig (Either ManagerSettings Manager)+pManager = lens manager (\f new -> f { manager = new })
Network/Syncthing/Internal/Error.hs view
@@ -5,16 +5,19 @@ module Network.Syncthing.Internal.Error ( DeviceError(..) , SyncError(..)+ , syncErrHandler , decodeDeviceError , decodeError ) where -import Control.Exception (Exception)+import Control.Monad ((<=<))+import Control.Monad.Catch (Exception, MonadThrow, throwM) import qualified Data.ByteString.Lazy.Char8 as BS import Data.List (find) import Data.Maybe (fromMaybe) import qualified Data.Text as T import Data.Typeable (Typeable)+import qualified Network.HTTP.Client as HTTP import Text.Regex.Posix ((=~)) @@ -35,6 +38,13 @@ instance Exception SyncError ++syncErrHandler :: MonadThrow m => HTTP.HttpException -> m (Either SyncError a)+syncErrHandler e@(HTTP.StatusCodeException _ headers _) =+ maybe (throwM e) (return . Left) $ extractErr headers+ where+ extractErr = decodeError . BS.fromStrict <=< lookup "X-Response-Body-Start"+syncErrHandler unhandledErr = throwM unhandledErr deviceIdLength, deviceIdCheckDigit :: String deviceIdLength = "device ID invalid: incorrect length"
− Network/Syncthing/Internal/Lens.hs
@@ -1,16 +0,0 @@--{-# LANGUAGE TemplateHaskell #-}--module Network.Syncthing.Internal.Lens- ( pServer- , pApiKey- , pAuth- , pHttps- , pManager- ) where--import Control.Lens (makeLenses)-import Network.Syncthing.Internal.Config (SyncConfig)--$(makeLenses ''SyncConfig)-
Network/Syncthing/Internal/Monad.hs view
@@ -3,9 +3,10 @@ {-# LANGUAGE OverloadedStrings #-} module Network.Syncthing.Internal.Monad- ( SyncResult + ( SyncResult , SyncM(..) , MonadSync(..)+ , syncthingM , liftEither , liftReader , liftInner@@ -13,16 +14,18 @@ , liftRight ) where -import Control.Applicative (Applicative)-import Control.Monad.Trans.Class (lift)-import Control.Monad.Trans.Either (EitherT, left, right)-import Control.Monad.Trans.Reader (ReaderT)-import Data.Aeson (Value)-import Data.ByteString.Lazy (ByteString)-import qualified Network.Wreq as W+import Control.Applicative (Applicative, (<$>))+import Control.Lens ((^.))+import Control.Monad.Catch (MonadCatch, catch)+import Control.Monad.Trans.Class (lift)+import Control.Monad.Trans.Either (EitherT, left, right, runEitherT)+import Control.Monad.Trans.Reader (ReaderT, runReaderT)+import Data.Aeson (Value)+import Data.ByteString.Lazy (ByteString)+import qualified Network.Wreq as W -import Network.Syncthing.Internal.Config-import Network.Syncthing.Internal.Error+import Network.Syncthing.Internal.Config+import Network.Syncthing.Internal.Error -- | The result type of Syncthing requests.@@ -36,6 +39,16 @@ class Monad m => MonadSync m where getMethod :: W.Options -> String -> m ByteString postMethod :: W.Options -> String -> Value -> m ByteString++-- | Use Wreq's getWith and postWith functions when running in IO+instance MonadSync IO where+ getMethod o s = (^. W.responseBody) <$> W.getWith o s+ postMethod o s p = (^. W.responseBody) <$> W.postWith o s p++-- | Run Syncthing requests.+syncthingM :: MonadCatch m => SyncConfig -> SyncM m a -> m (SyncResult a)+syncthingM config action =+ runReaderT (runEitherT $ runSyncthing action) config `catch` syncErrHandler liftEither :: Monad m => EitherT SyncError (ReaderT SyncConfig m) a -> SyncM m a liftEither = SyncM
Network/Syncthing/Internal/Request.hs view
@@ -26,7 +26,6 @@ import Network.Syncthing.Internal.Config import Network.Syncthing.Internal.Error-import Network.Syncthing.Internal.Lens import Network.Syncthing.Internal.Monad @@ -58,9 +57,9 @@ request req = do config <- liftReader ask let opts = prepareOptions config (params req) W.defaults- let server = T.unpack $ config ^. pServer+ let server' = T.unpack $ config ^. pServer let proto = if (config ^. pHttps) then "https://" else "http://"- let url = concat [proto, server, path req]+ let url = concat [proto, server', path req] liftInner $ case method req of Get -> getMethod opts url@@ -74,12 +73,12 @@ . setParams . setJsonHeader where- setManager mgr = (& W.manager .~ mgr)- setAuth authInfo = (& W.auth .~ authInfo)- setJsonHeader = (& W.header "Accept" .~ ["application/json"])- setParams = (& W.params .~ params')- setApiKey (Just apiKey) = (& W.header "X-API-Key" .~ [encodeUtf8 apiKey])- setApiKey Nothing = id+ setManager mgr = (& W.manager .~ mgr)+ setAuth authInfo = (& W.auth .~ authInfo)+ setJsonHeader = (& W.header "Accept" .~ ["application/json"])+ setParams = (& W.params .~ params')+ setApiKey (Just apiKey') = (& W.header "X-API-Key" .~ [encodeUtf8 apiKey'])+ setApiKey Nothing = id get :: HttpMethod get = Get
Network/Syncthing/Internal/Types.hs view
@@ -2,25 +2,26 @@ {-# OPTIONS_HADDOCK hide #-} module Network.Syncthing.Internal.Types- ( module Ty + ( module Ty ) where -import Network.Syncthing.Types.CacheEntry as Ty-import Network.Syncthing.Types.Common as Ty-import Network.Syncthing.Types.Completion as Ty-import Network.Syncthing.Types.Config as Ty-import Network.Syncthing.Types.Connection as Ty-import Network.Syncthing.Types.DeviceId as Ty-import Network.Syncthing.Types.DirTree as Ty-import Network.Syncthing.Types.Error as Ty-import Network.Syncthing.Types.Ignore as Ty-import Network.Syncthing.Types.Model as Ty-import Network.Syncthing.Types.Need as Ty-import Network.Syncthing.Types.Ping as Ty-import Network.Syncthing.Types.Sync as Ty-import Network.Syncthing.Types.System as Ty-import Network.Syncthing.Types.SystemMsg as Ty-import Network.Syncthing.Types.Upgrade as Ty-import Network.Syncthing.Types.Version as Ty+import Network.Syncthing.Types.CacheEntry as Ty+import Network.Syncthing.Types.Common as Ty+import Network.Syncthing.Types.Completion as Ty+import Network.Syncthing.Types.Config as Ty+import Network.Syncthing.Types.Connection as Ty+import Network.Syncthing.Types.DeviceId as Ty+import Network.Syncthing.Types.DirTree as Ty+import Network.Syncthing.Types.Error as Ty+import Network.Syncthing.Types.Ignore as Ty+import Network.Syncthing.Types.Model as Ty+import Network.Syncthing.Types.Need as Ty+import Network.Syncthing.Types.Ping as Ty+import Network.Syncthing.Types.Sync as Ty+import Network.Syncthing.Types.System as Ty+import Network.Syncthing.Types.SystemMsg as Ty+import Network.Syncthing.Types.Upgrade as Ty+import Network.Syncthing.Types.UsageReport as Ty+import Network.Syncthing.Types.Version as Ty
Network/Syncthing/Session.hs view
@@ -20,7 +20,6 @@ -- -- import "Control.Lens" (('Control.Lens.&'), ('Control.Lens..~')) -- import "Network.Syncthing"--- import "Network.Syncthing.Session" -- import qualified "Network.Syncthing.Get" as Get -- -- \-\- Customized configuration.@@ -59,11 +58,12 @@ , runSyncSession ) where -import Control.Exception (bracket)-import Control.Lens ((&), (.~), (^.))-import Network.HTTP.Client (closeManager, newManager)+import Control.Exception (bracket)+import Control.Lens ((&), (.~), (^.))+import Network.HTTP.Client (closeManager, newManager) -import Network.Syncthing+import Network.Syncthing.Internal.Config+import Network.Syncthing.Internal.Monad -- | Holds the session configuration and the connection manager.@@ -88,7 +88,7 @@ -- | Run a Syncthing request using connection sharing within a session. runSyncSession :: SyncSession -> SyncM IO a -> IO (SyncResult a)-runSyncSession = syncthing . getConfig+runSyncSession = syncthingM . getConfig -- | Create a new session using the provided configuration, run the -- action and close the session.
Network/Syncthing/Types.hs view
@@ -42,6 +42,7 @@ , System(..) , SystemMsg(..) , Upgrade(..)+ , UsageReport(..) , Version(..) ) where
Network/Syncthing/Types/DeviceId.hs view
@@ -6,8 +6,9 @@ import Control.Applicative ((<$>)) import Control.Monad (MonadPlus (mzero))-import Data.Aeson (FromJSON, Value (..), parseJSON, (.:))-import Data.HashMap.Lazy (member)+import Data.Aeson (FromJSON, Value(..), parseJSON, (.:))+import Data.Aeson.Types (Parser, Object)+import Data.HashMap.Strict (member) import Data.Text () import Network.Syncthing.Internal.Error@@ -20,6 +21,7 @@ result = parseIdResult hasId v parseJSON _ = mzero +parseIdResult :: Bool -> Object -> Parser (Either DeviceError Device) parseIdResult hasId v | hasId = Right <$> v .: "id" | otherwise = Left <$> (decodeDeviceError <$> v .: "error")
+ Network/Syncthing/Types/UsageReport.hs view
@@ -0,0 +1,47 @@++{-# LANGUAGE OverloadedStrings #-}++module Network.Syncthing.Types.UsageReport+ ( UsageReport(..)+ ) where++import Control.Applicative ((<$>), (<*>))+import Control.Monad (MonadPlus (mzero))+import Data.Aeson (FromJSON, Value (..), parseJSON, (.:))+import Data.Text (Text)+++-- | Information about the data sent in the anonymous usage report.+data UsageReport = UsageReport {+ getFolderMaxFiles :: Integer+ , getFolderMaxMiB :: Integer + , getLongVersionR :: Text+ , getMemorySize :: Integer+ , getMemoryUsageMiB :: Integer+ , getNumDevices :: Int+ , getNumFolders :: Int+ , getPlatform :: Text+ , getSHA256Perf :: Double+ , getTotFiles :: Integer+ , getTotMiB :: Integer+ , getUniqueId :: Text+ , getVersionR :: Text+ } deriving (Eq, Show)++instance FromJSON UsageReport where+ parseJSON (Object v) =+ UsageReport <$> (v .: "folderMaxFiles")+ <*> (v .: "folderMaxMiB")+ <*> (v .: "longVersion")+ <*> (v .: "memorySize")+ <*> (v .: "memoryUsageMiB")+ <*> (v .: "numDevices")+ <*> (v .: "numFolders")+ <*> (v .: "platform")+ <*> (v .: "sha256Perf")+ <*> (v .: "totFiles")+ <*> (v .: "totMiB")+ <*> (v .: "uniqueID")+ <*> (v .: "version")+ parseJSON _ = mzero+
changelog.md view
@@ -1,3 +1,9 @@+0.1.2.0+-------+* Update lower bounds of package dependencies +* Re-export Network.Syncthing.Session by Network.Syncthing+* Add /rest/report GET request+ 0.1.1.0 ------- * Add test-suite source files
syncthing-hs.cabal view
@@ -1,5 +1,5 @@ name: syncthing-hs-version: 0.1.1.0+version: 0.1.2.0 synopsis: Haskell bindings for the Syncthing REST API description: .@@ -32,7 +32,6 @@ Network.Syncthing.Internal.Error Network.Syncthing.Internal.Monad Network.Syncthing.Internal.Request- Network.Syncthing.Internal.Lens Network.Syncthing.Internal.Types Network.Syncthing.Internal.Utils Network.Syncthing.Types.CacheEntry@@ -51,23 +50,25 @@ Network.Syncthing.Types.System Network.Syncthing.Types.SystemMsg Network.Syncthing.Types.Upgrade+ Network.Syncthing.Types.UsageReport Network.Syncthing.Types.Version -- other-extensions: - build-depends: aeson >=0.8.0.1+ build-depends: aeson >=0.7.0.5 , base >=4.5 && <5 , bytestring >=0.9- , connection >= 0.2.3- , containers >= 0.5.5.1- , either >=4.3.1- , http-client >=0.3.1.1- , http-client-tls >=0.2- , lens >=4.5 - , old-locale >= 1.0.0.6- , regex-posix >= 0.95.2- , text >=1.2.0.0- , time >= 1.4.2- , transformers >=0.3.0.0- , unordered-containers >= 0.2.5.1+ , connection >=0.2.2+ , containers >=0.5.5.1+ , either >=4.0+ , exceptions >= 0.5+ , http-client >=0.4.6+ , http-client-tls >=0.2.2+ , lens >=4.5+ , old-locale >=1.0.0.6+ , regex-posix >=0.95.2+ , text >=1.1.1.0+ , time >=1.4.2+ , transformers >=0.2.2.1+ , unordered-containers >=0.2.3.3 , wreq >=0.3.0.0 -- hs-source-dirs: default-language: Haskell2010@@ -75,20 +76,20 @@ test-Suite tests type: exitcode-stdio-1.0 main-is: Test.hs- build-depends: aeson >=0.8.0.1+ build-depends: aeson >=0.7.0.5 , base >=4.5 && <5 , bytestring >=0.9 , containers >= 0.5.5.1 , derive - , either >=4.3.1+ , either >=4.0 , lens >=4.5 , quickcheck-instances , syncthing-hs , tasty , tasty-hunit , tasty-quickcheck- , text >=1.2.0.0- , transformers >=0.3.0.0+ , text >=1.1.1.0+ , transformers >=0.2.2.1 , wreq >=0.3.0.0 other-modules: Properties.ErrorProperties Properties.JsonArbitrary
tests/Properties/JsonArbitrary.hs view
@@ -145,5 +145,6 @@ , ''Error , ''Errors , ''System+ , ''UsageReport ]
tests/Properties/JsonInstances.hs view
@@ -156,3 +156,20 @@ toJSON Dir{..} = toJSON getDirContents toJSON File{..} = toJSON [getModTime, getFileSize] +instance ToJSON UsageReport where+ toJSON UsageReport{..} =+ object [ "folderMaxFiles" .= getFolderMaxFiles + , "folderMaxMiB" .= getFolderMaxMiB + , "longVersion" .= getLongVersionR + , "memorySize" .= getMemorySize + , "memoryUsageMiB" .= getMemoryUsageMiB + , "numDevices" .= getNumDevices + , "numFolders" .= getNumFolders + , "platform" .= getPlatform + , "sha256Perf" .= getSHA256Perf + , "totFiles" .= getTotFiles + , "totMiB" .= getTotMiB + , "uniqueID" .= getUniqueId + , "version" .= getVersionR + ]+
tests/Properties/JsonProperties.hs view
@@ -48,5 +48,6 @@ , genProp "Errors" (prop_json :: Errors -> Bool) , genProp "System" (prop_json :: System -> Bool) , genProp "DirTree" (prop_json :: DirTree -> Bool)+ , genProp "UsageReport" (prop_json :: UsageReport -> Bool) ]
tests/UnitTests/Requests.hs view
@@ -232,6 +232,7 @@ [("folder", "default")] (Get.need "default") , testGet "/rest/config/sync" noParams Get.sync+ , testGet "/rest/report" noParams Get.report , testGet "/rest/system" noParams Get.system , testGet "/rest/tree" [("folder", "default")]