135 lines
4.1 KiB
Haskell
Raw Normal View History

2025-01-24 22:38:58 +01:00
module TeaCleaner.Client
2025-01-26 10:17:33 +01:00
( Activity(..)
, User(..)
, getActivities
2025-01-24 22:38:58 +01:00
, getUsers
, purgeUser
) where
import Data.List.NonEmpty (NonEmpty(..))
2025-01-26 10:17:33 +01:00
import Data.Text (StrictText)
import qualified Data.Text.Encoding as Text.Encoding
2025-01-24 22:38:58 +01:00
import Data.Vector (Vector)
import Text.URI (URI(..))
import qualified Text.URI as URI
import qualified Text.URI.QQ as URI
import Network.HTTP.Req
( DELETE(..)
, GET(..)
, NoReqBody(..)
, defaultHttpConfig
, ignoreResponse
, jsonResponse
, oAuth2Bearer
, responseBody
, req
, runReq
, useHttpsURI
)
import GHC.Records (HasField(..))
2025-01-26 10:17:33 +01:00
import TeaCleaner.Options (jsonOptions)
import Data.Int (Int64)
import qualified Data.Aeson.TH as Aeson
import Data.Time (ZonedTime(..))
2025-01-24 22:38:58 +01:00
2025-01-26 10:17:33 +01:00
data User = User
{ id :: Int64
, login :: StrictText
, loginName :: StrictText
, fullName :: StrictText
, email :: StrictText
, avatarUrl :: StrictText
, language :: StrictText
, isAdmin :: Bool
, lastLogin :: ZonedTime
, created :: ZonedTime
, restricted :: Bool
, active :: Bool
, prohibitLogin :: Bool
, location :: StrictText
, website :: StrictText
, description :: StrictText
, visibility :: StrictText
, followersCount :: Int
, followingCount :: Int
, starredReposCount :: Int
, username :: StrictText
} deriving (Show)
$(Aeson.deriveJSON jsonOptions ''User)
data Activity = Activity
{ actUserId :: Int64
-- , comment Comment
, commentId :: Int64
, content :: StrictText
, created :: ZonedTime
, id :: Int64
, isPrivate :: Bool
, opType :: StrictText
, refName :: StrictText
-- repo Repository{...}
, repoId :: Int64
, userId :: Int64
} deriving (Show)
$(Aeson.deriveJSON jsonOptions ''Activity)
purgeUser :: URI -> StrictText -> User -> IO ()
purgeUser server token user =
2025-01-24 22:38:58 +01:00
let pathConstructor lastPiece = [URI.pathPiece|api|] :|
[ [URI.pathPiece|v1|]
, [URI.pathPiece|admin|]
, [URI.pathPiece|users|]
, lastPiece
]
uri = server
{ URI.uriPath = (False,) . pathConstructor
<$> URI.mkPathPiece (getField @"username" user)
, URI.uriQuery = [URI.QueryParam [URI.queryKey|purge|] [URI.queryValue|true|]]
}
in case useHttpsURI uri of
Just (httpsURI, httpsOptions) -> fmap responseBody
$ runReq defaultHttpConfig
$ req DELETE httpsURI NoReqBody ignoreResponse
2025-01-26 10:17:33 +01:00
$ httpsOptions <> oAuth2Bearer (Text.Encoding.encodeUtf8 token)
2025-01-24 22:38:58 +01:00
Nothing -> error "Invalid https URI"
2025-01-26 10:17:33 +01:00
getActivities :: URI -> StrictText -> User -> IO (Vector Activity)
getActivities server token user =
2025-01-24 22:38:58 +01:00
let pathConstructor lastPiece = [URI.pathPiece|api|] :|
[ [URI.pathPiece|v1|]
, [URI.pathPiece|users|]
, lastPiece
, [URI.pathPiece|activities|]
, [URI.pathPiece|feeds|]
]
uri = server
{ URI.uriPath = (False,) . pathConstructor
<$> URI.mkPathPiece (getField @"username" user)
, URI.uriQuery = [URI.QueryParam [URI.queryKey|purge|] [URI.queryValue|true|]]
}
in case useHttpsURI uri of
Just (httpsURI, httpsOptions) -> fmap responseBody
$ runReq defaultHttpConfig
$ req GET httpsURI NoReqBody jsonResponse
2025-01-26 10:17:33 +01:00
$ httpsOptions <> oAuth2Bearer (Text.Encoding.encodeUtf8 token)
2025-01-24 22:38:58 +01:00
Nothing -> error "Invalid https URI"
2025-01-26 10:17:33 +01:00
getUsers :: URI -> StrictText -> IO (Vector User)
getUsers server token =
2025-01-24 22:38:58 +01:00
let pathPieces = [URI.pathPiece|api|] :|
[ [URI.pathPiece|v1|]
, [URI.pathPiece|admin|]
, [URI.pathPiece|users|]
]
uri = server
{ URI.uriPath = Just (False, pathPieces)
}
in case useHttpsURI uri of
Just (httpsURI, httpsOptions) -> fmap responseBody
$ runReq defaultHttpConfig
$ req GET httpsURI NoReqBody jsonResponse
2025-01-26 10:17:33 +01:00
$ httpsOptions <> oAuth2Bearer (Text.Encoding.encodeUtf8 token)
2025-01-24 22:38:58 +01:00
Nothing -> error "Invalid https URI"