2017-04-27 10:34:27 -04:00
|
|
|
module Mastodon.Http
|
|
|
|
exposing
|
|
|
|
( Request
|
2017-04-27 12:39:14 -04:00
|
|
|
, context
|
2017-04-27 10:34:27 -04:00
|
|
|
, reblog
|
|
|
|
, unreblog
|
|
|
|
, favourite
|
|
|
|
, unfavourite
|
2017-04-29 16:48:55 -04:00
|
|
|
, follow
|
|
|
|
, unfollow
|
2017-04-27 10:34:27 -04:00
|
|
|
, register
|
|
|
|
, getAuthorizationUrl
|
|
|
|
, getAccessToken
|
|
|
|
, fetchAccount
|
2017-04-27 16:01:51 -04:00
|
|
|
, fetchAccountTimeline
|
2017-04-29 12:05:06 -04:00
|
|
|
, fetchAccountFollowers
|
|
|
|
, fetchAccountFollowing
|
2017-04-27 10:34:27 -04:00
|
|
|
, fetchLocalTimeline
|
|
|
|
, fetchNotifications
|
|
|
|
, fetchGlobalTimeline
|
|
|
|
, fetchUserTimeline
|
2017-04-29 16:48:55 -04:00
|
|
|
, fetchRelationships
|
2017-04-27 10:34:27 -04:00
|
|
|
, postStatus
|
2017-04-29 03:20:26 -04:00
|
|
|
, deleteStatus
|
2017-04-28 05:21:54 -04:00
|
|
|
, userAccount
|
2017-04-27 10:34:27 -04:00
|
|
|
, send
|
2017-05-01 16:10:34 -04:00
|
|
|
, searchAccounts
|
2017-04-27 10:34:27 -04:00
|
|
|
)
|
|
|
|
|
|
|
|
import Http
|
2017-05-02 16:26:13 -04:00
|
|
|
import HttpBuilder as Build
|
2017-04-27 10:34:27 -04:00
|
|
|
import Json.Decode as Decode
|
|
|
|
import Mastodon.ApiUrl as ApiUrl
|
|
|
|
import Mastodon.Decoder exposing (..)
|
|
|
|
import Mastodon.Encoder exposing (..)
|
|
|
|
import Mastodon.Model exposing (..)
|
|
|
|
|
|
|
|
|
2017-05-03 02:52:39 -04:00
|
|
|
type Method
|
|
|
|
= GET
|
|
|
|
| POST
|
|
|
|
| DELETE
|
|
|
|
|
|
|
|
|
2017-04-27 10:34:27 -04:00
|
|
|
type alias Request a =
|
2017-05-02 16:26:13 -04:00
|
|
|
Build.RequestBuilder a
|
2017-04-27 10:34:27 -04:00
|
|
|
|
|
|
|
|
|
|
|
extractMastodonError : Int -> String -> String -> Error
|
|
|
|
extractMastodonError statusCode statusMsg body =
|
|
|
|
case Decode.decodeString mastodonErrorDecoder body of
|
|
|
|
Ok errRecord ->
|
|
|
|
MastodonError statusCode statusMsg errRecord
|
|
|
|
|
|
|
|
Err err ->
|
|
|
|
ServerError statusCode statusMsg err
|
|
|
|
|
|
|
|
|
|
|
|
extractError : Http.Error -> Error
|
|
|
|
extractError error =
|
|
|
|
case error of
|
|
|
|
Http.BadStatus { status, body } ->
|
|
|
|
extractMastodonError status.code status.message body
|
|
|
|
|
|
|
|
Http.BadPayload str { status } ->
|
|
|
|
ServerError
|
|
|
|
status.code
|
|
|
|
status.message
|
|
|
|
("Failed decoding JSON: " ++ str)
|
|
|
|
|
|
|
|
Http.Timeout ->
|
|
|
|
TimeoutError
|
|
|
|
|
|
|
|
_ ->
|
|
|
|
NetworkError
|
|
|
|
|
|
|
|
|
|
|
|
toResponse : Result Http.Error a -> Result Error a
|
|
|
|
toResponse result =
|
|
|
|
Result.mapError extractError result
|
|
|
|
|
|
|
|
|
2017-05-03 02:52:39 -04:00
|
|
|
request : String -> Method -> String -> Decode.Decoder a -> Request a
|
|
|
|
request server method endpoint decoder =
|
2017-05-02 16:05:46 -04:00
|
|
|
let
|
2017-05-03 02:52:39 -04:00
|
|
|
httpMethod =
|
2017-05-02 16:05:46 -04:00
|
|
|
case method of
|
|
|
|
GET ->
|
2017-05-02 16:26:13 -04:00
|
|
|
Build.get
|
2017-05-02 16:05:46 -04:00
|
|
|
|
|
|
|
POST ->
|
2017-05-02 16:26:13 -04:00
|
|
|
Build.post
|
2017-05-02 16:05:46 -04:00
|
|
|
|
|
|
|
DELETE ->
|
2017-05-02 16:26:13 -04:00
|
|
|
Build.delete
|
2017-05-02 16:05:46 -04:00
|
|
|
in
|
2017-05-03 02:52:39 -04:00
|
|
|
httpMethod (server ++ endpoint)
|
2017-05-02 16:26:13 -04:00
|
|
|
|> Build.withExpect (Http.expectJson decoder)
|
2017-04-27 10:34:27 -04:00
|
|
|
|
|
|
|
|
2017-05-03 02:52:39 -04:00
|
|
|
authRequest : Client -> Method -> String -> Decode.Decoder a -> Request a
|
|
|
|
authRequest client method endpoint decoder =
|
|
|
|
request client.server method endpoint decoder
|
|
|
|
|> Build.withHeader "Authorization" ("Bearer " ++ client.token)
|
|
|
|
|
|
|
|
|
2017-04-27 10:34:27 -04:00
|
|
|
register : String -> String -> String -> String -> String -> Request AppRegistration
|
2017-05-02 16:26:13 -04:00
|
|
|
register server clientName redirectUri scope website =
|
2017-05-03 02:52:39 -04:00
|
|
|
request server POST ApiUrl.apps (appRegistrationDecoder server scope)
|
2017-05-02 16:26:13 -04:00
|
|
|
|> Build.withJsonBody (appRegistrationEncoder clientName redirectUri scope website)
|
|
|
|
|
|
|
|
|
|
|
|
getAccessToken : AppRegistration -> String -> Request AccessTokenResult
|
|
|
|
getAccessToken registration authCode =
|
2017-05-03 02:52:39 -04:00
|
|
|
request registration.server POST ApiUrl.oauthToken (accessTokenDecoder registration)
|
2017-05-02 16:26:13 -04:00
|
|
|
|> Build.withJsonBody (authorizationCodeEncoder registration authCode)
|
2017-04-27 10:34:27 -04:00
|
|
|
|
|
|
|
|
|
|
|
getAuthorizationUrl : AppRegistration -> String
|
|
|
|
getAuthorizationUrl registration =
|
2017-05-02 16:05:46 -04:00
|
|
|
encodeUrl (registration.server ++ ApiUrl.oauthAuthorize)
|
2017-04-27 10:34:27 -04:00
|
|
|
[ ( "response_type", "code" )
|
|
|
|
, ( "client_id", registration.client_id )
|
|
|
|
, ( "scope", registration.scope )
|
|
|
|
, ( "redirect_uri", registration.redirect_uri )
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
send : (Result Error a -> msg) -> Request a -> Cmd msg
|
|
|
|
send tagger builder =
|
2017-05-02 16:26:13 -04:00
|
|
|
Build.send (toResponse >> tagger) builder
|
2017-04-27 10:34:27 -04:00
|
|
|
|
|
|
|
|
|
|
|
fetchAccount : Client -> Int -> Request Account
|
|
|
|
fetchAccount client accountId =
|
2017-05-03 02:52:39 -04:00
|
|
|
authRequest client GET (ApiUrl.account accountId) accountDecoder
|
2017-04-27 10:34:27 -04:00
|
|
|
|
|
|
|
|
|
|
|
fetchUserTimeline : Client -> Request (List Status)
|
|
|
|
fetchUserTimeline client =
|
2017-05-03 02:52:39 -04:00
|
|
|
authRequest client GET ApiUrl.homeTimeline <| Decode.list statusDecoder
|
2017-04-27 10:34:27 -04:00
|
|
|
|
|
|
|
|
2017-04-29 16:48:55 -04:00
|
|
|
fetchRelationships : Client -> List Int -> Request (List Relationship)
|
|
|
|
fetchRelationships client ids =
|
2017-05-03 02:52:39 -04:00
|
|
|
authRequest client GET ApiUrl.relationships (Decode.list relationshipDecoder)
|
2017-05-02 16:31:15 -04:00
|
|
|
|> Build.withQueryParams (List.map (\id -> ( "id[]", toString id )) ids)
|
2017-04-29 16:48:55 -04:00
|
|
|
|
|
|
|
|
2017-04-27 10:34:27 -04:00
|
|
|
fetchLocalTimeline : Client -> Request (List Status)
|
|
|
|
fetchLocalTimeline client =
|
2017-05-03 02:52:39 -04:00
|
|
|
authRequest client GET ApiUrl.publicTimeline (Decode.list statusDecoder)
|
2017-05-02 16:31:15 -04:00
|
|
|
|> Build.withQueryParams [ ( "local", "true" ) ]
|
2017-04-27 10:34:27 -04:00
|
|
|
|
|
|
|
|
|
|
|
fetchGlobalTimeline : Client -> Request (List Status)
|
|
|
|
fetchGlobalTimeline client =
|
2017-05-03 02:52:39 -04:00
|
|
|
authRequest client GET ApiUrl.publicTimeline <| Decode.list statusDecoder
|
2017-04-27 10:34:27 -04:00
|
|
|
|
|
|
|
|
2017-04-27 16:01:51 -04:00
|
|
|
fetchAccountTimeline : Client -> Int -> Request (List Status)
|
|
|
|
fetchAccountTimeline client id =
|
2017-05-03 02:52:39 -04:00
|
|
|
authRequest client GET (ApiUrl.accountTimeline id) <| Decode.list statusDecoder
|
2017-04-27 16:01:51 -04:00
|
|
|
|
|
|
|
|
2017-04-27 10:34:27 -04:00
|
|
|
fetchNotifications : Client -> Request (List Notification)
|
|
|
|
fetchNotifications client =
|
2017-05-03 02:52:39 -04:00
|
|
|
authRequest client GET (ApiUrl.notifications) <| Decode.list notificationDecoder
|
2017-04-27 10:34:27 -04:00
|
|
|
|
|
|
|
|
2017-04-29 12:05:06 -04:00
|
|
|
fetchAccountFollowers : Client -> Int -> Request (List Account)
|
|
|
|
fetchAccountFollowers client accountId =
|
2017-05-03 02:52:39 -04:00
|
|
|
authRequest client GET (ApiUrl.followers accountId) <| Decode.list accountDecoder
|
2017-04-29 12:05:06 -04:00
|
|
|
|
|
|
|
|
|
|
|
fetchAccountFollowing : Client -> Int -> Request (List Account)
|
|
|
|
fetchAccountFollowing client accountId =
|
2017-05-03 02:52:39 -04:00
|
|
|
authRequest client GET (ApiUrl.following accountId) <| Decode.list accountDecoder
|
2017-04-29 12:05:06 -04:00
|
|
|
|
|
|
|
|
2017-05-01 16:10:34 -04:00
|
|
|
searchAccounts : Client -> String -> Int -> Bool -> Request (List Account)
|
|
|
|
searchAccounts client query limit resolve =
|
2017-05-03 02:52:39 -04:00
|
|
|
authRequest client GET ApiUrl.searchAccount (Decode.list accountDecoder)
|
2017-05-02 16:26:13 -04:00
|
|
|
|> Build.withQueryParams
|
2017-05-02 16:05:46 -04:00
|
|
|
[ ( "q", query )
|
|
|
|
, ( "limit", toString limit )
|
|
|
|
, ( "resolve"
|
|
|
|
, if resolve then
|
|
|
|
"true"
|
|
|
|
else
|
|
|
|
"false"
|
|
|
|
)
|
|
|
|
]
|
2017-05-01 16:10:34 -04:00
|
|
|
|
|
|
|
|
2017-04-28 05:21:54 -04:00
|
|
|
userAccount : Client -> Request Account
|
|
|
|
userAccount client =
|
2017-05-03 02:52:39 -04:00
|
|
|
authRequest client GET ApiUrl.userAccount accountDecoder
|
2017-04-28 05:21:54 -04:00
|
|
|
|
|
|
|
|
2017-04-27 10:34:27 -04:00
|
|
|
postStatus : Client -> StatusRequestBody -> Request Status
|
|
|
|
postStatus client statusRequestBody =
|
2017-05-03 02:52:39 -04:00
|
|
|
authRequest client POST ApiUrl.statuses statusDecoder
|
2017-05-02 16:26:13 -04:00
|
|
|
|> Build.withJsonBody (statusRequestBodyEncoder statusRequestBody)
|
2017-04-27 10:34:27 -04:00
|
|
|
|
|
|
|
|
2017-04-29 03:20:26 -04:00
|
|
|
deleteStatus : Client -> Int -> Request Int
|
|
|
|
deleteStatus client id =
|
2017-05-03 02:52:39 -04:00
|
|
|
authRequest client DELETE (ApiUrl.status id) <| Decode.succeed id
|
2017-04-29 03:20:26 -04:00
|
|
|
|
|
|
|
|
2017-04-27 12:39:14 -04:00
|
|
|
context : Client -> Int -> Request Context
|
|
|
|
context client id =
|
2017-05-03 02:52:39 -04:00
|
|
|
authRequest client GET (ApiUrl.context id) contextDecoder
|
2017-04-27 12:39:14 -04:00
|
|
|
|
|
|
|
|
2017-04-27 10:34:27 -04:00
|
|
|
reblog : Client -> Int -> Request Status
|
|
|
|
reblog client id =
|
2017-05-03 02:52:39 -04:00
|
|
|
authRequest client POST (ApiUrl.reblog id) statusDecoder
|
2017-04-27 10:34:27 -04:00
|
|
|
|
|
|
|
|
|
|
|
unreblog : Client -> Int -> Request Status
|
|
|
|
unreblog client id =
|
2017-05-03 02:52:39 -04:00
|
|
|
authRequest client POST (ApiUrl.unreblog id) statusDecoder
|
2017-04-27 10:34:27 -04:00
|
|
|
|
|
|
|
|
|
|
|
favourite : Client -> Int -> Request Status
|
|
|
|
favourite client id =
|
2017-05-03 02:52:39 -04:00
|
|
|
authRequest client POST (ApiUrl.favourite id) statusDecoder
|
2017-04-27 10:34:27 -04:00
|
|
|
|
|
|
|
|
|
|
|
unfavourite : Client -> Int -> Request Status
|
|
|
|
unfavourite client id =
|
2017-05-03 02:52:39 -04:00
|
|
|
authRequest client POST (ApiUrl.unfavourite id) statusDecoder
|
2017-04-29 16:48:55 -04:00
|
|
|
|
|
|
|
|
|
|
|
follow : Client -> Int -> Request Relationship
|
|
|
|
follow client id =
|
2017-05-03 02:52:39 -04:00
|
|
|
authRequest client POST (ApiUrl.follow id) relationshipDecoder
|
2017-04-29 16:48:55 -04:00
|
|
|
|
|
|
|
|
|
|
|
unfollow : Client -> Int -> Request Relationship
|
|
|
|
unfollow client id =
|
2017-05-03 02:52:39 -04:00
|
|
|
authRequest client POST (ApiUrl.unfollow id) relationshipDecoder
|