darcsden-1.1: src/DarcsDen/State/Issue.hs
module DarcsDen.State.Issue where
import Control.Monad.Trans
import Data.Time (UTCTime, formatTime)
import Database.CouchDB
import System.Locale (defaultTimeLocale)
import Text.JSON
import DarcsDen.Settings
import DarcsDen.State.Util
import DarcsDen.State.Repository
data Issue =
Issue
{ iID :: Maybe Doc
, iRev :: Maybe Rev
, iNumber :: Int
, iSummary :: String
, iOwner :: String
, iDescription :: String
, iTags :: [String]
, iCreated :: UTCTime
, iUpdated :: UTCTime
, iIsClosed :: Bool
, iRepository :: Doc
}
deriving Show
instance Eq Issue where
a == b = iID a == iID b
instance JSON Issue where
readJSON o = do
id' <- getID o
rev' <- getRev o
number <- getAttrOr o "number" 0
summary <- getAttr o "summary"
owner <- getAttr o "owner"
description <- getAttr o "description"
tags <- getAttr o "tags"
created <- getTime o "created"
updated <- getTime o "updated"
closed <- getAttr o "is_closed"
repository <- getAttr o "repository"
return Issue
{ iID = Just id'
, iRev = Just rev'
, iNumber = number
, iSummary = summary
, iOwner = owner
, iDescription = description
, iTags = tags
, iCreated = created
, iUpdated = updated
, iIsClosed = closed
, iRepository = repository
}
showJSON i = JSObject . toJSObject $
[ ("number", showJSON (iNumber i))
, ("summary", showJSON (iSummary i))
, ("owner", showJSON (iOwner i))
, ("description", showJSON (iDescription i))
, ("tags", showJSON (iTags i))
, ("created", showJSON (formatTime defaultTimeLocale "%F %T" (iCreated i)))
, ("updated", showJSON (formatTime defaultTimeLocale "%F %T" (iUpdated i)))
, ("is_closed", showJSON (iIsClosed i))
, ("repository", showJSON (iRepository i))
] ++ id' ++ rev'
where
id' =
case iID i of
Just id'' -> [("_id", showJSON (show id''))]
Nothing -> []
rev' =
case iRev i of
Just rev'' -> [("_rev", showJSON (show rev''))]
Nothing -> []
issueURL :: Repository -> Issue -> String
issueURL r i =
baseUrl ++ rOwner r ++ "/" ++ rName r ++ "/issue/" ++ show (iNumber i)
getIssueByID :: MonadIO m => Doc -> m (Maybe Issue)
getIssueByID key = do
res <- liftIO $ runDB (getDoc (db "issues") key)
case res of
Just (_, _, i) -> return (Just i)
Nothing -> return Nothing
getIssue :: MonadIO m => Doc -> Int -> m (Maybe Issue)
getIssue repo num =
liftIO (runDB query)
where
query = getDocByView
(db "issues")
(doc "issues")
(doc "by_repository_and_number")
[showJSON repo, showJSON num]
getIssuesOpen :: MonadIO m => Repository -> m [Issue]
getIssuesOpen (Repository { rID = Just repo }) =
liftIO $ fmap (map snd) (runDB query)
where
query = queryView
(db "issues")
(doc "issues")
(doc "by_repository_open")
[("key", showJSON repo)]
getIssuesOpen _ = error "getIssuesOpen: unsaved repository"
getIssuesClosed :: MonadIO m => Repository -> m [Issue]
getIssuesClosed (Repository { rID = Just repo }) =
liftIO $ fmap (map snd) (runDB query)
where
query = queryView
(db "issues")
(doc "issues")
(doc "by_repository_closed")
[("key", showJSON repo)]
getIssuesClosed _ = error "getIssuesClosed: unsaved repository"
getIssuesAll :: MonadIO m => Repository -> m [Issue]
getIssuesAll (Repository { rID = Just repo }) =
liftIO $ fmap (map snd) (runDB query)
where
query = queryView
(db "issues")
(doc "issues")
(doc "by_repository")
[("key", showJSON repo)]
getIssuesAll _ = error "getIssuesAll: unsaved repository"
getIssuesByTag :: MonadIO m => Repository -> String -> m [Issue]
getIssuesByTag (Repository { rID = Just repo }) t =
liftIO $ fmap (map snd) (runDB query)
where
query = queryView
(db "issues")
(doc "issues")
(doc "by_repository_and_tag")
[("key", showJSON [showJSON repo, showJSON t])]
getIssuesByTag _ _ = error "getIssuesByTag: unsaved repository"
addIssue :: MonadIO m => Issue -> m Issue
addIssue i = do
(id', rev') <- liftIO $ runDB (newDoc (db "issues") i)
return i { iID = Just id', iRev = Just rev' }
updateIssue :: MonadIO m => Issue -> m (Maybe Issue)
updateIssue i =
case (iID i, iRev i) of
(Just id', Just rev') -> do
update <-
liftIO . runDB $ updateDoc (db "issues") (id', rev') i
{ iID = Nothing }
case update of
Just (id'', rev'') -> return $ Just i
{ iID = Just id''
, iRev = Just rev''
}
_ -> return Nothing
_ -> return Nothing