142 lines
4.2 KiB
Haskell
Raw Normal View History

2025-02-24 21:09:23 +01:00
{- This Source Code Form is subject to the terms of the Mozilla Public License,
v. 2.0. If a copy of the MPL was not distributed with this file, You can
obtain one at https://mozilla.org/MPL/2.0/. -}
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 qualified Text.URI as URI
import qualified Text.URI.QQ as URI
import Network.HTTP.Req
( DELETE(..)
, GET(..)
, NoReqBody(..)
2025-02-18 11:57:18 +01:00
, HttpMethod(..)
, HttpBody
, HttpResponse(..)
, HttpBodyAllowed
, ProvidesBody
2025-01-24 22:38:58 +01:00
, 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-02-18 11:57:18 +01:00
import TeaCleaner.Configuration (Settings(..))
import Data.Data (Proxy)
import Text.URI (URI)
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)
2025-02-18 11:57:18 +01:00
purgeUser :: Settings -> User -> IO ()
purgeUser Settings{..} 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|]]
}
2025-02-18 11:57:18 +01:00
in doRequest uri token DELETE NoReqBody ignoreResponse
2025-01-24 22:38:58 +01:00
2025-02-18 11:57:18 +01:00
getActivities :: Settings -> User -> IO (Vector Activity)
getActivities Settings{..} 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|]]
}
2025-02-18 11:57:18 +01:00
in doRequest uri token GET NoReqBody jsonResponse
2025-01-24 22:38:58 +01:00
2025-02-18 11:57:18 +01:00
getUsers :: Settings -> IO (Vector User)
getUsers Settings{..} =
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)
}
2025-02-18 11:57:18 +01:00
in doRequest uri token GET NoReqBody jsonResponse
doRequest
:: (HttpMethod method, HttpBody body, HttpResponse response, HttpBodyAllowed (AllowsBody method) (ProvidesBody body))
=> URI -> StrictText -> method -> body -> Proxy response -> IO (HttpResponseBody response)
doRequest uri token method body response =
case useHttpsURI uri of
2025-01-24 22:38:58 +01:00
Just (httpsURI, httpsOptions) -> fmap responseBody
$ runReq defaultHttpConfig
2025-02-18 11:57:18 +01:00
$ req method httpsURI body response
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"