1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
|
{-# LANGUAGE TemplateHaskell, MultiParamTypeClasses, PatternGuards, ScopedTypeVariables, TypeSynonymInstances, FlexibleInstances #-}
-- | A todo list
--
-- (c) 2005 Samuel Bronson
module Plugin.Todo (theModule) where
import Plugin
import Message (Message, nick, packNick, unpackNick, showNick)
import qualified Data.ByteString.Char8 as P
$(plugin "Todo")
-- A list of key/elem pairs with an ordering determined by its position in the list
type TodoState = [(P.ByteString, P.ByteString)]
instance Module TodoModule TodoState where
moduleCmds _ = ["todo", "todo-add"]
modulePrivs _ = ["todo-delete"]
moduleHelp _ s = case s of
"todo" -> "todo. List todo entries"
"todo-add" -> "todo-add <idea>. Add a todo entry"
"todo-delete" -> "todo-delete <n>. Delete a todo entry (for admins)"
_ -> "Keep a todo list. Provides @todo, @todo-add, @todo-delete"
moduleDefState _ = return ([] :: TodoState)
moduleSerialize _ = Just assocListPackedSerial
process _ msg _ cmd rest = do
todoList <- readMS
case cmd of
"todo" -> getTodo msg todoList rest
"todo-add" -> addTodo sender rest
"todo-delete" -> delTodo rest
where sender = Message.packNick $ Message.nick msg
-- | Print todo list
getTodo :: Message.Message m => m -> TodoState -> String -> ModuleLB TodoState
getTodo msg todoList [] = return [formatTodo msg todoList]
getTodo _ _ _ = error "@todo has no args, try @todo-add or @list todo"
-- | Pretty print todo list
formatTodo :: Message.Message m => m -> [(P.ByteString, P.ByteString)] -> String
formatTodo _ [] = "Nothing to do!"
formatTodo msg todoList =
unlines $ map (\(n::Int, (idea, nick_)) -> concat $
[ show n,". ",showNick msg $ unpackNick nick_,": ",P.unpack idea ]) $
zip [0..] todoList
-- | Add new entry to list
addTodo :: P.ByteString -> String -> ModuleLB TodoState
addTodo sender rest = do
modifyMS (++[(P.pack rest, sender)])
return ["Entry added to the todo list"]
-- | Delete an entry from the list
delTodo :: String -> ModuleLB TodoState
delTodo rest
| Just n <- readM rest = withMS $ \ls write -> case () of
_ | null ls -> return ["Todo list is empty"]
| n > length ls - 1 || n < 0
-> return [show n ++ " is out of range"]
| otherwise -> do
write (map snd . filter ((/= n) . fst) . zip [0..] $ ls)
let (a,_) = ls !! n
return ["Removed: " ++ P.unpack a]
| otherwise = return ["Syntax error. @todo <n>, where n :: Int"]
|