Implement some botrulez
This commit is contained in:
parent
9df9280f5f
commit
15cd6724d2
5 changed files with 94 additions and 13 deletions
|
|
@ -1,6 +1,7 @@
|
||||||
# Changelog for haboli
|
# Changelog for haboli
|
||||||
|
|
||||||
## upcoming
|
## upcoming
|
||||||
|
- add `Haboli.Euphoria.Botrulez` module
|
||||||
- add `Haboli.Euphoria.Command` module and submodules
|
- add `Haboli.Euphoria.Command` module and submodules
|
||||||
- add `Haboli.Euphoria.Listing` module
|
- add `Haboli.Euphoria.Listing` module
|
||||||
- add `Haboli.Euphoria.Util` module and move `respondingToPing` there
|
- add `Haboli.Euphoria.Util` module and move `respondingToPing` there
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ cabal-version: 1.12
|
||||||
--
|
--
|
||||||
-- see: https://github.com/sol/hpack
|
-- see: https://github.com/sol/hpack
|
||||||
--
|
--
|
||||||
-- hash: 15fd0a6cea4710f753e56b5d0232a7986b434e5fab8fee7855e81e311f87499c
|
-- hash: ae5e8a6e8abe1ff515797a54dfa9acd185df7699102b31190d569ccfe3a693f8
|
||||||
|
|
||||||
name: haboli
|
name: haboli
|
||||||
version: 0.3.1.0
|
version: 0.3.1.0
|
||||||
|
|
@ -31,6 +31,7 @@ library
|
||||||
exposed-modules:
|
exposed-modules:
|
||||||
Haboli.Euphoria
|
Haboli.Euphoria
|
||||||
Haboli.Euphoria.Api
|
Haboli.Euphoria.Api
|
||||||
|
Haboli.Euphoria.Botrulez
|
||||||
Haboli.Euphoria.Client
|
Haboli.Euphoria.Client
|
||||||
Haboli.Euphoria.Command
|
Haboli.Euphoria.Command
|
||||||
Haboli.Euphoria.Command.Megaparsec
|
Haboli.Euphoria.Command.Megaparsec
|
||||||
|
|
|
||||||
54
src/Haboli/Euphoria/Botrulez.hs
Normal file
54
src/Haboli/Euphoria/Botrulez.hs
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
|
|
||||||
|
module Haboli.Euphoria.Botrulez
|
||||||
|
( botrulezPingGeneral
|
||||||
|
, botrulezPingSpecific
|
||||||
|
, botrulezHelpGeneral
|
||||||
|
, botrulezHelpSpecific
|
||||||
|
, botrulezUptimeSpecific
|
||||||
|
, botrulezKillSpecific
|
||||||
|
) where
|
||||||
|
|
||||||
|
import Control.Monad
|
||||||
|
import Control.Monad.IO.Class
|
||||||
|
import qualified Data.Text as T
|
||||||
|
import Data.Time
|
||||||
|
|
||||||
|
import Haboli.Euphoria.Api
|
||||||
|
import Haboli.Euphoria.Client
|
||||||
|
import Haboli.Euphoria.Command
|
||||||
|
import Haboli.Euphoria.Command.Simple
|
||||||
|
import Haboli.Euphoria.Util
|
||||||
|
|
||||||
|
botrulezPingGeneral :: Command e
|
||||||
|
botrulezPingGeneral = cmdGeneral "ping" $ \msg ->
|
||||||
|
void $ reply msg "Pong!"
|
||||||
|
|
||||||
|
botrulezPingSpecific :: T.Text -> Command e
|
||||||
|
botrulezPingSpecific name = cmdSpecific "ping" name $ \msg ->
|
||||||
|
void $ reply msg "Pong!"
|
||||||
|
|
||||||
|
botrulezHelpGeneral :: T.Text -> Command e
|
||||||
|
botrulezHelpGeneral help = cmdGeneral "help" $ \msg ->
|
||||||
|
void $ reply msg help
|
||||||
|
|
||||||
|
botrulezHelpSpecific :: T.Text -> T.Text -> Command e
|
||||||
|
botrulezHelpSpecific name help = cmdSpecific "help" name $ \msg ->
|
||||||
|
void $ reply msg help
|
||||||
|
|
||||||
|
botrulezUptimeSpecific :: T.Text -> UTCTime -> Command e
|
||||||
|
botrulezUptimeSpecific name since = cmdSpecific "uptime" name $ \msg -> do
|
||||||
|
now <- liftIO getCurrentTime
|
||||||
|
let delta = diffUTCTime now since
|
||||||
|
void $ reply msg $ mconcat
|
||||||
|
[ "/me has been up since "
|
||||||
|
, formatUTCTime since
|
||||||
|
, " UTC ("
|
||||||
|
, formatNominalDiffTime delta
|
||||||
|
, ")"
|
||||||
|
]
|
||||||
|
|
||||||
|
botrulezKillSpecific :: T.Text -> Command T.Text
|
||||||
|
botrulezKillSpecific name = cmdSpecific "kill" name $ \msg -> do
|
||||||
|
void $ reply msg "/me dies"
|
||||||
|
throw $ "I was killed by " <> svNick (msgSender msg)
|
||||||
|
|
@ -8,14 +8,18 @@ module Haboli.Euphoria.ExampleBot
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Control.Monad
|
import Control.Monad
|
||||||
|
import Control.Monad.IO.Class
|
||||||
import Control.Monad.Trans.Class
|
import Control.Monad.Trans.Class
|
||||||
import Control.Monad.Trans.State
|
import Control.Monad.Trans.State
|
||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
|
import Data.Time
|
||||||
|
|
||||||
import Haboli.Euphoria
|
import Haboli.Euphoria
|
||||||
|
import Haboli.Euphoria.Botrulez
|
||||||
|
|
||||||
newtype BotState = BotState
|
data BotState = BotState
|
||||||
{ botListing :: Listing
|
{ botStartTime :: UTCTime
|
||||||
|
, botListing :: Listing
|
||||||
} deriving (Show)
|
} deriving (Show)
|
||||||
|
|
||||||
type Bot = StateT BotState (Client T.Text)
|
type Bot = StateT BotState (Client T.Text)
|
||||||
|
|
@ -26,23 +30,26 @@ type Bot = StateT BotState (Client T.Text)
|
||||||
-- > runClient defaultConfig $ exampleBot Nothing
|
-- > runClient defaultConfig $ exampleBot Nothing
|
||||||
exampleBot :: Maybe T.Text -> Client T.Text ()
|
exampleBot :: Maybe T.Text -> Client T.Text ()
|
||||||
exampleBot mPasswd = do
|
exampleBot mPasswd = do
|
||||||
|
startTime <- liftIO getCurrentTime
|
||||||
initialEvents <- untilConnected $
|
initialEvents <- untilConnected $
|
||||||
respondingToBounce mPasswd $
|
respondingToBounce mPasswd $
|
||||||
respondingToPing nextEvent
|
respondingToPing nextEvent
|
||||||
listing <- preferNick "ExampleBot" $ newListing initialEvents
|
listing <- preferNick "ExampleBot" $ newListing initialEvents
|
||||||
void $ runStateT botMain $ BotState listing
|
void $ runStateT botMain $ BotState startTime listing
|
||||||
|
|
||||||
botMain :: Bot ()
|
botMain :: Bot ()
|
||||||
botMain = forever $ do
|
botMain = forever $ do
|
||||||
s <- get
|
s <- get
|
||||||
let name = svNick $ self $ botListing s
|
let name = svNick $ self $ botListing s
|
||||||
lift $ respondingToCommands
|
lift $ respondingToCommands
|
||||||
[ cmdGeneral "ping" $ \msg -> void $ reply msg "Pong!"
|
[ botrulezPingGeneral
|
||||||
, cmdSpecific "ping" name $ \msg -> void $ reply msg "Pong!"
|
, botrulezPingSpecific name
|
||||||
, cmdSpecific "help" name $ \msg ->
|
, botrulezHelpSpecific name "I am an example bot for https://github.com/Garmelon/haboli/."
|
||||||
void $ reply msg "I am an example bot for https://github.com/Garmelon/haboli/."
|
, botrulezUptimeSpecific name $ botStartTime s
|
||||||
, cmdSpecific "kill" name $ \msg -> do
|
, botrulezKillSpecific name
|
||||||
void $ reply msg "/me dies"
|
, cmdGeneral "hello" $ \msg ->
|
||||||
throw $ "I was killed by " <> svNick (msgSender msg)
|
void $ reply msg $ "Hi there, " <> nickMention (svNick $ msgSender msg) <> "!"
|
||||||
|
, cmdSpecific "hug" name $ \msg ->
|
||||||
|
void $ reply msg "/me hugs back"
|
||||||
] $ respondingToPing nextEvent
|
] $ respondingToPing nextEvent
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,10 @@
|
||||||
{-# LANGUAGE OverloadedStrings #-}
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
|
|
||||||
module Haboli.Euphoria.Util
|
module Haboli.Euphoria.Util
|
||||||
(
|
( formatUTCTime
|
||||||
|
, formatNominalDiffTime
|
||||||
-- * Events
|
-- * Events
|
||||||
respondingToPing
|
, respondingToPing
|
||||||
, respondingToBounce
|
, respondingToBounce
|
||||||
, respondingToBounce'
|
, respondingToBounce'
|
||||||
, untilConnected
|
, untilConnected
|
||||||
|
|
@ -20,10 +21,27 @@ import Data.Char
|
||||||
import Data.Function
|
import Data.Function
|
||||||
import qualified Data.Set as Set
|
import qualified Data.Set as Set
|
||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
|
import Data.Time
|
||||||
|
|
||||||
import Haboli.Euphoria.Api
|
import Haboli.Euphoria.Api
|
||||||
import Haboli.Euphoria.Client
|
import Haboli.Euphoria.Client
|
||||||
|
|
||||||
|
formatUTCTime :: UTCTime -> T.Text
|
||||||
|
formatUTCTime t = T.pack $ formatTime defaultTimeLocale "%F %T" t
|
||||||
|
|
||||||
|
formatNominalDiffTime :: NominalDiffTime -> T.Text
|
||||||
|
formatNominalDiffTime t = T.intercalate " " $ map T.pack $ concat
|
||||||
|
[ [show days ++ "d" | days /= 0]
|
||||||
|
, [show hours ++ "h" | hours /= 0]
|
||||||
|
, [show minutes ++ "m" | minutes /= 0]
|
||||||
|
, [show seconds ++ "s"]
|
||||||
|
]
|
||||||
|
where
|
||||||
|
totalSeconds = round $ nominalDiffTimeToSeconds t :: Integer
|
||||||
|
(days, secondsAfterDays) = totalSeconds `quotRem` (60 * 60 * 24)
|
||||||
|
(hours, secondsAfterHours) = secondsAfterDays `quotRem` (60 * 60)
|
||||||
|
(minutes, seconds) = secondsAfterHours `quotRem` 60
|
||||||
|
|
||||||
{- Events -}
|
{- Events -}
|
||||||
|
|
||||||
-- | Respond to 'EventPing's according to the documentation (see
|
-- | Respond to 'EventPing's according to the documentation (see
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue