Skip to content

Commit

Permalink
Continue implementing online themes. Remove pushshift and reveddit re…
Browse files Browse the repository at this point in the history
…trofit.
  • Loading branch information
Docile-Alligator committed Nov 7, 2024
1 parent b0a00e7 commit 3a9e1df
Show file tree
Hide file tree
Showing 9 changed files with 154 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import ml.docilealligator.infinityforreddit.apis.StreamableAPI;
import ml.docilealligator.infinityforreddit.network.AccessTokenAuthenticator;
import ml.docilealligator.infinityforreddit.network.RedgifsAccessTokenAuthenticator;
import ml.docilealligator.infinityforreddit.network.ServerAccessTokenAuthenticator;
import ml.docilealligator.infinityforreddit.network.SortTypeConverterFactory;
import ml.docilealligator.infinityforreddit.utils.APIUtils;
import okhttp3.ConnectionPool;
Expand Down Expand Up @@ -74,11 +75,24 @@ static Retrofit provideOAuthRetrofit(@Named("base") Retrofit retrofit,
@Singleton
static OkHttpClient provideOkHttpClient(@Named("base") OkHttpClient httpClient,
@Named("base") Retrofit retrofit,
RedditDataRoomDatabase accountRoomDatabase,
RedditDataRoomDatabase redditDataRoomDatabase,
@Named("current_account") SharedPreferences currentAccountSharedPreferences,
ConnectionPool connectionPool) {
return httpClient.newBuilder()
.authenticator(new AccessTokenAuthenticator(retrofit, accountRoomDatabase, currentAccountSharedPreferences))
.authenticator(new AccessTokenAuthenticator(retrofit, redditDataRoomDatabase, currentAccountSharedPreferences))
.connectionPool(connectionPool)
.build();
}

@Provides
@Named("server")
@Singleton
static OkHttpClient provideServerOkHttpClient(@Named("base") OkHttpClient httpClient,
RedditDataRoomDatabase redditDataRoomDatabase,
@Named("current_account") SharedPreferences currentAccountSharedPreferences,
ConnectionPool connectionPool) {
return httpClient.newBuilder()
.authenticator(new ServerAccessTokenAuthenticator(redditDataRoomDatabase, currentAccountSharedPreferences))
.connectionPool(connectionPool)
.build();
}
Expand Down Expand Up @@ -157,24 +171,6 @@ static Retrofit provideImgurRetrofit(@Named("base") Retrofit retrofit) {
.build();
}

@Provides
@Named("pushshift")
@Singleton
static Retrofit providePushshiftRetrofit(@Named("base") Retrofit retrofit) {
return retrofit.newBuilder()
.baseUrl(APIUtils.PUSHSHIFT_API_BASE_URI)
.build();
}

@Provides
@Named("reveddit")
@Singleton
static Retrofit provideRevedditRetrofit(@Named("base") Retrofit retrofit) {
return retrofit.newBuilder()
.baseUrl(APIUtils.REVEDDIT_API_BASE_URI)
.build();
}

@Provides
@Named("vReddIt")
@Singleton
Expand All @@ -196,9 +192,10 @@ static Retrofit provideStreamableRetrofit(@Named("base") Retrofit retrofit) {
@Provides
@Named("online_custom_themes")
@Singleton
static Retrofit provideOnlineCustomThemesRetrofit(@Named("base") Retrofit retrofit) {
static Retrofit provideOnlineCustomThemesRetrofit(@Named("base") Retrofit retrofit, @Named("server") OkHttpClient httpClient) {
return retrofit.newBuilder()
.baseUrl(APIUtils.ONLINE_CUSTOM_THEMES_API_BASE_URI)
.baseUrl(APIUtils.SERVER_API_BASE_URI)
.client(httpClient)
.build();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
import ml.docilealligator.infinityforreddit.R;
import ml.docilealligator.infinityforreddit.RecyclerViewContentScrollingInterface;
import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase;
import ml.docilealligator.infinityforreddit.apis.OnlineCustomThemeAPI;
import ml.docilealligator.infinityforreddit.apis.ServerAPI;
import ml.docilealligator.infinityforreddit.asynctasks.ChangeThemeName;
import ml.docilealligator.infinityforreddit.asynctasks.DeleteTheme;
import ml.docilealligator.infinityforreddit.asynctasks.GetCustomTheme;
Expand Down Expand Up @@ -294,7 +294,7 @@ public void shareTheme(CustomTheme customTheme) {

@Override
public void shareTheme(OnlineCustomThemeMetadata onlineCustomThemeMetadata) {
onlineCustomThemesRetrofit.create(OnlineCustomThemeAPI.class)
onlineCustomThemesRetrofit.create(ServerAPI.class)
.getCustomTheme(onlineCustomThemeMetadata.name, onlineCustomThemeMetadata.username)
.enqueue(new Callback<>() {
@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,19 @@

import com.google.common.util.concurrent.ListenableFuture;

import java.util.Map;

import retrofit2.Call;
import retrofit2.Response;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.GET;
import retrofit2.http.HeaderMap;
import retrofit2.http.PATCH;
import retrofit2.http.POST;
import retrofit2.http.Query;

public interface OnlineCustomThemeAPI {
public interface ServerAPI {
@GET("/themes/")
ListenableFuture<Response<String>> getCustomThemesListenableFuture(@Query("page") String page);

Expand All @@ -20,11 +23,16 @@ public interface OnlineCustomThemeAPI {

@FormUrlEncoded
@PATCH("/themes/modify")
Call<String> modifyTheme(@Field("id") int id, @Field("name") String themeName,
@Field("data") String customThemeJson, @Field("primary_color") String primaryColor);
Call<String> modifyTheme(@HeaderMap Map<String, String> headers, @Field("id") int id,
@Field("name") String themeName,
@Field("data") String customThemeJson);

@FormUrlEncoded
@POST("/themes/create")
Call<String> createTheme(@HeaderMap Map<String, String> headers, @Field("name") String themeName,
@Field("data") String customThemeJson);

@FormUrlEncoded
@POST("/themes/upload")
Call<String> uploadTheme(@Field("name") String themeName, @Field("username") String username,
@Field("data") String customThemeJson, @Field("primary_color") String primaryColor);
@POST("/redditUserAuth/refresh_access_token")
Call<String> refreshAccessToken(@Field("username") String username, @Field("refresh_token") String refreshToken);
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,21 @@
import java.util.concurrent.Executor;

import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase;
import ml.docilealligator.infinityforreddit.apis.OnlineCustomThemeAPI;
import ml.docilealligator.infinityforreddit.apis.ServerAPI;
import ml.docilealligator.infinityforreddit.utils.JSONUtils;
import retrofit2.HttpException;
import retrofit2.Response;
import retrofit2.Retrofit;

public class OnlineCustomThemePagingSource extends ListenableFuturePagingSource<String, OnlineCustomThemeMetadata> {
private final Executor executor;
private final OnlineCustomThemeAPI api;
private final ServerAPI api;
private final RedditDataRoomDatabase redditDataRoomDatabase;

public OnlineCustomThemePagingSource(Executor executor, Retrofit onlineCustomThemesRetrofit, RedditDataRoomDatabase redditDataRoomDatabase) {
this.executor = executor;
this.redditDataRoomDatabase = redditDataRoomDatabase;
api = onlineCustomThemesRetrofit.create(OnlineCustomThemeAPI.class);
api = onlineCustomThemesRetrofit.create(ServerAPI.class);
}

@Nullable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,12 +130,6 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic
private static final int EDIT_POST_REQUEST_CODE = 2;
private static final String SCROLL_POSITION_STATE = "SPS";

@Inject
@Named("pushshift")
Retrofit pushshiftRetrofit;
@Inject
@Named("reveddit")
Retrofit revedditRetrofit;
@Inject
@Named("no_oauth")
Retrofit mRetrofit;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,10 @@ public class AccessTokenAuthenticator implements Authenticator {
private final RedditDataRoomDatabase mRedditDataRoomDatabase;
private final SharedPreferences mCurrentAccountSharedPreferences;

public AccessTokenAuthenticator(Retrofit retrofit, RedditDataRoomDatabase accountRoomDatabase, SharedPreferences currentAccountSharedPreferences) {
public AccessTokenAuthenticator(Retrofit retrofit, RedditDataRoomDatabase redditDataRoomDatabase,
SharedPreferences currentAccountSharedPreferences) {
mRetrofit = retrofit;
mRedditDataRoomDatabase = accountRoomDatabase;
mRedditDataRoomDatabase = redditDataRoomDatabase;
mCurrentAccountSharedPreferences = currentAccountSharedPreferences;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package ml.docilealligator.infinityforreddit.network;

import android.content.SharedPreferences;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;

import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase;
import ml.docilealligator.infinityforreddit.account.Account;
import ml.docilealligator.infinityforreddit.apis.ServerAPI;
import ml.docilealligator.infinityforreddit.utils.APIUtils;
import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils;
import okhttp3.Authenticator;
import okhttp3.Headers;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.Route;
import retrofit2.Call;
import retrofit2.Retrofit;
import retrofit2.converter.scalars.ScalarsConverterFactory;

public class ServerAccessTokenAuthenticator implements Authenticator {
private final RedditDataRoomDatabase mRedditDataRoomDatabase;
private final SharedPreferences mCurrentAccountSharedPreferences;

public ServerAccessTokenAuthenticator(RedditDataRoomDatabase redditDataRoomDatabase,
SharedPreferences currentAccountSharedPreferences) {
mRedditDataRoomDatabase = redditDataRoomDatabase;
mCurrentAccountSharedPreferences = currentAccountSharedPreferences;
}

@Nullable
@Override
public Request authenticate(@Nullable Route route, @NonNull Response response) throws IOException {
if (response.code() == 401) {
String accessTokenHeader = response.request().header(APIUtils.AUTHORIZATION_KEY);
if (accessTokenHeader == null) {
return null;
}

String accessToken = accessTokenHeader.substring(APIUtils.AUTHORIZATION_BASE.length());
synchronized (this) {
Account account = mRedditDataRoomDatabase.accountDao().getCurrentAccount();
if (account == null) {
return null;
}
// TODO server access token
String accessTokenFromDatabase = account.getAccessToken();
if (accessToken.equals(accessTokenFromDatabase)) {
String newAccessToken = refreshAccessToken(account);
if (!newAccessToken.isEmpty()) {
return response.request().newBuilder().headers(Headers.of(APIUtils.getOAuthHeader(newAccessToken))).build();
} else {
return null;
}
} else {
return response.request().newBuilder().headers(Headers.of(APIUtils.getOAuthHeader(accessTokenFromDatabase))).build();
}
}
}
return null;
}

private String refreshAccessToken(Account account) {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(APIUtils.SERVER_API_BASE_URI)
.addConverterFactory(ScalarsConverterFactory.create())
.build();

// TODO server refresh token
String refreshToken = mRedditDataRoomDatabase.accountDao().getCurrentAccount().getRefreshToken();

Call<String> accessTokenCall = retrofit.create(ServerAPI.class).refreshAccessToken(account.getAccountName(), refreshToken);
try {
retrofit2.Response<String> response = accessTokenCall.execute();
if (response.isSuccessful() && response.body() != null) {
String newAccessToken = new JSONObject(response.body()).getString(APIUtils.ACCESS_TOKEN_KEY);
mRedditDataRoomDatabase.accountDao().updateAccessToken(account.getAccountName(), newAccessToken);
if (mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCOUNT_NAME, Account.ANONYMOUS_ACCOUNT).equals(account.getAccountName())) {
// TODO server access token
mCurrentAccountSharedPreferences.edit().putString(SharedPreferencesUtils.ACCESS_TOKEN, newAccessToken).apply();
}

return newAccessToken;
}
return "";
} catch (IOException | JSONException e) {
e.printStackTrace();
}

return "";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import java.util.Map;

import ml.docilealligator.infinityforreddit.BuildConfig;
import ml.docilealligator.infinityforreddit.account.Account;
import okhttp3.MediaType;
import okhttp3.RequestBody;

Expand Down Expand Up @@ -49,6 +50,7 @@ public class APIUtils {
public static final String AUTHORIZATION_BASE = "bearer ";
public static final String USER_AGENT_KEY = "User-Agent";
public static final String USER_AGENT = "android:ml.docilealligator.infinityforreddit:" + BuildConfig.VERSION_NAME + " (by /u/Hostilenemy)";
public static final String USERNAME_KEY = "username";

public static final String GRANT_TYPE_KEY = "grant_type";
public static final String GRANT_TYPE_REFRESH_TOKEN = "refresh_token";
Expand Down Expand Up @@ -129,6 +131,17 @@ public static Map<String, String> getOAuthHeader(String accessToken) {
return params;
}

public static Map<String, String> getServerHeader(String serverAccessToken, String accountName, boolean anonymous) {
if (accountName.equals(Account.ANONYMOUS_ACCOUNT) || anonymous) {
return new HashMap<>();
}

Map<String, String> params = new HashMap<>();
params.put(APIUtils.AUTHORIZATION_KEY, APIUtils.AUTHORIZATION_BASE + serverAccessToken);
params.put(APIUtils.USERNAME_KEY, accountName);
return params;
}

public static Map<String, String> getRedgifsOAuthHeader(String redgifsAccessToken) {
Map<String, String> params = new HashMap<>();
params.put(APIUtils.AUTHORIZATION_KEY, APIUtils.AUTHORIZATION_BASE + redgifsAccessToken);
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -980,7 +980,9 @@
<string name="save_theme_options_message">You uploaded this theme so you can make changes.</string>
<string name="save_locally">Save locally</string>
<string name="save_online">Save online</string>
<string name="save_online_anonymous">Save online (anonymously)</string>
<string name="save_locally_and_online">Save both locally and online</string>
<string name="save_locally_and_online_anonymous">Save both locally and online (anonymously)</string>
<string name="theme_saved_locally">Theme saved locally</string>
<string name="theme_saved_online">Theme saved online</string>
<string name="upload_theme_failed">Failed to upload this theme. Try again later.</string>
Expand Down

0 comments on commit 3a9e1df

Please sign in to comment.