Skip to content

Commit

Permalink
Format with brittany
Browse files Browse the repository at this point in the history
Everything except the imports.
  • Loading branch information
deiwin committed Nov 24, 2018
1 parent 803cd99 commit 769eccd
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 58 deletions.
42 changes: 20 additions & 22 deletions src/Lib.hs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ module Lib
( ensure
, listCaretakers
, listUsers
) where
)
where

import Prelude hiding (unlines, filter)
import Slack.Util (Token)
Expand Down Expand Up @@ -38,32 +39,29 @@ instance Interpret InputRecord

ensure :: Text -> Token -> ExceptT Text IO Text
ensure inputText apiToken = do
records <- lift $ input auto inputText
teamResults <- traverse (wrapTeamResult $ ensureTeamState apiToken) records
records <- lift $ input auto inputText
teamResults <- traverse (wrapTeamResult $ ensureTeamState apiToken) records
caretakerIDs <- traverse (lift . getCaretaker) (members <$> records)
groupResult <- wrapGroupResult <$>
ensureGroupState apiToken groupHandle groupName groupChannels caretakerIDs
groupResult <- wrapGroupResult <$> ensureGroupState apiToken groupHandle groupName groupChannels caretakerIDs
return $ unlines (teamResults ++ [groupResult])
where
wrapTeamResult f record = const ("Team " <> team record <> ": success!") <$> f record
wrapGroupResult = const "Caretakers group: success!"
groupHandle = "caretakers"
groupName = "Current caretakers of every team"
groupChannels = []
groupHandle = "caretakers"
groupName = "Current caretakers of every team"
groupChannels = []

listCaretakers :: Text -> Token -> ExceptT Text IO Text
listCaretakers inputText apiToken = do
records <- lift $ input auto inputText
caretakerIDs <- traverse (lift . getCaretaker) (members <$> records)
records <- lift $ input auto inputText
caretakerIDs <- traverse (lift . getCaretaker) (members <$> records)
caretakerDisplayNames <- traverse (fmap (^. displayName) . getUser apiToken) caretakerIDs
return $ unlines $ formatLine <$> zip3 (team <$> records) caretakerDisplayNames caretakerIDs
where
formatLine (teamName, userName, userID) = pack $ printf "Team %s: %s (%s)" teamName userName userID
where formatLine (teamName, userName, userID) = pack $ printf "Team %s: %s (%s)" teamName userName userID

listUsers :: Token -> ExceptT Text IO Text
listUsers apiToken = unlines . fmap formatLine <$> listAllUsers apiToken
where
formatLine user = pack $ printf "%s: %s" (user ^. User.id) (user ^. displayName)
where formatLine user = pack $ printf "%s: %s" (user ^. User.id) (user ^. displayName)

ensureTeamState :: Token -> InputRecord -> ExceptT Text IO ()
ensureTeamState apiToken record = do
Expand All @@ -72,23 +70,23 @@ ensureTeamState apiToken record = do
ensureAllMembersPresent apiToken channelID userIDs
caretakerID <- lift $ getCaretaker userIDs
ensureChannelTopic apiToken channel (Lib.topic record) caretakerID
ensureGroupState apiToken teamGroupHandle teamGroupName [channelID] userIDs
ensureGroupState apiToken teamGroupHandle teamGroupName [channelID] userIDs
ensureGroupState apiToken caretakerGroupHandle caretakerGroupName [channelID] [caretakerID]
where
channelName = "tm-" <> team record
teamGroupHandle = team record
teamGroupName = "Team " <> teamGroupHandle
channelName = "tm-" <> team record
teamGroupHandle = team record
teamGroupName = "Team " <> teamGroupHandle
caretakerGroupHandle = teamGroupHandle <> "-caretaker"
caretakerGroupName = teamGroupName <> " caretaker"
userIDs = members record
caretakerGroupName = teamGroupName <> " caretaker"
userIDs = members record

ensureChannelTopic :: Token -> Channel -> (Text -> Text) -> Text -> ExceptT Text IO ()
ensureChannelTopic apiToken channel buildTopic caretakerID = do
caretakerDisplayName <- (^. displayName) <$> getUser apiToken caretakerID
let newTopic = buildTopic caretakerDisplayName
unless (same currentTopic newTopic) $ setChannelTopic apiToken channelID newTopic
where
channelID = channel ^. Channel.id
channelID = channel ^. Channel.id
currentTopic = channel ^. Channel.topic
same oldTopic newTopic = oldTopic == newTopic || clean oldTopic == clean newTopic
clean = filter (not . potentialAddedChar)
Expand All @@ -107,7 +105,7 @@ findOrCreateChannel apiToken name userIDs = do
ensureGroupState :: Token -> Text -> Text -> [Text] -> [Text] -> ExceptT Text IO ()
ensureGroupState apiToken groupHandle groupName defaultChannelIDs userIDs = do
existingGroup <- findGroup apiToken groupHandle
group <- maybe createNew return existingGroup
group <- maybe createNew return existingGroup
let groupID = group ^. Group.id

currentMembers <- getGroupMembers apiToken groupID
Expand Down
12 changes: 7 additions & 5 deletions src/Slack/Channel.hs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ module Slack.Channel
, Channel
, id
, topic
) where
)
where

import Prelude hiding (id)
import Slack.Util (slackGetPaginated, slackPost, Token, fromJSON)
Expand Down Expand Up @@ -46,9 +47,10 @@ instance FromJSON Channel where
findChannel :: Text -> Token -> ExceptT Text IO (Maybe Channel)
findChannel expectedName apiToken = do
respBodies <- slackGetPaginated apiToken defaults "conversations.list"
channels <- traverse fromJSON =<< concatMap (^.. values) <$>
(traverse (^? key "channels") respBodies ??
"\"users.list\" response didn't include a \"channels\" field")
channels <-
traverse fromJSON
=<< concatMap (^.. values)
<$> (traverse (^? key "channels") respBodies ?? "\"users.list\" response didn't include a \"channels\" field")
return $ find (\x -> (x ^. name) == expectedName) channels

createChannel :: Token -> Text -> [Text] -> ExceptT Text IO Channel
Expand All @@ -57,7 +59,7 @@ createChannel apiToken newName userIDs = do
, "user_ids" .= intercalate "," (unpack <$> userIDs)
]
respBody <- slackPost apiToken params "conversations.create"
val <- (respBody ^? key "channel") ?? "\"conversations.create\" response didn't include a \"channel\" key"
val <- (respBody ^? key "channel") ?? "\"conversations.create\" response didn't include a \"channel\" key"
fromJSON val

inviteMembers :: Token -> Text -> [Text] -> ExceptT Text IO ()
Expand Down
12 changes: 7 additions & 5 deletions src/Slack/Group.hs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ module Slack.Group
, id
, handle
, channelIDs
) where
)
where

import Prelude hiding (id)
import Slack.Util (slackGet, slackPost, Token, fromJSON)
Expand Down Expand Up @@ -70,9 +71,10 @@ findGroup :: Token -> Text -> ExceptT Text IO (Maybe Group)
findGroup apiToken expectedHandle = do
let opts = defaults & param "include_disabled" .~ ["true"]
respBody <- slackGet apiToken opts "usergroups.list"
groups <- traverse fromJSON =<< (^.. values) <$>
((respBody ^? key "usergroups") ??
"\"users.list\" response didn't include a \"channels\" field")
groups <-
traverse fromJSON
=<< (^.. values)
<$> ((respBody ^? key "usergroups") ?? "\"users.list\" response didn't include a \"channels\" field")
return $ find (\x -> (x ^. handle) == expectedHandle) groups

createGroup :: Token -> Text -> Text -> [Text] -> ExceptT Text IO Group
Expand All @@ -82,5 +84,5 @@ createGroup apiToken groupHandle groupName defaultChannelIDs = do
, "channels" .= intercalate "," (unpack <$> defaultChannelIDs)
]
respBody <- slackPost apiToken params "usergroups.create"
val <- (respBody ^? key "usergroup") ?? "\"usergroups.create\" response didn't include a \"usergroup\" key"
val <- (respBody ^? key "usergroup") ?? "\"usergroups.create\" response didn't include a \"usergroup\" key"
fromJSON val
11 changes: 6 additions & 5 deletions src/Slack/User.hs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ module Slack.User
, User
, id
, displayName
) where
)
where

import Prelude hiding (id)
import Slack.Util (slackGet, slackGetPaginated, fromJSON, Token)
Expand Down Expand Up @@ -41,13 +42,13 @@ getUser :: Token -> Text -> ExceptT Text IO User
getUser apiToken userID = do
let opts = defaults & param "user" .~ [userID]
respBody <- slackGet apiToken opts "users.info"
val <- (respBody ^? key "user") ?? "\"users.info\" response didn't include a \"user\" field"
val <- (respBody ^? key "user") ?? "\"users.info\" response didn't include a \"user\" field"
fromJSON val

listAllUsers :: Token -> ExceptT Text IO [User]
listAllUsers apiToken = do
respBodies <- slackGetPaginated apiToken defaults "users.list"
vals <- concatMap (^.. values) <$>
(traverse (^? key "members") respBodies ??
"\"users.list\" response didn't include a \"members\" field")
vals <-
concatMap (^.. values)
<$> (traverse (^? key "members") respBodies ?? "\"users.list\" response didn't include a \"members\" field")
traverse fromJSON vals
41 changes: 20 additions & 21 deletions src/Slack/Util.hs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ module Slack.Util
, slackPost
, fromJSON
, Token
) where
)
where

import Prelude hiding (error)
import Data.Text as T (Text, pack, null)
Expand All @@ -34,7 +35,7 @@ slackURL = ("https://slack.com/api/" ++)
slackGet :: Token -> Options -> String -> ExceptT Text IO Value
slackGet apiToken opts method = do
let optsWithAuth = opts & auth ?~ oauth2Bearer apiToken
let url = slackURL method
let url = slackURL method
resp <- lift (asValue =<< getWith optsWithAuth url)
hoistEither $ handleSlackError "GET" method resp

Expand All @@ -44,35 +45,33 @@ slackGetPaginated' :: Maybe Text -> [Value] -> Token -> Options -> String -> Exc
slackGetPaginated' cursor !acc apiToken opts method = do
let optsWithCursor = opts & param "cursor" .~ maybeToList cursor
respBody <- slackGet apiToken optsWithCursor method
let
nextCursor = mfilter (not . T.null) $
respBody ^? key "response_metadata" . key "next_cursor" . _String
let nextAcc = respBody : acc
let nextCursor = mfilter (not . T.null) $ respBody ^? key "response_metadata" . key "next_cursor" . _String
let nextAcc = respBody : acc
case nextCursor of
Just _ -> slackGetPaginated' nextCursor nextAcc apiToken opts method
Nothing -> return $ reverse nextAcc
Just _ -> slackGetPaginated' nextCursor nextAcc apiToken opts method
Nothing -> return $ reverse nextAcc

slackPost :: Token -> [Pair] -> String -> ExceptT Text IO Value
slackPost apiToken params method = do
let optsWithAuth = defaults & auth ?~ oauth2Bearer apiToken
let url = slackURL method
let body = toJSON $ object params
let url = slackURL method
let body = toJSON $ object params
resp <- lift $ asValue =<< postWith optsWithAuth url body
hoistEither $ handleSlackError "POST" method resp

handleSlackError :: Text -> String -> Response Value -> Either Text Value
handleSlackError httpMethod method resp =
let respBody = resp ^. responseBody
ok = respBody ^?! key "ok" . _Bool
error = respBody ^. key "error" . _String
detail = respBody ^? key "detail" . _String
in if ok then
Right respBody
else
Left (httpMethod <> " " <> T.pack method <> ": " <> error <> maybe "" (" - " <>) detail)
ok = respBody ^?! key "ok" . _Bool
error = respBody ^. key "error" . _String
detail = respBody ^? key "detail" . _String
in if ok
then Right respBody
else Left (httpMethod <> " " <> T.pack method <> ": " <> error <> maybe "" (" - " <>) detail)

fromJSON :: (FromJSON a, Monad m) => Value -> ExceptT Text m a
fromJSON = hoistEither . hoistResult . A.fromJSON
where hoistResult res = case res of
Error e -> Left $ pack e
Success o -> Right o
fromJSON = hoistEither . hoistResult . A.fromJSON
where
hoistResult res = case res of
Error e -> Left $ pack e
Success o -> Right o

0 comments on commit 769eccd

Please sign in to comment.