calamity 0.1.9.3 → 0.1.9.4
raw patch · 14 files changed
+203/−50 lines, 14 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
+ Calamity.Commands: data Context
+ Calamity.Commands.CommandUtils: commandParams :: Command -> Text
+ Calamity.Commands.CommandUtils: commandPath :: Command -> [Text]
+ Calamity.Commands.CommandUtils: groupPath :: Group -> [Text]
+ Calamity.Gateway.DispatchEvents: instance Calamity.Internal.ConstructorName.CtorName Calamity.Gateway.DispatchEvents.DispatchData
+ Calamity.Internal.ConstructorName: class CtorName a
+ Calamity.Internal.ConstructorName: class GCtorName f
+ Calamity.Internal.ConstructorName: ctorName :: (CtorName a, Generic a, GCtorName (Rep a)) => a -> String
+ Calamity.Internal.ConstructorName: gctorName :: GCtorName f => f a -> String
+ Calamity.Internal.ConstructorName: instance forall k (c :: GHC.Generics.Meta) (f :: k -> *). GHC.Generics.Constructor c => Calamity.Internal.ConstructorName.GCtorName (GHC.Generics.C1 c f)
+ Calamity.Internal.ConstructorName: instance forall k (f :: k -> *) (d :: GHC.Generics.Meta). Calamity.Internal.ConstructorName.GCtorName f => Calamity.Internal.ConstructorName.GCtorName (GHC.Generics.D1 d f)
+ Calamity.Internal.ConstructorName: instance forall k (f :: k -> *) (g :: k -> *). (Calamity.Internal.ConstructorName.GCtorName f, Calamity.Internal.ConstructorName.GCtorName g) => Calamity.Internal.ConstructorName.GCtorName (f GHC.Generics.:+: g)
- Calamity.Cache.Eff: delDM :: forall r_a9Jrm. MemberWithError CacheEff r_a9Jrm => Snowflake DMChannel -> Sem r_a9Jrm ()
+ Calamity.Cache.Eff: delDM :: forall r_a9JDf. MemberWithError CacheEff r_a9JDf => Snowflake DMChannel -> Sem r_a9JDf ()
- Calamity.Cache.Eff: delGuild :: forall r_a9Jrf. MemberWithError CacheEff r_a9Jrf => Snowflake Guild -> Sem r_a9Jrf ()
+ Calamity.Cache.Eff: delGuild :: forall r_a9JD8. MemberWithError CacheEff r_a9JD8 => Snowflake Guild -> Sem r_a9JD8 ()
- Calamity.Cache.Eff: delMessage :: forall r_a9JrH. MemberWithError CacheEff r_a9JrH => Snowflake Message -> Sem r_a9JrH ()
+ Calamity.Cache.Eff: delMessage :: forall r_a9JDA. MemberWithError CacheEff r_a9JDA => Snowflake Message -> Sem r_a9JDA ()
- Calamity.Cache.Eff: delUnavailableGuild :: forall r_a9JrA. MemberWithError CacheEff r_a9JrA => Snowflake Guild -> Sem r_a9JrA ()
+ Calamity.Cache.Eff: delUnavailableGuild :: forall r_a9JDt. MemberWithError CacheEff r_a9JDt => Snowflake Guild -> Sem r_a9JDt ()
- Calamity.Cache.Eff: delUser :: forall r_a9Jrt. MemberWithError CacheEff r_a9Jrt => Snowflake User -> Sem r_a9Jrt ()
+ Calamity.Cache.Eff: delUser :: forall r_a9JDm. MemberWithError CacheEff r_a9JDm => Snowflake User -> Sem r_a9JDm ()
- Calamity.Cache.Eff: getBotUser :: forall r_a9Jr9. MemberWithError CacheEff r_a9Jr9 => Sem r_a9Jr9 (Maybe User)
+ Calamity.Cache.Eff: getBotUser :: forall r_a9JD2. MemberWithError CacheEff r_a9JD2 => Sem r_a9JD2 (Maybe User)
- Calamity.Cache.Eff: getDM :: forall r_a9Jrj. MemberWithError CacheEff r_a9Jrj => Snowflake DMChannel -> Sem r_a9Jrj (Maybe DMChannel)
+ Calamity.Cache.Eff: getDM :: forall r_a9JDc. MemberWithError CacheEff r_a9JDc => Snowflake DMChannel -> Sem r_a9JDc (Maybe DMChannel)
- Calamity.Cache.Eff: getDMs :: forall r_a9Jrl. MemberWithError CacheEff r_a9Jrl => Sem r_a9Jrl [DMChannel]
+ Calamity.Cache.Eff: getDMs :: forall r_a9JDe. MemberWithError CacheEff r_a9JDe => Sem r_a9JDe [DMChannel]
- Calamity.Cache.Eff: getGuild :: forall r_a9Jrc. MemberWithError CacheEff r_a9Jrc => Snowflake Guild -> Sem r_a9Jrc (Maybe Guild)
+ Calamity.Cache.Eff: getGuild :: forall r_a9JD5. MemberWithError CacheEff r_a9JD5 => Snowflake Guild -> Sem r_a9JD5 (Maybe Guild)
- Calamity.Cache.Eff: getGuilds :: forall r_a9Jre. MemberWithError CacheEff r_a9Jre => Sem r_a9Jre [Guild]
+ Calamity.Cache.Eff: getGuilds :: forall r_a9JD7. MemberWithError CacheEff r_a9JD7 => Sem r_a9JD7 [Guild]
- Calamity.Cache.Eff: getMessage :: forall r_a9JrE. MemberWithError CacheEff r_a9JrE => Snowflake Message -> Sem r_a9JrE (Maybe Message)
+ Calamity.Cache.Eff: getMessage :: forall r_a9JDx. MemberWithError CacheEff r_a9JDx => Snowflake Message -> Sem r_a9JDx (Maybe Message)
- Calamity.Cache.Eff: getMessages :: forall r_a9JrG. MemberWithError CacheEff r_a9JrG => Sem r_a9JrG [Message]
+ Calamity.Cache.Eff: getMessages :: forall r_a9JDz. MemberWithError CacheEff r_a9JDz => Sem r_a9JDz [Message]
- Calamity.Cache.Eff: getUnavailableGuilds :: forall r_a9Jrz. MemberWithError CacheEff r_a9Jrz => Sem r_a9Jrz [Snowflake Guild]
+ Calamity.Cache.Eff: getUnavailableGuilds :: forall r_a9JDs. MemberWithError CacheEff r_a9JDs => Sem r_a9JDs [Snowflake Guild]
- Calamity.Cache.Eff: getUser :: forall r_a9Jrq. MemberWithError CacheEff r_a9Jrq => Snowflake User -> Sem r_a9Jrq (Maybe User)
+ Calamity.Cache.Eff: getUser :: forall r_a9JDj. MemberWithError CacheEff r_a9JDj => Snowflake User -> Sem r_a9JDj (Maybe User)
- Calamity.Cache.Eff: getUsers :: forall r_a9Jrs. MemberWithError CacheEff r_a9Jrs => Sem r_a9Jrs [User]
+ Calamity.Cache.Eff: getUsers :: forall r_a9JDl. MemberWithError CacheEff r_a9JDl => Sem r_a9JDl [User]
- Calamity.Cache.Eff: isUnavailableGuild :: forall r_a9Jrx. MemberWithError CacheEff r_a9Jrx => Snowflake Guild -> Sem r_a9Jrx Bool
+ Calamity.Cache.Eff: isUnavailableGuild :: forall r_a9JDq. MemberWithError CacheEff r_a9JDq => Snowflake Guild -> Sem r_a9JDq Bool
- Calamity.Cache.Eff: setBotUser :: forall r_a9Jr7. MemberWithError CacheEff r_a9Jr7 => User -> Sem r_a9Jr7 ()
+ Calamity.Cache.Eff: setBotUser :: forall r_a9JD0. MemberWithError CacheEff r_a9JD0 => User -> Sem r_a9JD0 ()
- Calamity.Cache.Eff: setDM :: forall r_a9Jrh. MemberWithError CacheEff r_a9Jrh => DMChannel -> Sem r_a9Jrh ()
+ Calamity.Cache.Eff: setDM :: forall r_a9JDa. MemberWithError CacheEff r_a9JDa => DMChannel -> Sem r_a9JDa ()
- Calamity.Cache.Eff: setGuild :: forall r_a9Jra. MemberWithError CacheEff r_a9Jra => Guild -> Sem r_a9Jra ()
+ Calamity.Cache.Eff: setGuild :: forall r_a9JD3. MemberWithError CacheEff r_a9JD3 => Guild -> Sem r_a9JD3 ()
- Calamity.Cache.Eff: setMessage :: forall r_a9JrC. MemberWithError CacheEff r_a9JrC => Message -> Sem r_a9JrC ()
+ Calamity.Cache.Eff: setMessage :: forall r_a9JDv. MemberWithError CacheEff r_a9JDv => Message -> Sem r_a9JDv ()
- Calamity.Cache.Eff: setUnavailableGuild :: forall r_a9Jrv. MemberWithError CacheEff r_a9Jrv => Snowflake Guild -> Sem r_a9Jrv ()
+ Calamity.Cache.Eff: setUnavailableGuild :: forall r_a9JDo. MemberWithError CacheEff r_a9JDo => Snowflake Guild -> Sem r_a9JDo ()
- Calamity.Cache.Eff: setUser :: forall r_a9Jro. MemberWithError CacheEff r_a9Jro => User -> Sem r_a9Jro ()
+ Calamity.Cache.Eff: setUser :: forall r_a9JDh. MemberWithError CacheEff r_a9JDh => User -> Sem r_a9JDh ()
- Calamity.Client.Client: Dispatch :: DispatchData -> CalamityEvent
+ Calamity.Client.Client: Dispatch :: Int -> DispatchData -> CalamityEvent
- Calamity.Commands.ParsePrefix: parsePrefix :: forall r_a6EUN. MemberWithError ParsePrefix r_a6EUN => Message -> Sem r_a6EUN (Maybe (Text, Text))
+ Calamity.Commands.ParsePrefix: parsePrefix :: forall r_a6F6G. MemberWithError ParsePrefix r_a6F6G => Message -> Sem r_a6F6G (Maybe (Text, Text))
- Calamity.Gateway.DispatchEvents: Dispatch :: DispatchData -> CalamityEvent
+ Calamity.Gateway.DispatchEvents: Dispatch :: Int -> DispatchData -> CalamityEvent
- Calamity.Internal.LocalWriter: llisten :: forall o_aC3M r_aCfX a_XC3M. MemberWithError (LocalWriter o_aC3M) r_aCfX => Sem r_aCfX a_XC3M -> Sem r_aCfX (o_aC3M, a_XC3M)
+ Calamity.Internal.LocalWriter: llisten :: forall o_aCfF r_aCrQ a_XCfF. MemberWithError (LocalWriter o_aCfF) r_aCrQ => Sem r_aCrQ a_XCfF -> Sem r_aCrQ (o_aCfF, a_XCfF)
- Calamity.Internal.LocalWriter: ltell :: forall o_aC3I r_aCfV. MemberWithError (LocalWriter o_aC3I) r_aCfV => o_aC3I -> Sem r_aCfV ()
+ Calamity.Internal.LocalWriter: ltell :: forall o_aCfB r_aCrO. MemberWithError (LocalWriter o_aCfB) r_aCrO => o_aCfB -> Sem r_aCrO ()
- Calamity.Internal.RunIntoIO: intoIO :: forall p_aDFP r_aDFR r_aDL1. MemberWithError (IntoIO p_aDFP r_aDFR) r_aDL1 => (p_aDFP -> Sem r_aDL1 r_aDFR) -> Sem r_aDL1 (p_aDFP -> IO (Maybe r_aDFR))
+ Calamity.Internal.RunIntoIO: intoIO :: forall p_aDRI r_aDRK r_aDWU. MemberWithError (IntoIO p_aDRI r_aDRK) r_aDWU => (p_aDRI -> Sem r_aDWU r_aDRK) -> Sem r_aDWU (p_aDRI -> IO (Maybe r_aDRK))
- Calamity.Metrics.Eff: addCounter :: forall r_aGhQ. MemberWithError MetricEff r_aGhQ => Int -> Counter -> Sem r_aGhQ Int
+ Calamity.Metrics.Eff: addCounter :: forall r_aGtJ. MemberWithError MetricEff r_aGtJ => Int -> Counter -> Sem r_aGtJ Int
- Calamity.Metrics.Eff: modifyGauge :: forall r_aGhT. MemberWithError MetricEff r_aGhT => (Double -> Double) -> Gauge -> Sem r_aGhT Double
+ Calamity.Metrics.Eff: modifyGauge :: forall r_aGtM. MemberWithError MetricEff r_aGtM => (Double -> Double) -> Gauge -> Sem r_aGtM Double
- Calamity.Metrics.Eff: observeHistogram :: forall r_aGhW. MemberWithError MetricEff r_aGhW => Double -> Histogram -> Sem r_aGhW HistogramSample
+ Calamity.Metrics.Eff: observeHistogram :: forall r_aGtP. MemberWithError MetricEff r_aGtP => Double -> Histogram -> Sem r_aGtP HistogramSample
- Calamity.Metrics.Eff: registerCounter :: forall r_aGhG. MemberWithError MetricEff r_aGhG => Text -> [(Text, Text)] -> Sem r_aGhG Counter
+ Calamity.Metrics.Eff: registerCounter :: forall r_aGtz. MemberWithError MetricEff r_aGtz => Text -> [(Text, Text)] -> Sem r_aGtz Counter
- Calamity.Metrics.Eff: registerGauge :: forall r_aGhJ. MemberWithError MetricEff r_aGhJ => Text -> [(Text, Text)] -> Sem r_aGhJ Gauge
+ Calamity.Metrics.Eff: registerGauge :: forall r_aGtC. MemberWithError MetricEff r_aGtC => Text -> [(Text, Text)] -> Sem r_aGtC Gauge
- Calamity.Metrics.Eff: registerHistogram :: forall r_aGhM. MemberWithError MetricEff r_aGhM => Text -> [(Text, Text)] -> [Double] -> Sem r_aGhM Histogram
+ Calamity.Metrics.Eff: registerHistogram :: forall r_aGtF. MemberWithError MetricEff r_aGtF => Text -> [(Text, Text)] -> [Double] -> Sem r_aGtF Histogram
Files
- calamity.cabal +3/−2
- src/Calamity/Client.hs +38/−1
- src/Calamity/Client/Client.hs +20/−16
- src/Calamity/Commands.hs +29/−1
- src/Calamity/Commands/CommandUtils.hs +13/−1
- src/Calamity/Commands/Help.hs +5/−11
- src/Calamity/Commands/Utils.hs +6/−2
- src/Calamity/Gateway.hs +15/−1
- src/Calamity/Gateway/DispatchEvents.hs +8/−3
- src/Calamity/Gateway/Shard.hs +1/−6
- src/Calamity/HTTP.hs +30/−1
- src/Calamity/HTTP/Internal/Request.hs +0/−4
- src/Calamity/Internal/ConstructorName.hs +24/−0
- src/Calamity/Types.hs +11/−1
calamity.cabal view
@@ -4,10 +4,10 @@ -- -- see: https://github.com/sol/hpack ----- hash: f88c96cab00a86482d236a3a5f86d11d093b8179d8390725eabf46a12e054881+-- hash: d09b5d61b03cb493c415218e661c595c070b5c50807b090c8689f0cbe15a9782 name: calamity-version: 0.1.9.3+version: 0.1.9.4 synopsis: A library for writing discord bots description: Please see the README on GitHub at <https://github.com/nitros12/calamity#readme> category: Network, Web@@ -73,6 +73,7 @@ Calamity.HTTP.Webhook Calamity.Internal.AesonThings Calamity.Internal.BoundedStore+ Calamity.Internal.ConstructorName Calamity.Internal.GenericCurry Calamity.Internal.LocalWriter Calamity.Internal.RunIntoIO
src/Calamity/Client.hs view
@@ -1,7 +1,44 @@ -- | Module containing the core client stuff module Calamity.Client ( module Calamity.Client.Client- , module Calamity.Client.Types ) where+ , module Calamity.Client.Types+ -- * Client stuff+ -- $clientDocs+ ) where import Calamity.Client.Client import Calamity.Client.Types++-- $clientDocs+--+-- This module provides the core components for running a discord client, along+-- with abstractions for registering event handlers, firing custom events, and+-- waiting on events.+--+--+-- ==== Registered Metrics+--+-- 1. Counter: @"events_recieved" [type, shard]@+--+-- Incremented for each event received, the @type@ parameter is the type+-- of event (the name of the constructor in+-- 'Calamity.Gateway.DispatchEvents.DispatchData'), and @shard@ is the+-- ID of the shard that received the event.+--+-- 2. Histogram: @"cache_update"@+--+-- Tracks how long it takes to update the cache after recieving an event.+--+-- 3. Histogram: @"event_handle"@+--+-- Tracks how long it takes to process an event handler for an event.+--+--+-- ==== Examples+--+-- A simple client that prints every message recieved:+--+-- @+-- 'Control.Monad.void' . 'Polysemy.runFinal' . 'Polysemy.embedToFinal' . 'Calamity.Cache.InMemory.runCacheInMemory' . 'Calamity.Metrics.Noop.runMetricsNoop' $ 'runBotIO' ('Calamity.Types.Token.BotToken' token) $ do+-- 'react' \@\''MessageCreateEvt' (\msg -> 'Polysemy.embed' $ 'print' msg)+-- @
src/Calamity/Client/Client.hs view
@@ -19,23 +19,24 @@ import Calamity.Gateway.DispatchEvents import Calamity.Gateway.Types import Calamity.HTTP.Internal.Ratelimit+import Calamity.Internal.ConstructorName import Calamity.Internal.GenericCurry import Calamity.Internal.RunIntoIO-import qualified Calamity.Internal.SnowflakeMap as SM+import qualified Calamity.Internal.SnowflakeMap as SM import Calamity.Internal.Updateable import Calamity.Internal.Utils import Calamity.Metrics.Eff import Calamity.Types.Model.Channel import Calamity.Types.Model.Guild-import Calamity.Types.Model.Presence ( Presence(..) )+import Calamity.Types.Model.Presence ( Presence(..) ) import Calamity.Types.Snowflake import Calamity.Types.Token import Control.Concurrent.Chan.Unagi import Control.Concurrent.MVar import Control.Concurrent.STM-import Control.Exception ( SomeException )-import Control.Lens hiding ( (<.>) )+import Control.Exception ( SomeException )+import Control.Lens hiding ( (<.>) ) import Control.Monad import Data.Default.Class@@ -44,21 +45,24 @@ import Data.IORef import Data.Maybe import Data.Proxy+import qualified Data.Text as S import Data.Time.Clock.POSIX import Data.Traversable import Data.Typeable -import qualified DiPolysemy as Di+import qualified DiPolysemy as Di import Fmt -import qualified Polysemy as P-import qualified Polysemy.Async as P-import qualified Polysemy.AtomicState as P-import qualified Polysemy.Error as P-import qualified Polysemy.Fail as P-import qualified Polysemy.Reader as P+import qualified Polysemy as P+import qualified Polysemy.Async as P+import qualified Polysemy.AtomicState as P+import qualified Polysemy.Error as P+import qualified Polysemy.Fail as P+import qualified Polysemy.Reader as P +import TextShow ( TextShow(showt) )+ timeA :: P.Member (P.Embed IO) r => P.Sem r a -> P.Sem r (Double, a) timeA m = do start <- P.embed getPOSIXTime@@ -294,7 +298,7 @@ evt' <- P.embed $ readChan outc case evt' of -- NOTE: these raise's are needed to raise into the Error effect- Dispatch evt -> P.raise $ handleEvent evt+ Dispatch sid evt -> P.raise $ handleEvent sid evt Custom s d -> P.raise $ handleCustomEvent s d ShutDown -> P.throw () debug "leaving client loop"@@ -315,11 +319,13 @@ Right _ -> pure () Left e -> debug $ "got exception: " +|| e ||+ "" -handleEvent :: BotC r => DispatchData -> P.Sem r ()-handleEvent data' = do+handleEvent :: BotC r => Int -> DispatchData -> P.Sem r ()+handleEvent shardID data' = do debug "handling an event" eventHandlers <- P.atomicGet actions <- P.runFail $ do+ evtCounter <- registerCounter "events_received" [("type", S.pack $ ctorName data'), ("shard", showt shardID)]+ void $ addCounter 1 evtCounter cacheUpdateHisto <- registerHistogram "cache_update" mempty [10, 20..100] (time, res) <- timeA $ Di.reset $ handleEvent' eventHandlers data' void $ observeHistogram time cacheUpdateHisto@@ -470,8 +476,6 @@ pure $ map (\f -> f guild role) (getEventHandlers @'GuildRoleDeleteEvt eh) handleEvent' eh evt@(MessageCreate msg) = do- messagesReceived <- registerCounter "messages_received" mempty- void $ addCounter 1 messagesReceived updateCache evt pure $ map ($ msg) (getEventHandlers @'MessageCreateEvt eh)
src/Calamity/Commands.hs view
@@ -8,6 +8,7 @@ , module Calamity.Commands.ParsePrefix , module Calamity.Commands.Parser , module Calamity.Commands.Help+ , module Calamity.Commands.Context -- * Commands -- $commandDocs ) where@@ -19,6 +20,7 @@ import Calamity.Commands.ParsePrefix import Calamity.Commands.Parser import Calamity.Commands.Utils+import Calamity.Commands.Context ( Context ) -- $commandDocs --@@ -35,6 +37,32 @@ -- A default help command is provided in 'Calamity.Commands.Help' which can be -- added just by using 'helpCommand' inside the command declaration DSL. --+--+-- ==== Custom Events+--+-- the event handler registered by 'addCommands' will fire the following custom events:+--+-- 1. @"command-error" ('Context', 'CommandError')@+--+-- Fired when a command returns an error.+--+-- 2. @"command-not-found" ['Data.Text.Lazy.Text']@+--+-- Fired when a valid prefix is used, but the command is not found.+--+-- 3. @"command-invoked" 'Context'@+--+-- Fired when a command is successfully invoked.+--+--+-- ==== Registered Metrics+--+-- 1. Counter: @"commands_invoked" [name]@+--+-- Incremented on each command invokation, the parameter @name@ is the+-- path/name of the invoked command.+--+-- -- ==== Examples -- -- An example of using commands:@@ -43,7 +71,7 @@ -- 'addCommands' $ do -- 'helpCommand' -- 'command' \@\'['Calamity.Types.Model.User.User'] "utest" $ \ctx u \-\> do--- 'Control.Monad.void' $ 'Calamity.Tellable.tell' ctx $ "got user: " '<>' 'TextShow.showtl' u+-- 'Control.Monad.void' $ 'Calamity.Types.Tellable.tell' ctx $ "got user: " '<>' 'TextShow.showtl' u -- 'group' "admin" $ do -- 'command' \@'[] "bye" $ \ctx -> do -- 'Control.Monad.void' $ 'Calamity.Types.Tellable.tell' ctx "bye!"
src/Calamity/Commands/CommandUtils.hs view
@@ -7,7 +7,10 @@ , buildParser , buildCallback , runCommand- , invokeCommand ) where+ , invokeCommand+ , groupPath+ , commandPath+ , commandParams ) where import Calamity.Commands.Check import Calamity.Commands.Command@@ -30,6 +33,15 @@ import qualified Polysemy as P import qualified Polysemy.Error as P import qualified Polysemy.Fail as P++groupPath :: Group -> [S.Text]+groupPath grp = maybe [] groupPath (grp ^. #parent) ++ [grp ^. #name]++commandPath :: Command -> [S.Text]+commandPath Command { name, parent } = maybe [] groupPath parent ++ [name]++commandParams :: Command -> L.Text+commandParams Command { params } = L.fromStrict $ S.unwords params -- | Given the properties of a 'Command' with the @parser@ and @callback@ in the -- 'P.Sem' monad, build a command by transforming the Polysemy actions into IO
src/Calamity/Commands/Help.hs view
@@ -33,16 +33,10 @@ helpCommandHelp :: Context -> L.Text helpCommandHelp _ = "Show help for a command or group." -groupPath :: Group -> [S.Text]-groupPath grp = maybe [] groupPath (grp ^. #parent) ++ [grp ^. #name]--commandParams :: Command -> L.Text-commandParams Command { params } = L.fromStrict $ S.intercalate " " params- helpForCommand :: Context -> Command -> L.Text-helpForCommand ctx (cmd@Command { name, parent, help }) = "```\nUsage: " <> prefix' <> path' <> " " <> params' <> "\n\n" <> help ctx <> "\n```"+helpForCommand ctx (cmd@Command { help }) = "```\nUsage: " <> prefix' <> path' <> " " <> params' <> "\n\n" <> help ctx <> "\n```" where prefix' = ctx ^. #prefix- path' = L.fromStrict . S.intercalate " " $ maybe [] groupPath parent ++ [name]+ path' = L.fromStrict . S.unwords $ commandPath cmd params' = commandParams cmd fmtCommandWithParams :: Command -> L.Text@@ -50,7 +44,7 @@ helpForGroup :: Context -> Group -> L.Text helpForGroup ctx grp = "```\nGroup: " <> path' <> "\n\n" <> (grp ^. #help) ctx <> "\n" <> groupsMsg <> commandsMsg <> "\n```"- where path' = L.fromStrict . S.intercalate " " $ groupPath grp+ where path' = L.fromStrict . S.unwords $ groupPath grp groups = LH.keys $ grp ^. #children commands = LH.elems $ grp ^. #commands groupsMsg = if null groups then "" else "The following child groups exist:\n" <> L.fromStrict (S.unlines . map ("- " <>) $ groups)@@ -73,11 +67,11 @@ Just (Group' grp@Group { name } remainingPath) -> let failedMsg = if null remainingPath then ""- else "No command or group with the path: `" <> L.fromStrict (S.intercalate " " path) <> "` exists for the group: `" <> L.fromStrict name <> "`\n"+ else "No command or group with the path: `" <> L.fromStrict (S.unwords path) <> "` exists for the group: `" <> L.fromStrict name <> "`\n" in void $ tell @L.Text ctx $ failedMsg <> "Help for group `" <> L.fromStrict name <> "`: \n" <> helpForGroup ctx grp Nothing -> let failedMsg = if null path then ""- else "No command or group with the path: `" <> L.fromStrict (S.intercalate " " path) <> "` was found.\n"+ else "No command or group with the path: `" <> L.fromStrict (S.unwords path) <> "` was found.\n" in void $ tell @L.Text ctx $ failedMsg <> rootHelp handler -- | Given a 'CommandHandler', optionally a parent 'Group', and a list of 'Check's,
src/Calamity/Commands/Utils.hs view
@@ -6,6 +6,7 @@ , buildContext ) where import Calamity.Cache.Eff+import Calamity.Metrics.Eff import Calamity.Client.Client import Calamity.Client.Types import Calamity.Commands.Command@@ -64,8 +65,11 @@ case err of Left (ERR ctx e) -> fire $ customEvt @"command-error" (ctx, e) Left (NF path) -> fire $ customEvt @"command-not-found" path- Left _ -> pure () -- "ignore if no prefix or if context couldn't be built"- Right ctx -> fire $ customEvt @"command-run" ctx+ Left _ -> pure () -- ignore if no prefix or if context couldn't be built+ Right ctx -> do+ cmdInvoke <- registerCounter "commands_invoked" [("name", S.unwords $ commandPath (ctx ^. #command))]+ void $ addCounter 1 cmdInvoke+ fire $ customEvt @"command-invoked" ctx pure (remove, handler, res)
src/Calamity/Gateway.hs view
@@ -1,7 +1,21 @@ -- | module Calamity.Gateway ( module Calamity.Gateway.Shard- , module Calamity.Gateway.Types ) where+ , module Calamity.Gateway.Types+ -- * Gateway+ -- $gatewayDocs+ ) where import Calamity.Gateway.Shard import Calamity.Gateway.Types++-- $gatewayDocs+--+-- This module contains all the gateway related things.+--+--+-- ==== Registered Metrics+--+-- 1. Gauge: @"active_shards"@+--+-- Keeps track of how many shards are currently active.
src/Calamity/Gateway/DispatchEvents.hs view
@@ -2,6 +2,7 @@ module Calamity.Gateway.DispatchEvents where import Calamity.Internal.AesonThings+import Calamity.Internal.ConstructorName import Calamity.Internal.Utils () import Calamity.Types.Model.Channel import Calamity.Types.Model.Channel.Message@@ -26,8 +27,12 @@ import GHC.Generics data CalamityEvent- = Dispatch DispatchData- | Custom TypeRep Dynamic+ = Dispatch+ Int -- ^ The shard that pushed this event+ DispatchData -- ^ The attached data+ | Custom+ TypeRep -- ^ The name of the custom event+ Dynamic -- ^ The data sent to the custom event | ShutDown deriving ( Show, Generic ) @@ -65,7 +70,7 @@ | VoiceStateUpdate VoiceStateUpdateData | VoiceServerUpdate VoiceServerUpdateData | WebhooksUpdate WebhooksUpdateData- deriving ( Show, Generic )+ deriving ( Show, Generic, CtorName ) data ReadyData = ReadyData { v :: Integer
src/Calamity/Gateway/Shard.hs view
@@ -48,8 +48,6 @@ import Prelude hiding ( error ) -import TextShow- import Wuss data Websocket m a where@@ -223,8 +221,6 @@ , presence = Nothing }) - receivedMessages <- registerCounter "received_messages" [("shard", showt $ shard ^. #shardID)]- result <- P.resourceToIOFinal $ P.bracket (P.embed $ newTBMQueueIO 1) (P.embed . atomically . closeTBMQueue) (\q -> do@@ -233,7 +229,6 @@ _discordThread <- P.async $ discordStream ws q (fromEitherVoid <$>) . P.raise . P.runError . forever $ do -- only we close the queue- void $ addCounter 1 receivedMessages msg <- P.embed . atomically $ readTBMQueue q handleMsg $ fromJust msg) @@ -257,7 +252,7 @@ _ -> pure () shard <- P.atomicGets (^. #shardS)- P.embed $ UC.writeChan (shard ^. #evtIn) (Dispatch data')+ P.embed $ UC.writeChan (shard ^. #evtIn) (Dispatch (shard ^. #shardID) data') HeartBeatReq -> do debug "Received heartbeat request"
src/Calamity/HTTP.hs view
@@ -10,7 +10,10 @@ , module Calamity.HTTP.User , module Calamity.HTTP.Reason , module Calamity.HTTP.Internal.Types- , module Calamity.HTTP.Webhook ) where+ , module Calamity.HTTP.Webhook+ -- * HTTP+ -- $httpDocs+ ) where import Calamity.HTTP.AuditLog import Calamity.HTTP.Channel@@ -23,3 +26,29 @@ import Calamity.HTTP.Reason import Calamity.HTTP.User import Calamity.HTTP.Webhook++-- $httpDocs+--+-- This module contains all the http related things+--+--+-- ==== Registered Metrics+--+-- 1. Gauge: @"inflight_requests" [route]@+--+-- Keeps track of how many requests are currently in-flight, the @route@+-- parameter will be the route that is currently active.+--+-- 2. Counter: @"total_requests" [route]@+--+-- Incremented on every request, the @route@ parameter is the route that+-- the request was made on.+--+--+-- ==== Examples+--+-- Editing a message:+--+-- @+-- 'invoke' $ 'EditMessage' someChannel someMessage ('Just' "new content") 'Nothing'+-- @
src/Calamity/HTTP/Internal/Request.hs view
@@ -81,10 +81,6 @@ void $ modifyGauge succ inFlightRequests void $ addCounter 1 totalRequests - whenJust (route' ^. #guildID) $ \guildID -> do- totalRequestsGuild <- registerCounter "total_requests" [("guild", showt guildID)]- void $ addCounter 1 totalRequestsGuild- resp <- attr "route" (route' ^. #path) $ doRequest rlState' route' (action a (requestOptions token') (route' ^. #path . unpacked))
+ src/Calamity/Internal/ConstructorName.hs view
@@ -0,0 +1,24 @@+-- | Get the constructor name of something+module Calamity.Internal.ConstructorName+ ( CtorName(..)+ , GCtorName(..) ) where++import GHC.Generics++class GCtorName f where+ gctorName :: f a -> String++instance Constructor c => GCtorName (C1 c f) where+ gctorName = conName++instance GCtorName f => GCtorName (D1 d f) where+ gctorName (M1 a) = gctorName a++instance (GCtorName f, GCtorName g) => GCtorName (f :+: g) where+ gctorName (L1 a) = gctorName a+ gctorName (R1 a) = gctorName a++class CtorName a where+ ctorName :: a -> String+ default ctorName :: (Generic a, GCtorName (Rep a)) => a -> String+ ctorName = gctorName . from
src/Calamity/Types.hs view
@@ -5,7 +5,10 @@ , module Calamity.Types.Snowflake , module Calamity.Types.Token , module Calamity.Types.Tellable- , module Calamity.Types.UnixTimestamp ) where+ , module Calamity.Types.UnixTimestamp+ -- * Types+ -- $typesDocs+ ) where import Calamity.Types.Model import Calamity.Types.Partial@@ -13,3 +16,10 @@ import Calamity.Types.Token import Calamity.Types.Tellable import Calamity.Types.UnixTimestamp++-- $typesDocs+--+-- This module collects all discord models, and other useful types together.+--+-- The 'Tellable' class is also in here, which allows you to construct and send+-- messages to things to you can send messages to in a neat way.