File: Todo.hs

package info (click to toggle)
lambdabot 4.2.3.2-4
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 5,584 kB
  • sloc: haskell: 10,102; ansic: 76; makefile: 7
file content (69 lines) | stat: -rw-r--r-- 2,600 bytes parent folder | download
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"]