darcsden-1.1: src/DarcsDen/State/Comment.hs
module DarcsDen.State.Comment where
import Control.Monad.Trans
import Data.Time (UTCTime, formatTime)
import Database.CouchDB
import System.Locale (defaultTimeLocale)
import Text.JSON
import DarcsDen.State.Util
import DarcsDen.State.Issue
data IssueChange
= AddTag String
| RemoveTag String
| Summary String String
| Description String String
| Closed Bool
deriving (Eq, Show)
instance JSON IssueChange where
readJSON js = do
ctype <- getAttr js "type"
case ctype of
"add-tag" -> do
s <- getAttr js "name"
return (AddTag s)
"remove-tag" -> do
s <- getAttr js "name"
return (RemoveTag s)
"summary" -> do
f <- getAttrOr js "from" ""
t <- getOneOf js "to" "value"
return (Summary f t)
"description" -> do
f <- getAttrOr js "from" ""
t <- getOneOf js "to" "value"
return (Description f t)
"closed" -> do
b <- getAttr js "state"
return (Closed b)
_ -> fail ("unknown type: " ++ ctype)
showJSON (AddTag t) = JSObject . toJSObject $
[ ("type", showJSON "add-tag")
, ("name", showJSON t)
]
showJSON (RemoveTag t) = JSObject . toJSObject $
[ ("type", showJSON "remove-tag")
, ("name", showJSON t)
]
showJSON (Summary f t) = JSObject . toJSObject $
[ ("type", showJSON "summary")
, ("from", showJSON f)
, ("to", showJSON t)
]
showJSON (Description f t) = JSObject . toJSObject $
[ ("type", showJSON "description")
, ("from", showJSON f)
, ("to", showJSON t)
]
showJSON (Closed c) = JSObject . toJSObject $
[ ("type", showJSON "closed")
, ("state", showJSON c)
]
data Comment =
Comment
{ cID :: Maybe Doc
, cRev :: Maybe Rev
, cBody :: String
, cChanges :: [IssueChange]
, cAuthor :: String
, cCreated :: UTCTime
, cUpdated :: UTCTime
, cIssue :: Doc
}
deriving (Eq, Show)
instance JSON Comment where
readJSON o = do
id' <- getID o
rev' <- getRev o
body <- getAttr o "body"
changes <- getAttr o "changes"
author <- getAttr o "author"
created <- getTime o "created"
updated <- getTime o "updated"
issue <- getAttr o "issue"
return Comment
{ cID = Just id'
, cRev = Just rev'
, cBody = body
, cChanges = changes
, cAuthor = author
, cCreated = created
, cUpdated = updated
, cIssue = issue
}
showJSON c = JSObject . toJSObject $
[ ("body", showJSON (cBody c))
, ("changes", showJSON (cChanges c))
, ("author", showJSON (cAuthor c))
, ("created", showJSON (formatTime defaultTimeLocale "%F %T" (cCreated c)))
, ("updated", showJSON (formatTime defaultTimeLocale "%F %T" (cUpdated c)))
, ("issue", showJSON (cIssue c))
] ++ id' ++ rev'
where
id' =
case cID c of
Just id'' -> [("_id", showJSON (show id''))]
Nothing -> []
rev' =
case cRev c of
Just rev'' -> [("_rev", showJSON (show rev''))]
Nothing -> []
getComment :: MonadIO m => Doc -> m (Maybe Comment)
getComment key = do
res <- liftIO $ runDB (getDoc (db "comments") key)
case res of
Just (_, _, i) -> return (Just i)
Nothing -> return Nothing
getComments :: MonadIO m => Issue -> m [Comment]
getComments (Issue { iID = Just issue }) =
liftIO $ fmap (map snd) (runDB query)
where
query = queryView
(db "comments")
(doc "comments")
(doc "by_issue")
[("key", showJSON issue)]
getComments _ = error "getComments: unsaved issue"
addComment :: MonadIO m => Comment -> m Comment
addComment c = do
(id', rev') <- liftIO $ runDB (newDoc (db "comments") c)
return c { cID = Just id', cRev = Just rev' }
updateComment :: MonadIO m => Comment -> m (Maybe Comment)
updateComment c =
case (cID c, cRev c) of
(Just id', Just rev') -> do
update <-
liftIO . runDB $ updateDoc (db "comments") (id', rev') c
{ cID = Nothing }
case update of
Just (id'', rev'') -> return $ Just c
{ cID = Just id''
, cRev = Just rev''
}
_ -> return Nothing
_ -> return Nothing