module FunBot.ExtEvents
( Branch (..)
, Commit (..)
, Push (..)
, Tag (..)
, MergeRequest (..)
, NewsItem (..)
, Paste (..)
, ExtEvent (..)
)
where
import Control.Applicative
import Control.Monad (mzero)
import Data.Aeson
import Data.Aeson.Types (Parser)
import qualified Data.Text as T
data Branch = Branch
{ branchName :: String
, branchRepo :: String
, branchRepoOwner :: String
}
deriving Show
data Commit = Commit
{ commitAuthor :: String
, commitTitle :: String
, commitUrl :: String
}
deriving Show
data Push = Push
{ pushBranch :: Branch
, pushCommits :: [Commit]
}
deriving Show
data Tag = Tag
{ tagAuthor :: String
, tagRef :: String
, tagRepo :: String
, tagRepoOwner :: String
}
deriving Show
data MergeRequest = MergeRequest
{ mrAuthor :: String
, mrId :: Int
, mrRepo :: String
, mrRepoOwner :: String
, mrTitle :: String
, mrUrl :: String
, mrAction :: String
}
deriving Show
data NewsItem = NewsItem
{ itemFeedLabel :: String
, itemFeedTitle :: Maybe String
, itemTitle :: String
, itemAuthor :: Maybe String
, itemUrl :: Maybe String
}
deriving Show
data Paste = Paste
{ pasteAuthor :: String
, pasteVerb :: String
, pasteTitle :: String
, pasteUrl :: String
, pasteChannel :: String
}
deriving Show
data ExtEvent
= GitPushEvent Push
| GitTagEvent Tag
| MergeRequestEvent MergeRequest
| NewsEvent NewsItem
| PasteEvent Paste
deriving Show
instance FromJSON Branch where
parseJSON (Object o) =
Branch <$>
o .: "name" <*>
o .: "repo" <*>
o .: "user"
parseJSON _ = mzero
instance ToJSON Branch where
toJSON (Branch name repo owner) = object
[ "name" .= name
, "repo" .= repo
, "user" .= owner
]
instance FromJSON Commit where
parseJSON (Object o) =
Commit <$>
o .: "author" <*>
o .: "title" <*>
o .: "url"
parseJSON _ = mzero
instance ToJSON Commit where
toJSON (Commit author title url) = object
[ "author" .= author
, "title" .= title
, "url" .= url
]
instance FromJSON Push where
parseJSON (Object o) =
Push <$>
o .: "branch" <*>
o .: "commits"
parseJSON _ = mzero
instance ToJSON Push where
toJSON (Push branch commits) = object
[ "branch" .= branch
, "commits" .= commits
]
instance FromJSON Tag where
parseJSON (Object o) =
Tag <$>
o .: "author" <*>
o .: "ref" <*>
o .: "repo" <*>
o .: "user"
parseJSON _ = mzero
instance ToJSON Tag where
toJSON tag = object
[ "author" .= tagAuthor tag
, "ref" .= tagRef tag
, "repo" .= tagRepo tag
, "user" .= tagRepoOwner tag
]
instance FromJSON MergeRequest where
parseJSON (Object o) =
MergeRequest <$>
o .: "author" <*>
o .: "id" <*>
o .: "repo" <*>
o .: "user" <*>
o .: "title" <*>
o .: "url" <*>
o .: "action"
parseJSON _ = mzero
instance ToJSON MergeRequest where
toJSON mr = object
[ "author" .= mrAuthor mr
, "id" .= mrId mr
, "repo" .= mrRepo mr
, "user" .= mrRepoOwner mr
, "title" .= mrTitle mr
, "url" .= mrUrl mr
, "action" .= mrAction mr
]
instance FromJSON NewsItem where
parseJSON (Object o) =
NewsItem <$>
o .: "feed-label" <*>
o .: "feed-title" <*>
o .: "title" <*>
o .: "author" <*>
o .: "url"
parseJSON _ = mzero
instance ToJSON NewsItem where
toJSON (NewsItem fLabel fTitle title author url) = object
[ "feed-label" .= fLabel
, "feed-title" .= fTitle
, "title" .= title
, "author" .= author
, "url" .= url
]
instance FromJSON Paste where
parseJSON (Object o) =
Paste <$>
o .: "author" <*>
o .: "verb" <*>
o .: "title" <*>
o .: "url" <*>
o .: "channel"
parseJSON _ = mzero
instance ToJSON Paste where
toJSON (Paste author verb title url chan) = object
[ "author" .= author
, "verb" .= verb
, "title" .= title
, "url" .= url
, "channel" .= chan
]
text :: Parser T.Text -> T.Text -> Parser T.Text
text parser expected = do
got <- parser
if got == expected
then return got
else mzero
instance FromJSON ExtEvent where
parseJSON (Object o) =
let kind = text $ o .: "type"
in kind "push" *> (GitPushEvent <$> o .: "data") <|>
kind "tag" *> (GitTagEvent <$> o .: "data") <|>
kind "mr" *> (MergeRequestEvent <$> o .: "data") <|>
kind "news" *> (NewsEvent <$> o .: "data") <|>
kind "paste" *> (PasteEvent <$> o .: "data")
parseJSON _ = mzero
instance ToJSON ExtEvent where
toJSON (GitPushEvent commits) = object [ "type" .= ("push" :: T.Text)
, "data" .= commits
]
toJSON (GitTagEvent tag) = object [ "type" .= ("tag" :: T.Text)
, "data" .= tag
]
toJSON (MergeRequestEvent mr) = object [ "type" .= ("mr" :: T.Text)
, "data" .= mr
]
toJSON (NewsEvent item) = object [ "type" .= ("news" :: T.Text)
, "data" .= item
]
toJSON (PasteEvent paste) = object [ "type" .= ("paste" :: T.Text)
, "data" .= paste
]