funbot-0.2: src/FunBot/Commands.hs
{- This file is part of funbot.
-
- Written in 2015 by fr33domlover <fr33domlover@rel4tion.org>.
-
- ♡ Copying is an act of love. Please copy, reuse and share.
-
- The author(s) have dedicated all copyright and related and neighboring
- rights to this software to the public domain worldwide. This software is
- distributed without any warranty.
-
- You should have received a copy of the CC0 Public Domain Dedication along
- with this software. If not, see
- <http://creativecommons.org/publicdomain/zero/1.0/>.
-}
module FunBot.Commands
( commandSet
)
where
import Control.Monad (unless)
import Data.List (find, intercalate)
import Data.Settings.Types (showOption)
import FunBot.Memos (submitMemo)
import FunBot.Settings
import FunBot.Types (BotSession)
import Network.IRC.Fun.Bot.Behavior
import Network.IRC.Fun.Bot.Chat
import Network.IRC.Fun.Bot.Types
import Text.Printf (printf)
-- | The main command set, the only one currently
commandSet = CommandSet
{ prefix = '!'
, commands =
[ makeCmdHelp commandSet
, cmdInfo
, cmdEcho
, cmdPTell
, cmdCTell
, cmdGet
, cmdSet
, cmdReset
, cmdEnable
, cmdDisable
]
}
-------------------------------------------------------------------------------
-- Echo command
-- Send the input back to the IRC channel
-------------------------------------------------------------------------------
respondEcho _mchan _nick [] send = send " "
respondEcho _mchan _nick [param] send = send param
respondEcho _mchan _nick params send = send $ unwords params
cmdEcho = Command
{ names = ["echo"]
, respond = respondEcho
, help = "‘echo <text>’ - display the given text. Probably not a \
\useful command. Exists as an example and for testing."
}
-------------------------------------------------------------------------------
-- Help command
-- Show command help strings
-------------------------------------------------------------------------------
-- Return a response function given a CommandSet
respondHelp cset _mchan _nick [cname] send =
case find ((cname' `elem`) . names) $ commands cset of
Just cmd -> send $ help cmd
++ "\nCommand names: "
++ listNames Nothing Nothing True (names cmd)
Nothing -> do
succ <- respondSettingsHelp cname send
unless succ $ send $ printf
"No such command, or invalid settings path. \
\Maybe try just ‘%vhelp’ without a parameter."
(prefix cset)
where
cname' = case cname of
[] -> cname
(c:cs) -> if c == prefix cset then cs else cname
respondHelp cset _mchan _nick _params send =
send $ help (makeCmdHelp cset)
++ "\nAvailable commands: "
++ listPrimaryNames (Just $ prefix cset) Nothing False (commands cset)
makeCmdHelp cset = Command
{ names = ["help", "Help", "h", "?"]
, respond = respondHelp cset
, help = "‘help [<command> | <setting>]’ - display help for the given \
\command or settings option/section.\n\
\FunBot intends to provide interactive help, but some topics \
\may be missing. If that's the case, check out the user \
\manual (call ‘!info links’ for the URL) or ask in #freepost."
}
-------------------------------------------------------------------------------
-- Info command
-- Ask the bot to display some information
-------------------------------------------------------------------------------
respondInfo _mchan _nick ["intro"] send = send $
"I’m fpbot. An instance of funbot, written in Haskell. I run in #freepost \
\(and some extra channels). Developed in the Freepost community, I exist \
\for fun, collaboration and learning. But I also aim to provide useful \
\tools, in particular to Freepost and related projects and communities.\n\
\You can start by trying ‘!help’."
respondInfo _mchan _nick ["features"] send = send $
"This is a high-level list of features and subsystems I provide. It will \
\hopefully be kept up-to-date by updating it every time new features are \
\added.\n\
\• Help and information system (!help, !info)\n\
\• A settings system (!get, !set, etc.)\n\
\• Announcing commits in Git repositories\n\
\• Announcing RSS/Atom feed items\n\
\• Leaving memos (requires enabling nick tracking for the channel)\n\
\There is also an overview of the bot API features, useful to \
\contributors/developers, in the guide at \
\<http://rel4tion.org/projects/funbot/guide>."
respondInfo _mchan _nick ["contrib"] send = send $
"Thinking about contributing to my development? Opening a ticket, fixing \
\a bug, implementing a feature? Check out the project page at \
\<http://rel4tion.org/projects/funbot>, which links to the contribution \
\guide, to the tickets page and more."
respondInfo _mchan _nick ["copying"] send = send $
"♡ Copying is an act of love. Please copy, reuse and share me! \
\Grab a copy of me from <https://notabug.org/fr33domlover/funbot>."
respondInfo _mchan _nick ["links"] send = send $
"Website: http://rel4tion.org/projects/funbot\n\
\Code: https://notabug.org/fr33domlover/funbot\n\
\Tickets: http://rel4tion.org/projects/funbot/tickets\n\
\Roadmap: http://rel4tion.org/projects/funbot/ideas\n\
\Dev guide: http://rel4tion.org/projects/funbot/guide\n\
\User manual: http://rel4tion.org/projects/funbot/manual"
respondInfo mchan nick [arg] _send =
failBack mchan nick $ InvalidArg (Just 1) (Just arg)
respondInfo mchan nick args _send =
failBack mchan nick $ WrongNumArgsN (Just $ length args) (Just 1)
cmdInfo = Command
{ names = ["info", "i"]
, respond = respondInfo
, help = "‘info ( intro | features | contrib | copying | links)’ - \
\display information."
}
-------------------------------------------------------------------------------
-- Tell command
-- Tell something to some other user
-------------------------------------------------------------------------------
-- Given whether to always send privately, return a command response
respondTell priv mchan sender (recip:msghead:msgtail) _send =
submitMemo sender mchan recip priv (unwords $ msghead : msgtail)
respondTell _priv mchan nick args _send =
failBack mchan nick $ WrongNumArgsN (Just $ length args) Nothing
cmdPTell = Command
{ names = ["tell", "ptell"]
, respond = respondTell True
, help = "‘tell <nick> <text>’ - leave a memo for a user to see later. \
\Memos can be sent to the recipient privately, or publicly \
\in the channel in which they were submitted. With this \
\command, the memo will be sent privately. If that isn't your \
\intention, see the ctell command."
}
cmdCTell = Command
{ names = ["ctell"]
, respond = respondTell False
, help = "‘tell <nick> <text>’ - leave a memo for a user to see later. \
\Memos can be sent to the recipient privately, or publicly \
\in the channel in which they were submitted. With this \
\command, the memo will be sent in the same way it was \
\submitted: If you submit it in a channel, it will be sent to \
\the recipient in the same channel. If you submit using a \
\private message to me, I will also send it privately to the \
\recipient.\n\
\If that isn't your intention, see the tell command."
}
-------------------------------------------------------------------------------
-- Get, set, enable and disable commands
-- Manage bot settings
-------------------------------------------------------------------------------
respondGet _mchan _nick [] send = respondGet' "" send
respondGet _mchan _nick [path] send = respondGet' path send
respondGet mchan nick args _send =
failBack mchan nick $ WrongNumArgsN (Just $ length args) (Just 1)
respondSet _mchan _nick [name, val] send = respondSet' name val send
respondSet mchan nick args _send =
failBack mchan nick $ WrongNumArgsN (Just $ length args) (Just 2)
respondReset _mchan _nick [name] send = respondReset' name send
respondReset mchan nick args _send =
failBack mchan nick $ WrongNumArgsN (Just $ length args) (Just 1)
-- Given a boolean, create an enable/disable response accordingly
respondBool val _mchan _nick [name] send =
respondSet' name (showOption val) send
respondBool _val mchan nick args _send =
failBack mchan nick $ WrongNumArgsN (Just $ length args) (Just 1)
respondEnable = respondBool True
respondDisable = respondBool False
cmdGet = Command
{ names = ["get"]
, respond = respondGet
, help = "‘get <option>’ - get the value of a settings option at the \
\given path"
}
cmdSet = Command
{ names = ["set"]
, respond = respondSet
, help = "‘set <option> <value>’ - set a settings option at the given \
\path to the given value"
}
cmdReset = Command
{ names = ["reset"]
, respond = respondReset
, help = "‘reset <option>’ - set a settings option at the given path to \
\its default value"
}
cmdEnable = Command
{ names = ["enable"]
, respond = respondEnable
, help = "‘enable <option>’ - set a settings option at the given path \
\to True"
}
cmdDisable = Command
{ names = ["disable"]
, respond = respondDisable
, help = "‘disable <option>’ - set a settings option at the given path \
\to False"
}