{-# LANGUAGE ApplicativeDo #-} {-# LANGUAGE DuplicateRecordFields #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ScopedTypeVariables #-} module Simplex.Chat.Options ( ChatOpts (..), CoreChatOpts (..), CreateBotOpts (..), ChatCmdLog (..), chatOptsP, coreChatOptsP, getChatOpts, protocolServersP, defaultHostMode, printDbOpts, ) where import Control.Logger.Simple (LogLevel (..)) import qualified Data.Attoparsec.ByteString.Char8 as A import qualified Data.ByteString.Char8 as B import Data.Maybe (fromMaybe) import Data.Text (Text) import qualified Data.Text as T import Data.Text.Encoding (encodeUtf8) import Numeric.Natural (Natural) import Options.Applicative import Simplex.Chat.Controller (ChatLogLevel (..), SimpleNetCfg (..), versionNumber, versionString) import Simplex.FileTransfer.Description (mb) import Simplex.Messaging.Client (HostMode (..), SMPWebPortServers (..), SocksMode (..), textToHostMode) import Simplex.Messaging.Encoding.String import Simplex.Messaging.Parsers (parseAll) import Simplex.Messaging.Protocol (ProtoServerWithAuth, ProtocolTypeI, SMPServerWithAuth, XFTPServerWithAuth) import Simplex.Messaging.Transport.Client (SocksProxyWithAuth (..), SocksAuth (..), defaultSocksProxyWithAuth) import Simplex.Chat.Options.DB data ChatOpts = ChatOpts { ChatOpts -> CoreChatOpts coreOptions :: CoreChatOpts, ChatOpts -> String chatCmd :: String, ChatOpts -> Int chatCmdDelay :: Int, ChatOpts -> ChatCmdLog chatCmdLog :: ChatCmdLog, ChatOpts -> Maybe String chatServerPort :: Maybe String, ChatOpts -> Maybe String optFilesFolder :: Maybe FilePath, ChatOpts -> Maybe String optTempDirectory :: Maybe FilePath, ChatOpts -> Bool showReactions :: Bool, ChatOpts -> Bool allowInstantFiles :: Bool, ChatOpts -> Integer autoAcceptFileSize :: Integer, ChatOpts -> Bool muteNotifications :: Bool, ChatOpts -> Bool markRead :: Bool, ChatOpts -> Maybe CreateBotOpts createBot :: Maybe CreateBotOpts, ChatOpts -> Bool maintenance :: Bool } data CoreChatOpts = CoreChatOpts { CoreChatOpts -> ChatDbOpts dbOptions :: ChatDbOpts, CoreChatOpts -> [ProtoServerWithAuth 'PSMP] smpServers :: [SMPServerWithAuth], CoreChatOpts -> [ProtoServerWithAuth 'PXFTP] xftpServers :: [XFTPServerWithAuth], CoreChatOpts -> SimpleNetCfg simpleNetCfg :: SimpleNetCfg, CoreChatOpts -> ChatLogLevel logLevel :: ChatLogLevel, CoreChatOpts -> Bool logConnections :: Bool, CoreChatOpts -> Bool logServerHosts :: Bool, CoreChatOpts -> Maybe LogLevel logAgent :: Maybe LogLevel, CoreChatOpts -> Maybe String logFile :: Maybe FilePath, CoreChatOpts -> Natural tbqSize :: Natural, CoreChatOpts -> Maybe Text deviceName :: Maybe Text, CoreChatOpts -> Bool highlyAvailable :: Bool, CoreChatOpts -> Bool yesToUpMigrations :: Bool, CoreChatOpts -> Maybe String migrationBackupPath :: Maybe FilePath } data CreateBotOpts = CreateBotOpts { CreateBotOpts -> Text botDisplayName :: Text, CreateBotOpts -> Bool allowFiles :: Bool } data ChatCmdLog = CCLAll | CCLMessages | CCLNone deriving (ChatCmdLog -> ChatCmdLog -> Bool (ChatCmdLog -> ChatCmdLog -> Bool) -> (ChatCmdLog -> ChatCmdLog -> Bool) -> Eq ChatCmdLog forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a $c== :: ChatCmdLog -> ChatCmdLog -> Bool == :: ChatCmdLog -> ChatCmdLog -> Bool $c/= :: ChatCmdLog -> ChatCmdLog -> Bool /= :: ChatCmdLog -> ChatCmdLog -> Bool Eq) agentLogLevel :: ChatLogLevel -> LogLevel agentLogLevel :: ChatLogLevel -> LogLevel agentLogLevel = \case ChatLogLevel CLLDebug -> LogLevel LogDebug ChatLogLevel CLLInfo -> LogLevel LogInfo ChatLogLevel CLLWarning -> LogLevel LogWarn ChatLogLevel CLLError -> LogLevel LogError ChatLogLevel CLLImportant -> LogLevel LogInfo coreChatOptsP :: FilePath -> FilePath -> Parser CoreChatOpts coreChatOptsP :: String -> String -> Parser CoreChatOpts coreChatOptsP String appDir String defaultDbName = do ChatDbOpts dbOptions <- String -> String -> Parser ChatDbOpts chatDbOptsP String appDir String defaultDbName [ProtoServerWithAuth 'PSMP] smpServers <- ReadM [ProtoServerWithAuth 'PSMP] -> Mod OptionFields [ProtoServerWithAuth 'PSMP] -> Parser [ProtoServerWithAuth 'PSMP] forall a. ReadM a -> Mod OptionFields a -> Parser a option ReadM [ProtoServerWithAuth 'PSMP] forall (p :: ProtocolType). ProtocolTypeI p => ReadM [ProtoServerWithAuth p] parseProtocolServers ( String -> Mod OptionFields [ProtoServerWithAuth 'PSMP] forall (f :: * -> *) a. HasName f => String -> Mod f a long String "server" Mod OptionFields [ProtoServerWithAuth 'PSMP] -> Mod OptionFields [ProtoServerWithAuth 'PSMP] -> Mod OptionFields [ProtoServerWithAuth 'PSMP] forall a. Semigroup a => a -> a -> a <> Char -> Mod OptionFields [ProtoServerWithAuth 'PSMP] forall (f :: * -> *) a. HasName f => Char -> Mod f a short Char 's' Mod OptionFields [ProtoServerWithAuth 'PSMP] -> Mod OptionFields [ProtoServerWithAuth 'PSMP] -> Mod OptionFields [ProtoServerWithAuth 'PSMP] forall a. Semigroup a => a -> a -> a <> String -> Mod OptionFields [ProtoServerWithAuth 'PSMP] forall (f :: * -> *) a. HasMetavar f => String -> Mod f a metavar String "SERVER" Mod OptionFields [ProtoServerWithAuth 'PSMP] -> Mod OptionFields [ProtoServerWithAuth 'PSMP] -> Mod OptionFields [ProtoServerWithAuth 'PSMP] forall a. Semigroup a => a -> a -> a <> String -> Mod OptionFields [ProtoServerWithAuth 'PSMP] forall (f :: * -> *) a. String -> Mod f a help ( (String "Space-separated list of SMP server(s) to use (each server can have more than one hostname)." String -> String -> String forall a. Semigroup a => a -> a -> a <> String "\n") String -> String -> String forall a. Semigroup a => a -> a -> a <> (String "If you pass multiple servers, surround the entire list in quotes." String -> String -> String forall a. Semigroup a => a -> a -> a <> String "\n") String -> String -> String forall a. Semigroup a => a -> a -> a <> String "Examples: smp1.example.com, \"smp1.example.com smp2.example.com smp3.example.com\"" ) Mod OptionFields [ProtoServerWithAuth 'PSMP] -> Mod OptionFields [ProtoServerWithAuth 'PSMP] -> Mod OptionFields [ProtoServerWithAuth 'PSMP] forall a. Semigroup a => a -> a -> a <> [ProtoServerWithAuth 'PSMP] -> Mod OptionFields [ProtoServerWithAuth 'PSMP] forall (f :: * -> *) a. HasValue f => a -> Mod f a value [] ) [ProtoServerWithAuth 'PXFTP] xftpServers <- ReadM [ProtoServerWithAuth 'PXFTP] -> Mod OptionFields [ProtoServerWithAuth 'PXFTP] -> Parser [ProtoServerWithAuth 'PXFTP] forall a. ReadM a -> Mod OptionFields a -> Parser a option ReadM [ProtoServerWithAuth 'PXFTP] forall (p :: ProtocolType). ProtocolTypeI p => ReadM [ProtoServerWithAuth p] parseProtocolServers ( String -> Mod OptionFields [ProtoServerWithAuth 'PXFTP] forall (f :: * -> *) a. HasName f => String -> Mod f a long String "xftp-server" Mod OptionFields [ProtoServerWithAuth 'PXFTP] -> Mod OptionFields [ProtoServerWithAuth 'PXFTP] -> Mod OptionFields [ProtoServerWithAuth 'PXFTP] forall a. Semigroup a => a -> a -> a <> String -> Mod OptionFields [ProtoServerWithAuth 'PXFTP] forall (f :: * -> *) a. HasMetavar f => String -> Mod f a metavar String "SERVER" Mod OptionFields [ProtoServerWithAuth 'PXFTP] -> Mod OptionFields [ProtoServerWithAuth 'PXFTP] -> Mod OptionFields [ProtoServerWithAuth 'PXFTP] forall a. Semigroup a => a -> a -> a <> String -> Mod OptionFields [ProtoServerWithAuth 'PXFTP] forall (f :: * -> *) a. String -> Mod f a help ( (String "Space-separated list of XFTP server(s) to use (each server can have more than one hostname)." String -> String -> String forall a. Semigroup a => a -> a -> a <> String "\n") String -> String -> String forall a. Semigroup a => a -> a -> a <> (String "If you pass multiple servers, surround the entire list in quotes." String -> String -> String forall a. Semigroup a => a -> a -> a <> String "\n") String -> String -> String forall a. Semigroup a => a -> a -> a <> String "Examples: xftp1.example.com, \"xftp1.example.com xftp2.example.com xftp3.example.com\"" ) Mod OptionFields [ProtoServerWithAuth 'PXFTP] -> Mod OptionFields [ProtoServerWithAuth 'PXFTP] -> Mod OptionFields [ProtoServerWithAuth 'PXFTP] forall a. Semigroup a => a -> a -> a <> [ProtoServerWithAuth 'PXFTP] -> Mod OptionFields [ProtoServerWithAuth 'PXFTP] forall (f :: * -> *) a. HasValue f => a -> Mod f a value [] ) Maybe SocksProxyWithAuth socksProxy <- Maybe SocksProxyWithAuth -> Mod FlagFields (Maybe SocksProxyWithAuth) -> Parser (Maybe SocksProxyWithAuth) forall a. a -> Mod FlagFields a -> Parser a flag' (SocksProxyWithAuth -> Maybe SocksProxyWithAuth forall a. a -> Maybe a Just SocksProxyWithAuth defaultSocksProxyWithAuth) (Char -> Mod FlagFields (Maybe SocksProxyWithAuth) forall (f :: * -> *) a. HasName f => Char -> Mod f a short Char 'x' Mod FlagFields (Maybe SocksProxyWithAuth) -> Mod FlagFields (Maybe SocksProxyWithAuth) -> Mod FlagFields (Maybe SocksProxyWithAuth) forall a. Semigroup a => a -> a -> a <> String -> Mod FlagFields (Maybe SocksProxyWithAuth) forall (f :: * -> *) a. String -> Mod f a help String "Use local SOCKS5 proxy at :9050") Parser (Maybe SocksProxyWithAuth) -> Parser (Maybe SocksProxyWithAuth) -> Parser (Maybe SocksProxyWithAuth) forall a. Parser a -> Parser a -> Parser a forall (f :: * -> *) a. Alternative f => f a -> f a -> f a <|> ReadM (Maybe SocksProxyWithAuth) -> Mod OptionFields (Maybe SocksProxyWithAuth) -> Parser (Maybe SocksProxyWithAuth) forall a. ReadM a -> Mod OptionFields a -> Parser a option ReadM (Maybe SocksProxyWithAuth) forall a. StrEncoding a => ReadM a strParse ( String -> Mod OptionFields (Maybe SocksProxyWithAuth) forall (f :: * -> *) a. HasName f => String -> Mod f a long String "socks-proxy" Mod OptionFields (Maybe SocksProxyWithAuth) -> Mod OptionFields (Maybe SocksProxyWithAuth) -> Mod OptionFields (Maybe SocksProxyWithAuth) forall a. Semigroup a => a -> a -> a <> String -> Mod OptionFields (Maybe SocksProxyWithAuth) forall (f :: * -> *) a. HasMetavar f => String -> Mod f a metavar String "SOCKS5" Mod OptionFields (Maybe SocksProxyWithAuth) -> Mod OptionFields (Maybe SocksProxyWithAuth) -> Mod OptionFields (Maybe SocksProxyWithAuth) forall a. Semigroup a => a -> a -> a <> String -> Mod OptionFields (Maybe SocksProxyWithAuth) forall (f :: * -> *) a. String -> Mod f a help String "Use SOCKS5 proxy at `ipv4:port` or `:port`" Mod OptionFields (Maybe SocksProxyWithAuth) -> Mod OptionFields (Maybe SocksProxyWithAuth) -> Mod OptionFields (Maybe SocksProxyWithAuth) forall a. Semigroup a => a -> a -> a <> Maybe SocksProxyWithAuth -> Mod OptionFields (Maybe SocksProxyWithAuth) forall (f :: * -> *) a. HasValue f => a -> Mod f a value Maybe SocksProxyWithAuth forall a. Maybe a Nothing ) SocksMode socksMode <- ReadM SocksMode -> Mod OptionFields SocksMode -> Parser SocksMode forall a. ReadM a -> Mod OptionFields a -> Parser a option ReadM SocksMode forall a. StrEncoding a => ReadM a strParse ( String -> Mod OptionFields SocksMode forall (f :: * -> *) a. HasName f => String -> Mod f a long String "socks-mode" Mod OptionFields SocksMode -> Mod OptionFields SocksMode -> Mod OptionFields SocksMode forall a. Semigroup a => a -> a -> a <> String -> Mod OptionFields SocksMode forall (f :: * -> *) a. HasMetavar f => String -> Mod f a metavar String "SOCKS_MODE" Mod OptionFields SocksMode -> Mod OptionFields SocksMode -> Mod OptionFields SocksMode forall a. Semigroup a => a -> a -> a <> String -> Mod OptionFields SocksMode forall (f :: * -> *) a. String -> Mod f a help String "Use SOCKS5 proxy: always (default), onion (with onion-only relays)" Mod OptionFields SocksMode -> Mod OptionFields SocksMode -> Mod OptionFields SocksMode forall a. Semigroup a => a -> a -> a <> SocksMode -> Mod OptionFields SocksMode forall (f :: * -> *) a. HasValue f => a -> Mod f a value SocksMode SMAlways ) Maybe HostMode hostMode_ <- Parser HostMode -> Parser (Maybe HostMode) forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a) optional (Parser HostMode -> Parser (Maybe HostMode)) -> Parser HostMode -> Parser (Maybe HostMode) forall a b. (a -> b) -> a -> b $ ReadM HostMode -> Mod OptionFields HostMode -> Parser HostMode forall a. ReadM a -> Mod OptionFields a -> Parser a option ReadM HostMode parseHostMode ( String -> Mod OptionFields HostMode forall (f :: * -> *) a. HasName f => String -> Mod f a long String "host-mode" Mod OptionFields HostMode -> Mod OptionFields HostMode -> Mod OptionFields HostMode forall a. Semigroup a => a -> a -> a <> String -> Mod OptionFields HostMode forall (f :: * -> *) a. HasMetavar f => String -> Mod f a metavar String "HOST_MODE" Mod OptionFields HostMode -> Mod OptionFields HostMode -> Mod OptionFields HostMode forall a. Semigroup a => a -> a -> a <> String -> Mod OptionFields HostMode forall (f :: * -> *) a. String -> Mod f a help String "Preferred server host type: onion (when SOCKS proxy with isolate-by-auth is used), public" ) Bool requiredHostMode <- Mod FlagFields Bool -> Parser Bool switch ( String -> Mod FlagFields Bool forall (f :: * -> *) a. HasName f => String -> Mod f a long String "required-host-mode" Mod FlagFields Bool -> Mod FlagFields Bool -> Mod FlagFields Bool forall a. Semigroup a => a -> a -> a <> String -> Mod FlagFields Bool forall (f :: * -> *) a. String -> Mod f a help String "Refuse connection if preferred server host type is not available" ) Maybe SMPProxyMode smpProxyMode_ <- Parser SMPProxyMode -> Parser (Maybe SMPProxyMode) forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a) optional (Parser SMPProxyMode -> Parser (Maybe SMPProxyMode)) -> Parser SMPProxyMode -> Parser (Maybe SMPProxyMode) forall a b. (a -> b) -> a -> b $ ReadM SMPProxyMode -> Mod OptionFields SMPProxyMode -> Parser SMPProxyMode forall a. ReadM a -> Mod OptionFields a -> Parser a option ReadM SMPProxyMode forall a. StrEncoding a => ReadM a strParse ( String -> Mod OptionFields SMPProxyMode forall (f :: * -> *) a. HasName f => String -> Mod f a long String "smp-proxy" Mod OptionFields SMPProxyMode -> Mod OptionFields SMPProxyMode -> Mod OptionFields SMPProxyMode forall a. Semigroup a => a -> a -> a <> String -> Mod OptionFields SMPProxyMode forall (f :: * -> *) a. HasMetavar f => String -> Mod f a metavar String "SMP_PROXY_MODE" Mod OptionFields SMPProxyMode -> Mod OptionFields SMPProxyMode -> Mod OptionFields SMPProxyMode forall a. Semigroup a => a -> a -> a <> String -> Mod OptionFields SMPProxyMode forall (f :: * -> *) a. String -> Mod f a help String "Use private message routing: always, unknown (default), unprotected, never" ) Maybe SMPProxyFallback smpProxyFallback_ <- Parser SMPProxyFallback -> Parser (Maybe SMPProxyFallback) forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a) optional (Parser SMPProxyFallback -> Parser (Maybe SMPProxyFallback)) -> Parser SMPProxyFallback -> Parser (Maybe SMPProxyFallback) forall a b. (a -> b) -> a -> b $ ReadM SMPProxyFallback -> Mod OptionFields SMPProxyFallback -> Parser SMPProxyFallback forall a. ReadM a -> Mod OptionFields a -> Parser a option ReadM SMPProxyFallback forall a. StrEncoding a => ReadM a strParse ( String -> Mod OptionFields SMPProxyFallback forall (f :: * -> *) a. HasName f => String -> Mod f a long String "smp-proxy-fallback" Mod OptionFields SMPProxyFallback -> Mod OptionFields SMPProxyFallback -> Mod OptionFields SMPProxyFallback forall a. Semigroup a => a -> a -> a <> String -> Mod OptionFields SMPProxyFallback forall (f :: * -> *) a. HasMetavar f => String -> Mod f a metavar String "SMP_PROXY_FALLBACK_MODE" Mod OptionFields SMPProxyFallback -> Mod OptionFields SMPProxyFallback -> Mod OptionFields SMPProxyFallback forall a. Semigroup a => a -> a -> a <> String -> Mod OptionFields SMPProxyFallback forall (f :: * -> *) a. String -> Mod f a help String "Allow downgrade and connect directly: no, [when IP address is] protected (default), yes" ) SMPWebPortServers smpWebPortServers <- SMPWebPortServers -> Mod FlagFields SMPWebPortServers -> Parser SMPWebPortServers forall a. a -> Mod FlagFields a -> Parser a flag' SMPWebPortServers SWPAll ( String -> Mod FlagFields SMPWebPortServers forall (f :: * -> *) a. HasName f => String -> Mod f a long String "smp-web-port" Mod FlagFields SMPWebPortServers -> Mod FlagFields SMPWebPortServers -> Mod FlagFields SMPWebPortServers forall a. Semigroup a => a -> a -> a <> String -> Mod FlagFields SMPWebPortServers forall (f :: * -> *) a. String -> Mod f a help String "Use port 443 with SMP servers when not specified" ) Parser SMPWebPortServers -> Parser SMPWebPortServers -> Parser SMPWebPortServers forall a. Parser a -> Parser a -> Parser a forall (f :: * -> *) a. Alternative f => f a -> f a -> f a <|> ReadM SMPWebPortServers -> Mod OptionFields SMPWebPortServers -> Parser SMPWebPortServers forall a. ReadM a -> Mod OptionFields a -> Parser a option ReadM SMPWebPortServers forall a. StrEncoding a => ReadM a strParse ( String -> Mod OptionFields SMPWebPortServers forall (f :: * -> *) a. HasName f => String -> Mod f a long String "smp-web-port-servers" Mod OptionFields SMPWebPortServers -> Mod OptionFields SMPWebPortServers -> Mod OptionFields SMPWebPortServers forall a. Semigroup a => a -> a -> a <> String -> Mod OptionFields SMPWebPortServers forall (f :: * -> *) a. String -> Mod f a help String "Use port 443 with SMP servers when not specified: all, preset (default), off" Mod OptionFields SMPWebPortServers -> Mod OptionFields SMPWebPortServers -> Mod OptionFields SMPWebPortServers forall a. Semigroup a => a -> a -> a <> SMPWebPortServers -> Mod OptionFields SMPWebPortServers forall (f :: * -> *) a. HasValue f => a -> Mod f a value SMPWebPortServers SWPPreset ) Int t <- ReadM Int -> Mod OptionFields Int -> Parser Int forall a. ReadM a -> Mod OptionFields a -> Parser a option ReadM Int forall a. Read a => ReadM a auto ( String -> Mod OptionFields Int forall (f :: * -> *) a. HasName f => String -> Mod f a long String "tcp-timeout" Mod OptionFields Int -> Mod OptionFields Int -> Mod OptionFields Int forall a. Semigroup a => a -> a -> a <> String -> Mod OptionFields Int forall (f :: * -> *) a. HasMetavar f => String -> Mod f a metavar String "TIMEOUT" Mod OptionFields Int -> Mod OptionFields Int -> Mod OptionFields Int forall a. Semigroup a => a -> a -> a <> String -> Mod OptionFields Int forall (f :: * -> *) a. String -> Mod f a help String "TCP timeout, seconds (default: 7/15 without/with SOCKS5 proxy)" Mod OptionFields Int -> Mod OptionFields Int -> Mod OptionFields Int forall a. Semigroup a => a -> a -> a <> Int -> Mod OptionFields Int forall (f :: * -> *) a. HasValue f => a -> Mod f a value Int 0 ) ChatLogLevel logLevel <- ReadM ChatLogLevel -> Mod OptionFields ChatLogLevel -> Parser ChatLogLevel forall a. ReadM a -> Mod OptionFields a -> Parser a option ReadM ChatLogLevel parseLogLevel ( String -> Mod OptionFields ChatLogLevel forall (f :: * -> *) a. HasName f => String -> Mod f a long String "log-level" Mod OptionFields ChatLogLevel -> Mod OptionFields ChatLogLevel -> Mod OptionFields ChatLogLevel forall a. Semigroup a => a -> a -> a <> Char -> Mod OptionFields ChatLogLevel forall (f :: * -> *) a. HasName f => Char -> Mod f a short Char 'l' Mod OptionFields ChatLogLevel -> Mod OptionFields ChatLogLevel -> Mod OptionFields ChatLogLevel forall a. Semigroup a => a -> a -> a <> String -> Mod OptionFields ChatLogLevel forall (f :: * -> *) a. HasMetavar f => String -> Mod f a metavar String "LEVEL" Mod OptionFields ChatLogLevel -> Mod OptionFields ChatLogLevel -> Mod OptionFields ChatLogLevel forall a. Semigroup a => a -> a -> a <> String -> Mod OptionFields ChatLogLevel forall (f :: * -> *) a. String -> Mod f a help String "Log level: debug, info, warn, error, important (default)" Mod OptionFields ChatLogLevel -> Mod OptionFields ChatLogLevel -> Mod OptionFields ChatLogLevel forall a. Semigroup a => a -> a -> a <> ChatLogLevel -> Mod OptionFields ChatLogLevel forall (f :: * -> *) a. HasValue f => a -> Mod f a value ChatLogLevel CLLImportant ) Bool logTLSErrors <- Mod FlagFields Bool -> Parser Bool switch ( String -> Mod FlagFields Bool forall (f :: * -> *) a. HasName f => String -> Mod f a long String "log-tls-errors" Mod FlagFields Bool -> Mod FlagFields Bool -> Mod FlagFields Bool forall a. Semigroup a => a -> a -> a <> String -> Mod FlagFields Bool forall (f :: * -> *) a. String -> Mod f a help String "Log TLS errors" ) Bool logConnections <- Mod FlagFields Bool -> Parser Bool switch ( String -> Mod FlagFields Bool forall (f :: * -> *) a. HasName f => String -> Mod f a long String "connections" Mod FlagFields Bool -> Mod FlagFields Bool -> Mod FlagFields Bool forall a. Semigroup a => a -> a -> a <> Char -> Mod FlagFields Bool forall (f :: * -> *) a. HasName f => Char -> Mod f a short Char 'c' Mod FlagFields Bool -> Mod FlagFields Bool -> Mod FlagFields Bool forall a. Semigroup a => a -> a -> a <> String -> Mod FlagFields Bool forall (f :: * -> *) a. String -> Mod f a help String "Log connections subscription errors on start (also with `-l info`)" ) Bool logServerHosts <- Mod FlagFields Bool -> Parser Bool switch ( String -> Mod FlagFields Bool forall (f :: * -> *) a. HasName f => String -> Mod f a long String "log-hosts" Mod FlagFields Bool -> Mod FlagFields Bool -> Mod FlagFields Bool forall a. Semigroup a => a -> a -> a <> String -> Mod FlagFields Bool forall (f :: * -> *) a. String -> Mod f a help String "Log connections to servers (also with `-l info`)" ) Bool logAgent <- Mod FlagFields Bool -> Parser Bool switch ( String -> Mod FlagFields Bool forall (f :: * -> *) a. HasName f => String -> Mod f a long String "log-agent" Mod FlagFields Bool -> Mod FlagFields Bool -> Mod FlagFields Bool forall a. Semigroup a => a -> a -> a <> String -> Mod FlagFields Bool forall (f :: * -> *) a. String -> Mod f a help String "Enable logs from SMP agent (also with `-l debug`)" ) Maybe String logFile <- Parser String -> Parser (Maybe String) forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a) optional (Parser String -> Parser (Maybe String)) -> Parser String -> Parser (Maybe String) forall a b. (a -> b) -> a -> b $ Mod OptionFields String -> Parser String forall s. IsString s => Mod OptionFields s -> Parser s strOption ( String -> Mod OptionFields String forall (f :: * -> *) a. HasName f => String -> Mod f a long String "log-file" Mod OptionFields String -> Mod OptionFields String -> Mod OptionFields String forall a. Semigroup a => a -> a -> a <> String -> Mod OptionFields String forall (f :: * -> *) a. String -> Mod f a help String "Log to specified file / device" ) Natural tbqSize <- ReadM Natural -> Mod OptionFields Natural -> Parser Natural forall a. ReadM a -> Mod OptionFields a -> Parser a option ReadM Natural forall a. Read a => ReadM a auto ( String -> Mod OptionFields Natural forall (f :: * -> *) a. HasName f => String -> Mod f a long String "queue-size" Mod OptionFields Natural -> Mod OptionFields Natural -> Mod OptionFields Natural forall a. Semigroup a => a -> a -> a <> Char -> Mod OptionFields Natural forall (f :: * -> *) a. HasName f => Char -> Mod f a short Char 'q' Mod OptionFields Natural -> Mod OptionFields Natural -> Mod OptionFields Natural forall a. Semigroup a => a -> a -> a <> String -> Mod OptionFields Natural forall (f :: * -> *) a. HasMetavar f => String -> Mod f a metavar String "SIZE" Mod OptionFields Natural -> Mod OptionFields Natural -> Mod OptionFields Natural forall a. Semigroup a => a -> a -> a <> String -> Mod OptionFields Natural forall (f :: * -> *) a. String -> Mod f a help String "Internal queue size" Mod OptionFields Natural -> Mod OptionFields Natural -> Mod OptionFields Natural forall a. Semigroup a => a -> a -> a <> Natural -> Mod OptionFields Natural forall (f :: * -> *) a. HasValue f => a -> Mod f a value Natural 1024 Mod OptionFields Natural -> Mod OptionFields Natural -> Mod OptionFields Natural forall a. Semigroup a => a -> a -> a <> Mod OptionFields Natural forall a (f :: * -> *). Show a => Mod f a showDefault ) Maybe Text deviceName <- Parser Text -> Parser (Maybe Text) forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a) optional (Parser Text -> Parser (Maybe Text)) -> Parser Text -> Parser (Maybe Text) forall a b. (a -> b) -> a -> b $ Mod OptionFields Text -> Parser Text forall s. IsString s => Mod OptionFields s -> Parser s strOption ( String -> Mod OptionFields Text forall (f :: * -> *) a. HasName f => String -> Mod f a long String "device-name" Mod OptionFields Text -> Mod OptionFields Text -> Mod OptionFields Text forall a. Semigroup a => a -> a -> a <> String -> Mod OptionFields Text forall (f :: * -> *) a. HasMetavar f => String -> Mod f a metavar String "DEVICE" Mod OptionFields Text -> Mod OptionFields Text -> Mod OptionFields Text forall a. Semigroup a => a -> a -> a <> String -> Mod OptionFields Text forall (f :: * -> *) a. String -> Mod f a help String "Device name to use in connections with remote hosts and controller" ) Bool highlyAvailable <- Mod FlagFields Bool -> Parser Bool switch ( String -> Mod FlagFields Bool forall (f :: * -> *) a. HasName f => String -> Mod f a long String "ha" Mod FlagFields Bool -> Mod FlagFields Bool -> Mod FlagFields Bool forall a. Semigroup a => a -> a -> a <> String -> Mod FlagFields Bool forall (f :: * -> *) a. String -> Mod f a help String "Run as a highly available client (this may increase traffic in groups)" ) Bool yesToUpMigrations <- Mod FlagFields Bool -> Parser Bool switch ( String -> Mod FlagFields Bool forall (f :: * -> *) a. HasName f => String -> Mod f a long String "yes-migrate" Mod FlagFields Bool -> Mod FlagFields Bool -> Mod FlagFields Bool forall a. Semigroup a => a -> a -> a <> Char -> Mod FlagFields Bool forall (f :: * -> *) a. HasName f => Char -> Mod f a short Char 'y' Mod FlagFields Bool -> Mod FlagFields Bool -> Mod FlagFields Bool forall a. Semigroup a => a -> a -> a <> String -> Mod FlagFields Bool forall (f :: * -> *) a. String -> Mod f a help String "Automatically confirm \"up\" database migrations" ) Maybe String migrationBackupPath <- Parser (Maybe String) migrationBackupPathP pure CoreChatOpts { ChatDbOpts dbOptions :: ChatDbOpts dbOptions :: ChatDbOpts dbOptions, [ProtoServerWithAuth 'PSMP] smpServers :: [ProtoServerWithAuth 'PSMP] smpServers :: [ProtoServerWithAuth 'PSMP] smpServers, [ProtoServerWithAuth 'PXFTP] xftpServers :: [ProtoServerWithAuth 'PXFTP] xftpServers :: [ProtoServerWithAuth 'PXFTP] xftpServers, simpleNetCfg :: SimpleNetCfg simpleNetCfg = SimpleNetCfg { Maybe SocksProxyWithAuth socksProxy :: Maybe SocksProxyWithAuth socksProxy :: Maybe SocksProxyWithAuth socksProxy, SocksMode socksMode :: SocksMode socksMode :: SocksMode socksMode, hostMode :: HostMode hostMode = HostMode -> Maybe HostMode -> HostMode forall a. a -> Maybe a -> a fromMaybe (Maybe SocksProxyWithAuth -> HostMode defaultHostMode Maybe SocksProxyWithAuth socksProxy) Maybe HostMode hostMode_, Bool requiredHostMode :: Bool requiredHostMode :: Bool requiredHostMode, Maybe SMPProxyMode smpProxyMode_ :: Maybe SMPProxyMode smpProxyMode_ :: Maybe SMPProxyMode smpProxyMode_, Maybe SMPProxyFallback smpProxyFallback_ :: Maybe SMPProxyFallback smpProxyFallback_ :: Maybe SMPProxyFallback smpProxyFallback_, SMPWebPortServers smpWebPortServers :: SMPWebPortServers smpWebPortServers :: SMPWebPortServers smpWebPortServers, tcpTimeout_ :: Maybe Int tcpTimeout_ = Int -> Maybe Int forall a. a -> Maybe a Just (Int -> Maybe Int) -> Int -> Maybe Int forall a b. (a -> b) -> a -> b $ Maybe SocksProxyWithAuth -> Int -> Int forall {a} {a}. (Num a, Ord a) => Maybe a -> a -> a useTcpTimeout Maybe SocksProxyWithAuth socksProxy Int t, Bool logTLSErrors :: Bool logTLSErrors :: Bool logTLSErrors }, ChatLogLevel logLevel :: ChatLogLevel logLevel :: ChatLogLevel logLevel, logConnections :: Bool logConnections = Bool logConnections Bool -> Bool -> Bool || ChatLogLevel logLevel ChatLogLevel -> ChatLogLevel -> Bool forall a. Ord a => a -> a -> Bool <= ChatLogLevel CLLInfo, logServerHosts :: Bool logServerHosts = Bool logServerHosts Bool -> Bool -> Bool || ChatLogLevel logLevel ChatLogLevel -> ChatLogLevel -> Bool forall a. Ord a => a -> a -> Bool <= ChatLogLevel CLLInfo, logAgent :: Maybe LogLevel logAgent = if Bool logAgent Bool -> Bool -> Bool || ChatLogLevel logLevel ChatLogLevel -> ChatLogLevel -> Bool forall a. Eq a => a -> a -> Bool == ChatLogLevel CLLDebug then LogLevel -> Maybe LogLevel forall a. a -> Maybe a Just (LogLevel -> Maybe LogLevel) -> LogLevel -> Maybe LogLevel forall a b. (a -> b) -> a -> b $ ChatLogLevel -> LogLevel agentLogLevel ChatLogLevel logLevel else Maybe LogLevel forall a. Maybe a Nothing, Maybe String logFile :: Maybe String logFile :: Maybe String logFile, Natural tbqSize :: Natural tbqSize :: Natural tbqSize, Maybe Text deviceName :: Maybe Text deviceName :: Maybe Text deviceName, Bool highlyAvailable :: Bool highlyAvailable :: Bool highlyAvailable, Bool yesToUpMigrations :: Bool yesToUpMigrations :: Bool yesToUpMigrations, Maybe String migrationBackupPath :: Maybe String migrationBackupPath :: Maybe String migrationBackupPath } where useTcpTimeout :: Maybe a -> a -> a useTcpTimeout Maybe a p a t = a 1000000 a -> a -> a forall a. Num a => a -> a -> a * if a t a -> a -> Bool forall a. Ord a => a -> a -> Bool > a 0 then a t else a -> (a -> a) -> Maybe a -> a forall b a. b -> (a -> b) -> Maybe a -> b maybe a 7 (a -> a -> a forall a b. a -> b -> a const a 15) Maybe a p defaultHostMode :: Maybe SocksProxyWithAuth -> HostMode defaultHostMode :: Maybe SocksProxyWithAuth -> HostMode defaultHostMode = \case Just (SocksProxyWithAuth SocksAuth SocksIsolateByAuth SocksProxy _) -> HostMode HMOnionViaSocks; Maybe SocksProxyWithAuth _ -> HostMode HMPublic chatOptsP :: FilePath -> FilePath -> Parser ChatOpts chatOptsP :: String -> String -> Parser ChatOpts chatOptsP String appDir String defaultDbName = do CoreChatOpts coreOptions <- String -> String -> Parser CoreChatOpts coreChatOptsP String appDir String defaultDbName String chatCmd <- Mod OptionFields String -> Parser String forall s. IsString s => Mod OptionFields s -> Parser s strOption ( String -> Mod OptionFields String forall (f :: * -> *) a. HasName f => String -> Mod f a long String "execute" Mod OptionFields String -> Mod OptionFields String -> Mod OptionFields String forall a. Semigroup a => a -> a -> a <> Char -> Mod OptionFields String forall (f :: * -> *) a. HasName f => Char -> Mod f a short Char 'e' Mod OptionFields String -> Mod OptionFields String -> Mod OptionFields String forall a. Semigroup a => a -> a -> a <> String -> Mod OptionFields String forall (f :: * -> *) a. HasMetavar f => String -> Mod f a metavar String "COMMAND" Mod OptionFields String -> Mod OptionFields String -> Mod OptionFields String forall a. Semigroup a => a -> a -> a <> String -> Mod OptionFields String forall (f :: * -> *) a. String -> Mod f a help String "Execute chat command (received messages won't be logged) and exit" Mod OptionFields String -> Mod OptionFields String -> Mod OptionFields String forall a. Semigroup a => a -> a -> a <> String -> Mod OptionFields String forall (f :: * -> *) a. HasValue f => a -> Mod f a value String "" ) Int chatCmdDelay <- ReadM Int -> Mod OptionFields Int -> Parser Int forall a. ReadM a -> Mod OptionFields a -> Parser a option ReadM Int forall a. Read a => ReadM a auto ( String -> Mod OptionFields Int forall (f :: * -> *) a. HasName f => String -> Mod f a long String "time" Mod OptionFields Int -> Mod OptionFields Int -> Mod OptionFields Int forall a. Semigroup a => a -> a -> a <> Char -> Mod OptionFields Int forall (f :: * -> *) a. HasName f => Char -> Mod f a short Char 't' Mod OptionFields Int -> Mod OptionFields Int -> Mod OptionFields Int forall a. Semigroup a => a -> a -> a <> String -> Mod OptionFields Int forall (f :: * -> *) a. HasMetavar f => String -> Mod f a metavar String "TIME" Mod OptionFields Int -> Mod OptionFields Int -> Mod OptionFields Int forall a. Semigroup a => a -> a -> a <> String -> Mod OptionFields Int forall (f :: * -> *) a. String -> Mod f a help String "Time to wait after sending chat command before exiting, seconds" Mod OptionFields Int -> Mod OptionFields Int -> Mod OptionFields Int forall a. Semigroup a => a -> a -> a <> Int -> Mod OptionFields Int forall (f :: * -> *) a. HasValue f => a -> Mod f a value Int 3 Mod OptionFields Int -> Mod OptionFields Int -> Mod OptionFields Int forall a. Semigroup a => a -> a -> a <> Mod OptionFields Int forall a (f :: * -> *). Show a => Mod f a showDefault ) ChatCmdLog chatCmdLog <- ReadM ChatCmdLog -> Mod OptionFields ChatCmdLog -> Parser ChatCmdLog forall a. ReadM a -> Mod OptionFields a -> Parser a option ReadM ChatCmdLog parseChatCmdLog ( String -> Mod OptionFields ChatCmdLog forall (f :: * -> *) a. HasName f => String -> Mod f a long String "execute-log" Mod OptionFields ChatCmdLog -> Mod OptionFields ChatCmdLog -> Mod OptionFields ChatCmdLog forall a. Semigroup a => a -> a -> a <> String -> Mod OptionFields ChatCmdLog forall (f :: * -> *) a. HasMetavar f => String -> Mod f a metavar String "EXEC_LOG" Mod OptionFields ChatCmdLog -> Mod OptionFields ChatCmdLog -> Mod OptionFields ChatCmdLog forall a. Semigroup a => a -> a -> a <> String -> Mod OptionFields ChatCmdLog forall (f :: * -> *) a. String -> Mod f a help String "Log during command execution: all, messages, none (default)" Mod OptionFields ChatCmdLog -> Mod OptionFields ChatCmdLog -> Mod OptionFields ChatCmdLog forall a. Semigroup a => a -> a -> a <> ChatCmdLog -> Mod OptionFields ChatCmdLog forall (f :: * -> *) a. HasValue f => a -> Mod f a value ChatCmdLog CCLNone ) Maybe String chatServerPort <- ReadM (Maybe String) -> Mod OptionFields (Maybe String) -> Parser (Maybe String) forall a. ReadM a -> Mod OptionFields a -> Parser a option ReadM (Maybe String) parseServerPort ( String -> Mod OptionFields (Maybe String) forall (f :: * -> *) a. HasName f => String -> Mod f a long String "chat-server-port" Mod OptionFields (Maybe String) -> Mod OptionFields (Maybe String) -> Mod OptionFields (Maybe String) forall a. Semigroup a => a -> a -> a <> Char -> Mod OptionFields (Maybe String) forall (f :: * -> *) a. HasName f => Char -> Mod f a short Char 'p' Mod OptionFields (Maybe String) -> Mod OptionFields (Maybe String) -> Mod OptionFields (Maybe String) forall a. Semigroup a => a -> a -> a <> String -> Mod OptionFields (Maybe String) forall (f :: * -> *) a. HasMetavar f => String -> Mod f a metavar String "PORT" Mod OptionFields (Maybe String) -> Mod OptionFields (Maybe String) -> Mod OptionFields (Maybe String) forall a. Semigroup a => a -> a -> a <> String -> Mod OptionFields (Maybe String) forall (f :: * -> *) a. String -> Mod f a help String "Run chat server on specified port" Mod OptionFields (Maybe String) -> Mod OptionFields (Maybe String) -> Mod OptionFields (Maybe String) forall a. Semigroup a => a -> a -> a <> Maybe String -> Mod OptionFields (Maybe String) forall (f :: * -> *) a. HasValue f => a -> Mod f a value Maybe String forall a. Maybe a Nothing ) Maybe String optFilesFolder <- Parser String -> Parser (Maybe String) forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a) optional (Parser String -> Parser (Maybe String)) -> Parser String -> Parser (Maybe String) forall a b. (a -> b) -> a -> b $ Mod OptionFields String -> Parser String forall s. IsString s => Mod OptionFields s -> Parser s strOption ( String -> Mod OptionFields String forall (f :: * -> *) a. HasName f => String -> Mod f a long String "files-folder" Mod OptionFields String -> Mod OptionFields String -> Mod OptionFields String forall a. Semigroup a => a -> a -> a <> String -> Mod OptionFields String forall (f :: * -> *) a. HasMetavar f => String -> Mod f a metavar String "FOLDER" Mod OptionFields String -> Mod OptionFields String -> Mod OptionFields String forall a. Semigroup a => a -> a -> a <> String -> Mod OptionFields String forall (f :: * -> *) a. String -> Mod f a help String "Folder to use for sent and received files" ) Maybe String optTempDirectory <- Parser String -> Parser (Maybe String) forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a) optional (Parser String -> Parser (Maybe String)) -> Parser String -> Parser (Maybe String) forall a b. (a -> b) -> a -> b $ Mod OptionFields String -> Parser String forall s. IsString s => Mod OptionFields s -> Parser s strOption ( String -> Mod OptionFields String forall (f :: * -> *) a. HasName f => String -> Mod f a long String "temp-folder" Mod OptionFields String -> Mod OptionFields String -> Mod OptionFields String forall a. Semigroup a => a -> a -> a <> String -> Mod OptionFields String forall (f :: * -> *) a. HasMetavar f => String -> Mod f a metavar String "FOLDER" Mod OptionFields String -> Mod OptionFields String -> Mod OptionFields String forall a. Semigroup a => a -> a -> a <> String -> Mod OptionFields String forall (f :: * -> *) a. String -> Mod f a help String "Folder for temporary encrypted files (default: system temp directory)" ) Bool showReactions <- Mod FlagFields Bool -> Parser Bool switch ( String -> Mod FlagFields Bool forall (f :: * -> *) a. HasName f => String -> Mod f a long String "reactions" Mod FlagFields Bool -> Mod FlagFields Bool -> Mod FlagFields Bool forall a. Semigroup a => a -> a -> a <> String -> Mod FlagFields Bool forall (f :: * -> *) a. String -> Mod f a help String "Show message reactions" ) Bool allowInstantFiles <- Mod FlagFields Bool -> Parser Bool switch ( String -> Mod FlagFields Bool forall (f :: * -> *) a. HasName f => String -> Mod f a long String "allow-instant-files" Mod FlagFields Bool -> Mod FlagFields Bool -> Mod FlagFields Bool forall a. Semigroup a => a -> a -> a <> Char -> Mod FlagFields Bool forall (f :: * -> *) a. HasName f => Char -> Mod f a short Char 'f' Mod FlagFields Bool -> Mod FlagFields Bool -> Mod FlagFields Bool forall a. Semigroup a => a -> a -> a <> String -> Mod FlagFields Bool forall (f :: * -> *) a. String -> Mod f a help String "Send and receive instant files without acceptance" ) Integer autoAcceptFileSize <- Integer -> Mod FlagFields Integer -> Parser Integer forall a. a -> Mod FlagFields a -> Parser a flag' (Integer -> Integer forall a. Integral a => a -> a mb Integer 1) (Char -> Mod FlagFields Integer forall (f :: * -> *) a. HasName f => Char -> Mod f a short Char 'a' Mod FlagFields Integer -> Mod FlagFields Integer -> Mod FlagFields Integer forall a. Semigroup a => a -> a -> a <> String -> Mod FlagFields Integer forall (f :: * -> *) a. String -> Mod f a help String "Automatically accept files up to 1MB") Parser Integer -> Parser Integer -> Parser Integer forall a. Parser a -> Parser a -> Parser a forall (f :: * -> *) a. Alternative f => f a -> f a -> f a <|> ReadM Integer -> Mod OptionFields Integer -> Parser Integer forall a. ReadM a -> Mod OptionFields a -> Parser a option ReadM Integer forall a. Read a => ReadM a auto ( String -> Mod OptionFields Integer forall (f :: * -> *) a. HasName f => String -> Mod f a long String "auto-accept-files" Mod OptionFields Integer -> Mod OptionFields Integer -> Mod OptionFields Integer forall a. Semigroup a => a -> a -> a <> String -> Mod OptionFields Integer forall (f :: * -> *) a. HasMetavar f => String -> Mod f a metavar String "FILE_SIZE" Mod OptionFields Integer -> Mod OptionFields Integer -> Mod OptionFields Integer forall a. Semigroup a => a -> a -> a <> String -> Mod OptionFields Integer forall (f :: * -> *) a. String -> Mod f a help String "Automatically accept files up to specified size" Mod OptionFields Integer -> Mod OptionFields Integer -> Mod OptionFields Integer forall a. Semigroup a => a -> a -> a <> Integer -> Mod OptionFields Integer forall (f :: * -> *) a. HasValue f => a -> Mod f a value Integer 0 ) Bool muteNotifications <- Mod FlagFields Bool -> Parser Bool switch ( String -> Mod FlagFields Bool forall (f :: * -> *) a. HasName f => String -> Mod f a long String "mute" Mod FlagFields Bool -> Mod FlagFields Bool -> Mod FlagFields Bool forall a. Semigroup a => a -> a -> a <> String -> Mod FlagFields Bool forall (f :: * -> *) a. String -> Mod f a help String "Mute notifications" ) Bool markRead <- Mod FlagFields Bool -> Parser Bool switch ( String -> Mod FlagFields Bool forall (f :: * -> *) a. HasName f => String -> Mod f a long String "mark-read" Mod FlagFields Bool -> Mod FlagFields Bool -> Mod FlagFields Bool forall a. Semigroup a => a -> a -> a <> Char -> Mod FlagFields Bool forall (f :: * -> *) a. HasName f => Char -> Mod f a short Char 'r' Mod FlagFields Bool -> Mod FlagFields Bool -> Mod FlagFields Bool forall a. Semigroup a => a -> a -> a <> String -> Mod FlagFields Bool forall (f :: * -> *) a. String -> Mod f a help String "Mark shown messages as read" ) Maybe Text createBotDisplayName <- Parser Text -> Parser (Maybe Text) forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a) optional (Parser Text -> Parser (Maybe Text)) -> Parser Text -> Parser (Maybe Text) forall a b. (a -> b) -> a -> b $ Mod OptionFields Text -> Parser Text forall s. IsString s => Mod OptionFields s -> Parser s strOption ( String -> Mod OptionFields Text forall (f :: * -> *) a. HasName f => String -> Mod f a long String "create-bot-display-name" Mod OptionFields Text -> Mod OptionFields Text -> Mod OptionFields Text forall a. Semigroup a => a -> a -> a <> String -> Mod OptionFields Text forall (f :: * -> *) a. HasMetavar f => String -> Mod f a metavar String "BOT_NAME" Mod OptionFields Text -> Mod OptionFields Text -> Mod OptionFields Text forall a. Semigroup a => a -> a -> a <> String -> Mod OptionFields Text forall (f :: * -> *) a. String -> Mod f a help String "Create new bot user on the first start with the passed display name" ) Bool createBotAllowFiles <- Mod FlagFields Bool -> Parser Bool switch ( String -> Mod FlagFields Bool forall (f :: * -> *) a. HasName f => String -> Mod f a long String "create-bot-allow-files" Mod FlagFields Bool -> Mod FlagFields Bool -> Mod FlagFields Bool forall a. Semigroup a => a -> a -> a <> String -> Mod FlagFields Bool forall (f :: * -> *) a. String -> Mod f a help String "Flag for created bot to allow files (only allowed together with --create-bot option)" ) Bool maintenance <- Mod FlagFields Bool -> Parser Bool switch ( String -> Mod FlagFields Bool forall (f :: * -> *) a. HasName f => String -> Mod f a long String "maintenance" Mod FlagFields Bool -> Mod FlagFields Bool -> Mod FlagFields Bool forall a. Semigroup a => a -> a -> a <> Char -> Mod FlagFields Bool forall (f :: * -> *) a. HasName f => Char -> Mod f a short Char 'm' Mod FlagFields Bool -> Mod FlagFields Bool -> Mod FlagFields Bool forall a. Semigroup a => a -> a -> a <> String -> Mod FlagFields Bool forall (f :: * -> *) a. String -> Mod f a help String "Run in maintenance mode (/_start to start chat)" ) pure ChatOpts { CoreChatOpts coreOptions :: CoreChatOpts coreOptions :: CoreChatOpts coreOptions, String chatCmd :: String chatCmd :: String chatCmd, Int chatCmdDelay :: Int chatCmdDelay :: Int chatCmdDelay, ChatCmdLog chatCmdLog :: ChatCmdLog chatCmdLog :: ChatCmdLog chatCmdLog, Maybe String chatServerPort :: Maybe String chatServerPort :: Maybe String chatServerPort, Maybe String optFilesFolder :: Maybe String optFilesFolder :: Maybe String optFilesFolder, Maybe String optTempDirectory :: Maybe String optTempDirectory :: Maybe String optTempDirectory, Bool showReactions :: Bool showReactions :: Bool showReactions, Bool allowInstantFiles :: Bool allowInstantFiles :: Bool allowInstantFiles, Integer autoAcceptFileSize :: Integer autoAcceptFileSize :: Integer autoAcceptFileSize, Bool muteNotifications :: Bool muteNotifications :: Bool muteNotifications, Bool markRead :: Bool markRead :: Bool markRead, createBot :: Maybe CreateBotOpts createBot = case Maybe Text createBotDisplayName of Just Text botDisplayName -> CreateBotOpts -> Maybe CreateBotOpts forall a. a -> Maybe a Just CreateBotOpts {Text botDisplayName :: Text botDisplayName :: Text botDisplayName, allowFiles :: Bool allowFiles = Bool createBotAllowFiles} Maybe Text Nothing | Bool createBotAllowFiles -> String -> Maybe CreateBotOpts forall a. HasCallStack => String -> a error String "--create-bot-allow-files option requires --create-bot-name option" | Bool otherwise -> Maybe CreateBotOpts forall a. Maybe a Nothing, Bool maintenance :: Bool maintenance :: Bool maintenance } parseProtocolServers :: ProtocolTypeI p => ReadM [ProtoServerWithAuth p] parseProtocolServers :: forall (p :: ProtocolType). ProtocolTypeI p => ReadM [ProtoServerWithAuth p] parseProtocolServers = (String -> Either String [ProtoServerWithAuth p]) -> ReadM [ProtoServerWithAuth p] forall a. (String -> Either String a) -> ReadM a eitherReader ((String -> Either String [ProtoServerWithAuth p]) -> ReadM [ProtoServerWithAuth p]) -> (String -> Either String [ProtoServerWithAuth p]) -> ReadM [ProtoServerWithAuth p] forall a b. (a -> b) -> a -> b $ Parser [ProtoServerWithAuth p] -> ByteString -> Either String [ProtoServerWithAuth p] forall a. Parser a -> ByteString -> Either String a parseAll Parser [ProtoServerWithAuth p] forall (p :: ProtocolType). ProtocolTypeI p => Parser [ProtoServerWithAuth p] protocolServersP (ByteString -> Either String [ProtoServerWithAuth p]) -> (String -> ByteString) -> String -> Either String [ProtoServerWithAuth p] forall b c a. (b -> c) -> (a -> b) -> a -> c . String -> ByteString B.pack strParse :: StrEncoding a => ReadM a strParse :: forall a. StrEncoding a => ReadM a strParse = (String -> Either String a) -> ReadM a forall a. (String -> Either String a) -> ReadM a eitherReader ((String -> Either String a) -> ReadM a) -> (String -> Either String a) -> ReadM a forall a b. (a -> b) -> a -> b $ Parser a -> ByteString -> Either String a forall a. Parser a -> ByteString -> Either String a parseAll Parser a forall a. StrEncoding a => Parser a strP (ByteString -> Either String a) -> (String -> ByteString) -> String -> Either String a forall b c a. (b -> c) -> (a -> b) -> a -> c . Text -> ByteString encodeUtf8 (Text -> ByteString) -> (String -> Text) -> String -> ByteString forall b c a. (b -> c) -> (a -> b) -> a -> c . String -> Text T.pack parseHostMode :: ReadM HostMode parseHostMode :: ReadM HostMode parseHostMode = (String -> Either String HostMode) -> ReadM HostMode forall a. (String -> Either String a) -> ReadM a eitherReader ((String -> Either String HostMode) -> ReadM HostMode) -> (String -> Either String HostMode) -> ReadM HostMode forall a b. (a -> b) -> a -> b $ Text -> Either String HostMode textToHostMode (Text -> Either String HostMode) -> (String -> Text) -> String -> Either String HostMode forall b c a. (b -> c) -> (a -> b) -> a -> c . String -> Text T.pack parseServerPort :: ReadM (Maybe String) parseServerPort :: ReadM (Maybe String) parseServerPort = (String -> Either String (Maybe String)) -> ReadM (Maybe String) forall a. (String -> Either String a) -> ReadM a eitherReader ((String -> Either String (Maybe String)) -> ReadM (Maybe String)) -> (String -> Either String (Maybe String)) -> ReadM (Maybe String) forall a b. (a -> b) -> a -> b $ Parser (Maybe String) -> ByteString -> Either String (Maybe String) forall a. Parser a -> ByteString -> Either String a parseAll Parser (Maybe String) serverPortP (ByteString -> Either String (Maybe String)) -> (String -> ByteString) -> String -> Either String (Maybe String) forall b c a. (b -> c) -> (a -> b) -> a -> c . String -> ByteString B.pack serverPortP :: A.Parser (Maybe String) serverPortP :: Parser (Maybe String) serverPortP = String -> Maybe String forall a. a -> Maybe a Just (String -> Maybe String) -> (ByteString -> String) -> ByteString -> Maybe String forall b c a. (b -> c) -> (a -> b) -> a -> c . ByteString -> String B.unpack (ByteString -> Maybe String) -> Parser ByteString ByteString -> Parser (Maybe String) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> (Char -> Bool) -> Parser ByteString ByteString A.takeWhile Char -> Bool A.isDigit protocolServersP :: ProtocolTypeI p => A.Parser [ProtoServerWithAuth p] protocolServersP :: forall (p :: ProtocolType). ProtocolTypeI p => Parser [ProtoServerWithAuth p] protocolServersP = Parser (ProtoServerWithAuth p) forall a. StrEncoding a => Parser a strP Parser (ProtoServerWithAuth p) -> Parser ByteString Char -> Parser ByteString [ProtoServerWithAuth p] forall (f :: * -> *) a s. Alternative f => f a -> f s -> f [a] `A.sepBy1` Char -> Parser ByteString Char A.char Char ' ' parseLogLevel :: ReadM ChatLogLevel parseLogLevel :: ReadM ChatLogLevel parseLogLevel = (String -> Either String ChatLogLevel) -> ReadM ChatLogLevel forall a. (String -> Either String a) -> ReadM a eitherReader ((String -> Either String ChatLogLevel) -> ReadM ChatLogLevel) -> (String -> Either String ChatLogLevel) -> ReadM ChatLogLevel forall a b. (a -> b) -> a -> b $ \case String "debug" -> ChatLogLevel -> Either String ChatLogLevel forall a b. b -> Either a b Right ChatLogLevel CLLDebug String "info" -> ChatLogLevel -> Either String ChatLogLevel forall a b. b -> Either a b Right ChatLogLevel CLLInfo String "warn" -> ChatLogLevel -> Either String ChatLogLevel forall a b. b -> Either a b Right ChatLogLevel CLLWarning String "error" -> ChatLogLevel -> Either String ChatLogLevel forall a b. b -> Either a b Right ChatLogLevel CLLError String "important" -> ChatLogLevel -> Either String ChatLogLevel forall a b. b -> Either a b Right ChatLogLevel CLLImportant String _ -> String -> Either String ChatLogLevel forall a b. a -> Either a b Left String "Invalid log level" parseChatCmdLog :: ReadM ChatCmdLog parseChatCmdLog :: ReadM ChatCmdLog parseChatCmdLog = (String -> Either String ChatCmdLog) -> ReadM ChatCmdLog forall a. (String -> Either String a) -> ReadM a eitherReader ((String -> Either String ChatCmdLog) -> ReadM ChatCmdLog) -> (String -> Either String ChatCmdLog) -> ReadM ChatCmdLog forall a b. (a -> b) -> a -> b $ \case String "all" -> ChatCmdLog -> Either String ChatCmdLog forall a b. b -> Either a b Right ChatCmdLog CCLAll String "messages" -> ChatCmdLog -> Either String ChatCmdLog forall a b. b -> Either a b Right ChatCmdLog CCLMessages String "none" -> ChatCmdLog -> Either String ChatCmdLog forall a b. b -> Either a b Right ChatCmdLog CCLNone String _ -> String -> Either String ChatCmdLog forall a b. a -> Either a b Left String "Invalid chat command log level" getChatOpts :: FilePath -> FilePath -> IO ChatOpts getChatOpts :: String -> String -> IO ChatOpts getChatOpts String appDir String defaultDbName = ParserInfo ChatOpts -> IO ChatOpts forall a. ParserInfo a -> IO a execParser (ParserInfo ChatOpts -> IO ChatOpts) -> ParserInfo ChatOpts -> IO ChatOpts forall a b. (a -> b) -> a -> b $ Parser ChatOpts -> InfoMod ChatOpts -> ParserInfo ChatOpts forall a. Parser a -> InfoMod a -> ParserInfo a info (Parser ((ChatOpts -> ChatOpts) -> ChatOpts -> ChatOpts) forall a. Parser (a -> a) helper Parser ((ChatOpts -> ChatOpts) -> ChatOpts -> ChatOpts) -> Parser (ChatOpts -> ChatOpts) -> Parser (ChatOpts -> ChatOpts) forall a b. Parser (a -> b) -> Parser a -> Parser b forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b <*> Parser (ChatOpts -> ChatOpts) forall a. Parser (a -> a) versionOption Parser (ChatOpts -> ChatOpts) -> Parser ChatOpts -> Parser ChatOpts forall a b. Parser (a -> b) -> Parser a -> Parser b forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b <*> String -> String -> Parser ChatOpts chatOptsP String appDir String defaultDbName) (String -> InfoMod ChatOpts forall a. String -> InfoMod a header String versionStr InfoMod ChatOpts -> InfoMod ChatOpts -> InfoMod ChatOpts forall a. Semigroup a => a -> a -> a <> InfoMod ChatOpts forall a. InfoMod a fullDesc InfoMod ChatOpts -> InfoMod ChatOpts -> InfoMod ChatOpts forall a. Semigroup a => a -> a -> a <> String -> InfoMod ChatOpts forall a. String -> InfoMod a progDesc String "Start chat with DB_FILE file and use SERVER as SMP server") where versionOption :: Parser (a -> a) versionOption = String -> Mod OptionFields (a -> a) -> Parser (a -> a) forall a. String -> Mod OptionFields (a -> a) -> Parser (a -> a) infoOption String versionStr (String -> Mod OptionFields (a -> a) forall (f :: * -> *) a. HasName f => String -> Mod f a long String "version" Mod OptionFields (a -> a) -> Mod OptionFields (a -> a) -> Mod OptionFields (a -> a) forall a. Semigroup a => a -> a -> a <> Char -> Mod OptionFields (a -> a) forall (f :: * -> *) a. HasName f => Char -> Mod f a short Char 'v' Mod OptionFields (a -> a) -> Mod OptionFields (a -> a) -> Mod OptionFields (a -> a) forall a. Semigroup a => a -> a -> a <> String -> Mod OptionFields (a -> a) forall (f :: * -> *) a. String -> Mod f a help String "Show version") versionStr :: String versionStr = String -> String versionString String versionNumber printDbOpts :: CoreChatOpts -> IO () printDbOpts :: CoreChatOpts -> IO () printDbOpts CoreChatOpts opts = String -> IO () putStrLn (String -> IO ()) -> String -> IO () forall a b. (a -> b) -> a -> b $ String "db: " String -> String -> String forall a. Semigroup a => a -> a -> a <> ChatDbOpts -> String dbString (CoreChatOpts -> ChatDbOpts dbOptions CoreChatOpts opts)