2017-04-10 02:12:31 +02:00
|
|
|
/* Copyright 2017 Andrew Dawson
|
|
|
|
*
|
|
|
|
* This file is a part of Tusky.
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
|
|
|
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
|
|
|
|
* License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* Tusky is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
|
|
|
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
|
|
|
* Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License along with Tusky; if not,
|
|
|
|
* see <http://www.gnu.org/licenses>. */
|
|
|
|
|
2017-05-05 00:55:34 +02:00
|
|
|
package com.keylesspalace.tusky.network;
|
2017-03-08 22:08:50 +01:00
|
|
|
|
2017-11-05 22:32:36 +01:00
|
|
|
import android.support.annotation.Nullable;
|
|
|
|
|
2017-03-10 03:55:07 +01:00
|
|
|
import com.keylesspalace.tusky.entity.AccessToken;
|
2017-03-08 23:19:03 +01:00
|
|
|
import com.keylesspalace.tusky.entity.Account;
|
2017-03-10 03:55:07 +01:00
|
|
|
import com.keylesspalace.tusky.entity.AppCredentials;
|
2017-11-30 20:12:09 +01:00
|
|
|
import com.keylesspalace.tusky.entity.Attachment;
|
2017-10-27 13:20:17 +02:00
|
|
|
import com.keylesspalace.tusky.entity.Card;
|
2018-04-13 22:37:21 +02:00
|
|
|
import com.keylesspalace.tusky.entity.Emoji;
|
2018-04-22 10:35:46 +02:00
|
|
|
import com.keylesspalace.tusky.entity.Instance;
|
2018-01-06 19:01:37 +01:00
|
|
|
import com.keylesspalace.tusky.entity.MastoList;
|
2017-03-09 00:27:37 +01:00
|
|
|
import com.keylesspalace.tusky.entity.Notification;
|
2017-03-08 22:08:50 +01:00
|
|
|
import com.keylesspalace.tusky.entity.Relationship;
|
2017-06-19 10:18:39 +02:00
|
|
|
import com.keylesspalace.tusky.entity.SearchResults;
|
2017-03-09 00:27:37 +01:00
|
|
|
import com.keylesspalace.tusky.entity.Status;
|
2017-03-08 22:08:50 +01:00
|
|
|
import com.keylesspalace.tusky.entity.StatusContext;
|
|
|
|
|
|
|
|
import java.util.List;
|
|
|
|
|
2017-03-09 16:59:18 +01:00
|
|
|
import okhttp3.MultipartBody;
|
2018-02-12 22:04:18 +01:00
|
|
|
import okhttp3.RequestBody;
|
2017-03-08 22:34:13 +01:00
|
|
|
import okhttp3.ResponseBody;
|
2017-03-08 22:08:50 +01:00
|
|
|
import retrofit2.Call;
|
|
|
|
import retrofit2.http.DELETE;
|
|
|
|
import retrofit2.http.Field;
|
|
|
|
import retrofit2.http.FormUrlEncoded;
|
|
|
|
import retrofit2.http.GET;
|
2018-02-03 22:45:14 +01:00
|
|
|
import retrofit2.http.Header;
|
2017-03-08 22:08:50 +01:00
|
|
|
import retrofit2.http.Multipart;
|
2017-04-15 01:46:33 +02:00
|
|
|
import retrofit2.http.PATCH;
|
2017-03-08 22:08:50 +01:00
|
|
|
import retrofit2.http.POST;
|
2018-01-08 23:16:21 +01:00
|
|
|
import retrofit2.http.PUT;
|
2017-03-08 22:08:50 +01:00
|
|
|
import retrofit2.http.Part;
|
|
|
|
import retrofit2.http.Path;
|
|
|
|
import retrofit2.http.Query;
|
|
|
|
|
2017-06-22 20:01:25 +02:00
|
|
|
public interface MastodonApi {
|
2017-03-10 21:12:40 +01:00
|
|
|
String ENDPOINT_AUTHORIZE = "/oauth/authorize";
|
2018-03-27 19:47:00 +02:00
|
|
|
String DOMAIN_HEADER = "domain";
|
2018-04-22 17:20:01 +02:00
|
|
|
String PLACEHOLDER_DOMAIN = "dummy.placeholder";
|
2017-03-10 21:12:40 +01:00
|
|
|
|
2017-03-08 22:08:50 +01:00
|
|
|
@GET("api/v1/timelines/home")
|
2017-03-08 23:19:03 +01:00
|
|
|
Call<List<Status>> homeTimeline(
|
|
|
|
@Query("max_id") String maxId,
|
|
|
|
@Query("since_id") String sinceId,
|
|
|
|
@Query("limit") Integer limit);
|
2017-03-08 22:08:50 +01:00
|
|
|
@GET("api/v1/timelines/public")
|
2017-03-08 23:19:03 +01:00
|
|
|
Call<List<Status>> publicTimeline(
|
|
|
|
@Query("local") Boolean local,
|
|
|
|
@Query("max_id") String maxId,
|
|
|
|
@Query("since_id") String sinceId,
|
|
|
|
@Query("limit") Integer limit);
|
2017-03-08 22:08:50 +01:00
|
|
|
@GET("api/v1/timelines/tag/{hashtag}")
|
2017-03-08 23:19:03 +01:00
|
|
|
Call<List<Status>> hashtagTimeline(
|
|
|
|
@Path("hashtag") String hashtag,
|
|
|
|
@Query("local") Boolean local,
|
|
|
|
@Query("max_id") String maxId,
|
|
|
|
@Query("since_id") String sinceId,
|
|
|
|
@Query("limit") Integer limit);
|
2018-01-06 19:01:37 +01:00
|
|
|
@GET("api/v1/timelines/list/{listId}")
|
|
|
|
Call<List<Status>> listTimeline(
|
|
|
|
@Path("listId") String listId,
|
|
|
|
@Query("max_id") String maxId,
|
|
|
|
@Query("since_id") String sinceId,
|
|
|
|
@Query("limit") Integer limit);
|
2017-03-08 22:08:50 +01:00
|
|
|
|
|
|
|
@GET("api/v1/notifications")
|
2017-03-08 23:19:03 +01:00
|
|
|
Call<List<Notification>> notifications(
|
|
|
|
@Query("max_id") String maxId,
|
|
|
|
@Query("since_id") String sinceId,
|
|
|
|
@Query("limit") Integer limit);
|
2018-02-03 22:45:14 +01:00
|
|
|
@GET("api/v1/notifications")
|
|
|
|
Call<List<Notification>> notificationsWithAuth(
|
2018-03-27 19:47:00 +02:00
|
|
|
@Header("Authorization") String auth, @Header(DOMAIN_HEADER) String domain);
|
2017-03-08 22:08:50 +01:00
|
|
|
@POST("api/v1/notifications/clear")
|
2017-03-08 22:34:13 +01:00
|
|
|
Call<ResponseBody> clearNotifications();
|
2017-03-08 22:08:50 +01:00
|
|
|
@GET("api/v1/notifications/{id}")
|
2017-03-08 23:19:03 +01:00
|
|
|
Call<Notification> notification(@Path("id") String notificationId);
|
2017-03-08 22:08:50 +01:00
|
|
|
|
|
|
|
@Multipart
|
|
|
|
@POST("api/v1/media")
|
2017-11-30 20:12:09 +01:00
|
|
|
Call<Attachment> uploadMedia(@Part MultipartBody.Part file);
|
2018-01-08 23:16:21 +01:00
|
|
|
@FormUrlEncoded
|
|
|
|
@PUT("api/v1/media/{mediaId}")
|
|
|
|
Call<Attachment> updateMedia(@Path("mediaId") String mediaId,
|
|
|
|
@Field("description") String description);
|
2017-03-08 22:08:50 +01:00
|
|
|
|
|
|
|
@FormUrlEncoded
|
|
|
|
@POST("api/v1/statuses")
|
2017-03-08 23:19:03 +01:00
|
|
|
Call<Status> createStatus(
|
2018-04-13 22:37:21 +02:00
|
|
|
@Header("Authorization") String auth,
|
|
|
|
@Header(DOMAIN_HEADER) String domain,
|
2017-03-08 23:19:03 +01:00
|
|
|
@Field("status") String text,
|
|
|
|
@Field("in_reply_to_id") String inReplyToId,
|
|
|
|
@Field("spoiler_text") String warningText,
|
|
|
|
@Field("visibility") String visibility,
|
|
|
|
@Field("sensitive") Boolean sensitive,
|
2018-04-13 22:37:21 +02:00
|
|
|
@Field("media_ids[]") List<String> mediaIds,
|
|
|
|
@Header("Idempotency-Key") String idempotencyKey);
|
2017-03-08 22:08:50 +01:00
|
|
|
@GET("api/v1/statuses/{id}")
|
2017-03-08 23:19:03 +01:00
|
|
|
Call<Status> status(@Path("id") String statusId);
|
2017-03-08 22:08:50 +01:00
|
|
|
@GET("api/v1/statuses/{id}/context")
|
2017-03-08 23:19:03 +01:00
|
|
|
Call<StatusContext> statusContext(@Path("id") String statusId);
|
2017-03-08 22:08:50 +01:00
|
|
|
@GET("api/v1/statuses/{id}/reblogged_by")
|
2017-03-08 23:19:03 +01:00
|
|
|
Call<List<Account>> statusRebloggedBy(
|
|
|
|
@Path("id") String statusId,
|
|
|
|
@Query("max_id") String maxId,
|
|
|
|
@Query("since_id") String sinceId,
|
|
|
|
@Query("limit") Integer limit);
|
2017-03-08 22:08:50 +01:00
|
|
|
@GET("api/v1/statuses/{id}/favourited_by")
|
2017-03-08 23:19:03 +01:00
|
|
|
Call<List<Account>> statusFavouritedBy(
|
|
|
|
@Path("id") String statusId,
|
|
|
|
@Query("max_id") String maxId,
|
|
|
|
@Query("since_id") String sinceId,
|
|
|
|
@Query("limit") Integer limit);
|
2017-03-08 22:08:50 +01:00
|
|
|
@DELETE("api/v1/statuses/{id}")
|
2017-03-08 23:19:03 +01:00
|
|
|
Call<ResponseBody> deleteStatus(@Path("id") String statusId);
|
2017-03-08 22:08:50 +01:00
|
|
|
@POST("api/v1/statuses/{id}/reblog")
|
2017-03-08 23:19:03 +01:00
|
|
|
Call<Status> reblogStatus(@Path("id") String statusId);
|
2017-03-08 22:08:50 +01:00
|
|
|
@POST("api/v1/statuses/{id}/unreblog")
|
2017-03-08 23:19:03 +01:00
|
|
|
Call<Status> unreblogStatus(@Path("id") String statusId);
|
2017-03-08 22:08:50 +01:00
|
|
|
@POST("api/v1/statuses/{id}/favourite")
|
2017-03-08 23:19:03 +01:00
|
|
|
Call<Status> favouriteStatus(@Path("id") String statusId);
|
2017-03-08 22:08:50 +01:00
|
|
|
@POST("api/v1/statuses/{id}/unfavourite")
|
2017-03-08 23:19:03 +01:00
|
|
|
Call<Status> unfavouriteStatus(@Path("id") String statusId);
|
2017-03-08 22:08:50 +01:00
|
|
|
|
|
|
|
@GET("api/v1/accounts/verify_credentials")
|
|
|
|
Call<Account> accountVerifyCredentials();
|
2018-02-12 22:04:18 +01:00
|
|
|
|
|
|
|
@Multipart
|
2017-04-15 01:46:33 +02:00
|
|
|
@PATCH("api/v1/accounts/update_credentials")
|
2018-02-12 22:04:18 +01:00
|
|
|
Call<Account> accountUpdateCredentials(
|
|
|
|
@Nullable @Part(value="display_name") RequestBody displayName,
|
|
|
|
@Nullable @Part(value="note") RequestBody note,
|
2018-03-27 20:46:53 +02:00
|
|
|
@Nullable @Part(value="locked") RequestBody locked,
|
2018-02-12 22:04:18 +01:00
|
|
|
@Nullable @Part MultipartBody.Part avatar,
|
|
|
|
@Nullable @Part MultipartBody.Part header);
|
|
|
|
|
2017-03-08 22:08:50 +01:00
|
|
|
@GET("api/v1/accounts/search")
|
2017-03-08 23:19:03 +01:00
|
|
|
Call<List<Account>> searchAccounts(
|
|
|
|
@Query("q") String q,
|
|
|
|
@Query("resolve") Boolean resolve,
|
|
|
|
@Query("limit") Integer limit);
|
2017-03-08 22:08:50 +01:00
|
|
|
@GET("api/v1/accounts/{id}")
|
2017-03-08 23:19:03 +01:00
|
|
|
Call<Account> account(@Path("id") String accountId);
|
2017-11-05 22:32:36 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Method to fetch statuses for the specified account.
|
|
|
|
* @param accountId ID for account for which statuses will be requested
|
|
|
|
* @param maxId Only statuses with ID less than maxID will be returned
|
|
|
|
* @param sinceId Only statuses with ID bigger than sinceID will be returned
|
|
|
|
* @param limit Limit returned statuses (current API limits: default - 20, max - 40)
|
|
|
|
* @param onlyMedia Should server return only statuses which contain media. Caution! The server
|
|
|
|
* works in a weird way so if any value if present at this field it will be
|
|
|
|
* interpreted as "true". Pass null to return all statuses.
|
|
|
|
* @return
|
|
|
|
*/
|
2017-03-08 22:08:50 +01:00
|
|
|
@GET("api/v1/accounts/{id}/statuses")
|
2017-03-08 23:19:03 +01:00
|
|
|
Call<List<Status>> accountStatuses(
|
|
|
|
@Path("id") String accountId,
|
|
|
|
@Query("max_id") String maxId,
|
|
|
|
@Query("since_id") String sinceId,
|
2017-11-05 22:32:36 +01:00
|
|
|
@Query("limit") Integer limit,
|
|
|
|
@Nullable @Query("only_media") Boolean onlyMedia);
|
2017-03-08 22:08:50 +01:00
|
|
|
@GET("api/v1/accounts/{id}/followers")
|
2017-03-08 23:19:03 +01:00
|
|
|
Call<List<Account>> accountFollowers(
|
|
|
|
@Path("id") String accountId,
|
|
|
|
@Query("max_id") String maxId,
|
|
|
|
@Query("since_id") String sinceId,
|
|
|
|
@Query("limit") Integer limit);
|
2017-03-08 22:08:50 +01:00
|
|
|
@GET("api/v1/accounts/{id}/following")
|
2017-03-08 23:19:03 +01:00
|
|
|
Call<List<Account>> accountFollowing(
|
|
|
|
@Path("id") String accountId,
|
|
|
|
@Query("max_id") String maxId,
|
|
|
|
@Query("since_id") String sinceId,
|
|
|
|
@Query("limit") Integer limit);
|
2017-03-08 22:08:50 +01:00
|
|
|
@POST("api/v1/accounts/{id}/follow")
|
2017-03-08 23:19:03 +01:00
|
|
|
Call<Relationship> followAccount(@Path("id") String accountId);
|
2017-03-08 22:08:50 +01:00
|
|
|
@POST("api/v1/accounts/{id}/unfollow")
|
2017-03-08 23:19:03 +01:00
|
|
|
Call<Relationship> unfollowAccount(@Path("id") String accountId);
|
2017-03-08 22:08:50 +01:00
|
|
|
@POST("api/v1/accounts/{id}/block")
|
2017-03-08 23:19:03 +01:00
|
|
|
Call<Relationship> blockAccount(@Path("id") String accountId);
|
2017-03-08 22:08:50 +01:00
|
|
|
@POST("api/v1/accounts/{id}/unblock")
|
2017-03-08 23:19:03 +01:00
|
|
|
Call<Relationship> unblockAccount(@Path("id") String accountId);
|
2017-03-08 22:08:50 +01:00
|
|
|
@POST("api/v1/accounts/{id}/mute")
|
2017-03-08 23:19:03 +01:00
|
|
|
Call<Relationship> muteAccount(@Path("id") String accountId);
|
2017-03-08 22:08:50 +01:00
|
|
|
@POST("api/v1/accounts/{id}/unmute")
|
2017-03-08 23:19:03 +01:00
|
|
|
Call<Relationship> unmuteAccount(@Path("id") String accountId);
|
2017-03-08 22:08:50 +01:00
|
|
|
|
|
|
|
@GET("api/v1/accounts/relationships")
|
2017-03-09 01:01:45 +01:00
|
|
|
Call<List<Relationship>> relationships(@Query("id[]") List<String> accountIds);
|
2017-03-08 22:08:50 +01:00
|
|
|
|
|
|
|
@GET("api/v1/blocks")
|
2017-03-08 23:19:03 +01:00
|
|
|
Call<List<Account>> blocks(
|
|
|
|
@Query("max_id") String maxId,
|
|
|
|
@Query("since_id") String sinceId,
|
|
|
|
@Query("limit") Integer limit);
|
2017-03-08 22:08:50 +01:00
|
|
|
|
|
|
|
@GET("api/v1/mutes")
|
2017-03-08 23:19:03 +01:00
|
|
|
Call<List<Account>> mutes(
|
|
|
|
@Query("max_id") String maxId,
|
|
|
|
@Query("since_id") String sinceId,
|
|
|
|
@Query("limit") Integer limit);
|
2017-03-08 22:08:50 +01:00
|
|
|
|
|
|
|
@GET("api/v1/favourites")
|
2017-03-09 00:27:37 +01:00
|
|
|
Call<List<Status>> favourites(
|
2017-03-08 23:19:03 +01:00
|
|
|
@Query("max_id") String maxId,
|
|
|
|
@Query("since_id") String sinceId,
|
|
|
|
@Query("limit") Integer limit);
|
2017-03-08 22:08:50 +01:00
|
|
|
|
|
|
|
@GET("api/v1/follow_requests")
|
2017-03-08 23:19:03 +01:00
|
|
|
Call<List<Account>> followRequests(
|
|
|
|
@Query("max_id") String maxId,
|
|
|
|
@Query("since_id") String sinceId,
|
|
|
|
@Query("limit") Integer limit);
|
2017-03-08 22:08:50 +01:00
|
|
|
@POST("api/v1/follow_requests/{id}/authorize")
|
2017-03-08 23:19:03 +01:00
|
|
|
Call<Relationship> authorizeFollowRequest(@Path("id") String accountId);
|
2017-03-08 22:08:50 +01:00
|
|
|
@POST("api/v1/follow_requests/{id}/reject")
|
2017-03-08 23:19:03 +01:00
|
|
|
Call<Relationship> rejectFollowRequest(@Path("id") String accountId);
|
2017-03-09 16:59:18 +01:00
|
|
|
|
|
|
|
@FormUrlEncoded
|
|
|
|
@POST("api/v1/reports")
|
2017-07-02 02:32:35 +02:00
|
|
|
Call<ResponseBody> report(
|
|
|
|
@Field("account_id") String accountId,
|
|
|
|
@Field("status_ids[]") List<String> statusIds,
|
|
|
|
@Field("comment") String comment);
|
2017-03-10 03:55:07 +01:00
|
|
|
|
2017-06-19 10:18:39 +02:00
|
|
|
@GET("api/v1/search")
|
|
|
|
Call<SearchResults> search(@Query("q") String q, @Query("resolve") Boolean resolve);
|
|
|
|
|
2017-03-10 03:55:07 +01:00
|
|
|
@FormUrlEncoded
|
|
|
|
@POST("api/v1/apps")
|
|
|
|
Call<AppCredentials> authenticateApp(
|
2018-04-22 17:20:01 +02:00
|
|
|
@Header(DOMAIN_HEADER) String domain,
|
2017-03-10 03:55:07 +01:00
|
|
|
@Field("client_name") String clientName,
|
2017-03-13 19:13:49 +01:00
|
|
|
@Field("redirect_uris") String redirectUris,
|
2017-03-10 03:55:07 +01:00
|
|
|
@Field("scopes") String scopes,
|
|
|
|
@Field("website") String website);
|
|
|
|
|
|
|
|
@FormUrlEncoded
|
|
|
|
@POST("oauth/token")
|
|
|
|
Call<AccessToken> fetchOAuthToken(
|
2018-04-22 17:20:01 +02:00
|
|
|
@Header(DOMAIN_HEADER) String domain,
|
2017-03-10 03:55:07 +01:00
|
|
|
@Field("client_id") String clientId,
|
|
|
|
@Field("client_secret") String clientSecret,
|
|
|
|
@Field("redirect_uri") String redirectUri,
|
|
|
|
@Field("code") String code,
|
|
|
|
@Field("grant_type") String grantType
|
|
|
|
);
|
2017-10-27 13:20:17 +02:00
|
|
|
|
|
|
|
@GET("/api/v1/statuses/{id}/card")
|
|
|
|
Call<Card> statusCard(
|
|
|
|
@Path("id") String statusId
|
|
|
|
);
|
2018-01-06 19:01:37 +01:00
|
|
|
|
|
|
|
@GET("/api/v1/lists")
|
|
|
|
Call<List<MastoList>> getLists();
|
2018-04-13 22:37:21 +02:00
|
|
|
|
|
|
|
@GET("/api/v1/custom_emojis")
|
|
|
|
Call<List<Emoji>> getCustomEmojis();
|
2018-04-22 10:35:46 +02:00
|
|
|
|
|
|
|
@GET("api/v1/instance")
|
|
|
|
Call<Instance> getInstance();
|
2017-03-08 22:08:50 +01:00
|
|
|
}
|