module FunBot.ExtEvents
( Repository (..)
, ProjectObject (..)
, Commit (..)
, Push (..)
, Tag (..)
, Issue (..)
, Note (..)
, MergeRequest (..)
, NewsItem (..)
, Paste (..)
, ExtEvent (..)
)
where
import Control.Applicative
import Data.Aeson
import Data.Aeson.Types (Parser, typeMismatch)
import Data.Text (Text)
data Repository = Repository
{
repoName :: Text
, repoSpace :: Text
, repoHost :: Text
}
deriving Show
instance FromJSON Repository where
parseJSON (Object o) =
Repository <$>
o .: "name" <*>
o .: "space" <*>
o .: "host"
parseJSON v = typeMismatch "Repository" v
instance ToJSON Repository where
toJSON repo = object
[ "name" .= repoName repo
, "space" .= repoSpace repo
, "host" .= repoHost repo
]
data ProjectObject a = ProjectObject
{
poRepo :: Repository
, poObj :: a
}
deriving Show
instance FromJSON a => FromJSON (ProjectObject a) where
parseJSON (Object o) =
ProjectObject <$>
o .: "repo" <*>
o .: "obj"
parseJSON v = typeMismatch "ProjectObject" v
instance ToJSON a => ToJSON (ProjectObject a) where
toJSON po = object
[ "repo" .= poRepo po
, "obj" .= poObj po
]
data Commit = Commit
{
commitAuthor :: Text
, commitTitle :: Text
, commitUrl :: Text
, commitAdded :: [Text]
, commitModified :: [Text]
, commitRemoved :: [Text]
}
deriving Show
instance FromJSON Commit where
parseJSON (Object o) =
Commit <$>
o .: "author" <*>
o .: "title" <*>
o .: "url" <*>
o .: "added" <*>
o .: "modified" <*>
o .: "removed"
parseJSON v = typeMismatch "Commit" v
instance ToJSON Commit where
toJSON (Commit author title url added modified removed) = object
[ "author" .= author
, "title" .= title
, "url" .= url
, "added" .= added
, "modified" .= modified
, "removed" .= removed
]
data Push = Push
{ pushBranch :: Text
, pushCommits :: [Commit]
}
deriving Show
instance FromJSON Push where
parseJSON (Object o) =
Push <$>
o .: "branch" <*>
o .: "commits"
parseJSON v = typeMismatch "Push" v
instance ToJSON Push where
toJSON (Push branch commits) = object
[ "branch" .= branch
, "commits" .= commits
]
data Tag = Tag
{
tagAuthor :: Text
, tagRef :: Text
}
deriving Show
instance FromJSON Tag where
parseJSON (Object o) =
Tag <$>
o .: "author" <*>
o .: "ref"
parseJSON v = typeMismatch "Tag" v
instance ToJSON Tag where
toJSON tag = object
[ "author" .= tagAuthor tag
, "ref" .= tagRef tag
]
data Issue = Issue
{
issueAuthor :: Text
, issueId :: Int
, issueTitle :: Text
, issueUrl :: Text
, issueAction :: Text
}
deriving Show
instance FromJSON Issue where
parseJSON (Object o) =
Issue <$>
o .: "author" <*>
o .: "id" <*>
o .: "title" <*>
o .: "url" <*>
o .: "action"
parseJSON v = typeMismatch "Issue" v
instance ToJSON Issue where
toJSON issue = object
[ "author" .= issueAuthor issue
, "id" .= issueId issue
, "title" .= issueTitle issue
, "url" .= issueUrl issue
, "action" .= issueAction issue
]
data Note = Note
{
noteAuthor :: Text
, noteContent :: Text
, noteTarget :: Text
, noteUrl :: Text
}
deriving Show
instance FromJSON Note where
parseJSON (Object o) =
Note <$>
o .: "author" <*>
o .: "content" <*>
o .: "target" <*>
o .: "url"
parseJSON v = typeMismatch "Note" v
instance ToJSON Note where
toJSON (Note author content target url) = object
[ "author" .= author
, "content" .= content
, "target" .= target
, "url" .= url
]
data MergeRequest = MergeRequest
{
mrAuthor :: Text
, mrId :: Int
, mrTitle :: Text
, mrUrl :: Text
, mrAction :: Text
}
deriving Show
instance FromJSON MergeRequest where
parseJSON (Object o) =
MergeRequest <$>
o .: "author" <*>
o .: "id" <*>
o .: "title" <*>
o .: "url" <*>
o .: "action"
parseJSON v = typeMismatch "MergeRequest" v
instance ToJSON MergeRequest where
toJSON mr = object
[ "author" .= mrAuthor mr
, "id" .= mrId mr
, "title" .= mrTitle mr
, "url" .= mrUrl mr
, "action" .= mrAction mr
]
data NewsItem = NewsItem
{
itemFeedLabel :: Text
, itemFeedTitle :: Maybe Text
, itemTitle :: Text
, itemAuthor :: Maybe Text
, itemUrl :: Maybe Text
}
deriving Show
instance FromJSON NewsItem where
parseJSON (Object o) =
NewsItem <$>
o .: "feed-label" <*>
o .: "feed-title" <*>
o .: "title" <*>
o .: "author" <*>
o .: "url"
parseJSON v = typeMismatch "NewsItem" v
instance ToJSON NewsItem where
toJSON (NewsItem fLabel fTitle title author url) = object
[ "feed-label" .= fLabel
, "feed-title" .= fTitle
, "title" .= title
, "author" .= author
, "url" .= url
]
data Paste = Paste
{
pasteAuthor :: Text
, pasteVerb :: Text
, pasteTitle :: Text
, pasteUrl :: Text
, pasteChannel :: Text
}
deriving Show
instance FromJSON Paste where
parseJSON (Object o) =
Paste <$>
o .: "author" <*>
o .: "verb" <*>
o .: "title" <*>
o .: "url" <*>
o .: "channel"
parseJSON v = typeMismatch "Paste" v
instance ToJSON Paste where
toJSON (Paste author verb title url chan) = object
[ "author" .= author
, "verb" .= verb
, "title" .= title
, "url" .= url
, "channel" .= chan
]
data ExtEvent
= GitPushEvent (ProjectObject Push)
| GitTagEvent (ProjectObject Tag)
| IssueEvent (ProjectObject Issue)
| MergeRequestEvent (ProjectObject MergeRequest)
| NoteEvent (ProjectObject Note)
| NewsEvent NewsItem
| PasteEvent Paste
| WelcomeEvent Text Text
deriving Show
text :: Parser Text -> Text -> Parser Text
text parser expected = do
got <- parser
if got == expected
then return got
else empty
instance FromJSON ExtEvent where
parseJSON (Object o) =
let kind = text $ o .: "type"
event label ctor = kind label *> (ctor <$> o .: "data")
in event "push" GitPushEvent <|>
event "tag" GitTagEvent <|>
event "mr" MergeRequestEvent <|>
event "note" NoteEvent <|>
event "issue" IssueEvent <|>
event "news" NewsEvent <|>
event "paste" PasteEvent
parseJSON v = typeMismatch "ExtEvent" v
instance ToJSON ExtEvent where
toJSON (GitPushEvent commits) = object [ "type" .= ("push" :: Text)
, "data" .= commits
]
toJSON (GitTagEvent tag) = object [ "type" .= ("tag" :: Text)
, "data" .= tag
]
toJSON (IssueEvent issue) = object [ "type" .= ("issue" :: Text)
, "data" .= issue
]
toJSON (MergeRequestEvent mr) = object [ "type" .= ("mr" :: Text)
, "data" .= mr
]
toJSON (NoteEvent note) = object [ "type" .= ("note" :: Text)
, "data" .= note
]
toJSON (NewsEvent item) = object [ "type" .= ("news" :: Text)
, "data" .= item
]
toJSON (PasteEvent paste) = object [ "type" .= ("paste" :: Text)
, "data" .= paste
]
toJSON (WelcomeEvent _ _) = object []