<commit_before>package com.ddiehl.android.htn.io;

import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.TextUtils;

import com.ddiehl.android.htn.AccessTokenManager;
import com.ddiehl.android.htn.AndroidContextProvider;
import com.ddiehl.android.htn.BusProvider;
import com.ddiehl.android.htn.HoldTheNarwhal;
import com.ddiehl.android.htn.analytics.Analytics;
import com.ddiehl.android.htn.events.requests.FriendAddEvent;
import com.ddiehl.android.htn.events.requests.FriendDeleteEvent;
import com.ddiehl.android.htn.events.requests.FriendNoteSaveEvent;
import com.ddiehl.android.htn.events.requests.GetSubredditInfoEvent;
import com.ddiehl.android.htn.events.requests.GetUserIdentityEvent;
import com.ddiehl.android.htn.events.requests.GetUserSettingsEvent;
import com.ddiehl.android.htn.events.requests.HideEvent;
import com.ddiehl.android.htn.events.requests.LoadLinkCommentsEvent;
import com.ddiehl.android.htn.events.requests.LoadMoreChildrenEvent;
import com.ddiehl.android.htn.events.requests.LoadUserProfileListingEvent;
import com.ddiehl.android.htn.events.requests.LoadUserProfileSummaryEvent;
import com.ddiehl.android.htn.events.requests.ReportEvent;
import com.ddiehl.android.htn.events.requests.SaveEvent;
import com.ddiehl.android.htn.events.requests.UpdateUserSettingsEvent;
import com.ddiehl.android.htn.events.requests.VoteEvent;
import com.ddiehl.android.htn.events.responses.FriendAddedEvent;
import com.ddiehl.android.htn.events.responses.FriendDeletedEvent;
import com.ddiehl.android.htn.events.responses.FriendInfoLoadedEvent;
import com.ddiehl.android.htn.events.responses.HideSubmittedEvent;
import com.ddiehl.android.htn.events.responses.LinkCommentsLoadedEvent;
import com.ddiehl.android.htn.events.responses.ListingsLoadedEvent;
import com.ddiehl.android.htn.events.responses.MoreChildrenLoadedEvent;
import com.ddiehl.android.htn.events.responses.SaveSubmittedEvent;
import com.ddiehl.android.htn.events.responses.SubredditInfoLoadedEvent;
import com.ddiehl.android.htn.events.responses.TrophiesLoadedEvent;
import com.ddiehl.android.htn.events.responses.UserIdentityRetrievedEvent;
import com.ddiehl.android.htn.events.responses.UserInfoLoadedEvent;
import com.ddiehl.android.htn.events.responses.UserSettingsRetrievedEvent;
import com.ddiehl.android.htn.events.responses.UserSettingsUpdatedEvent;
import com.ddiehl.android.htn.events.responses.VoteSubmittedEvent;
import com.ddiehl.reddit.Hideable;
import com.ddiehl.reddit.Savable;
import com.ddiehl.reddit.Votable;
import com.ddiehl.reddit.adapters.AbsCommentDeserializer;
import com.ddiehl.reddit.adapters.ListingDeserializer;
import com.ddiehl.reddit.adapters.ListingResponseDeserializer;
import com.ddiehl.reddit.identity.AccessToken;
import com.ddiehl.reddit.identity.Friend;
import com.ddiehl.reddit.identity.UserIdentity;
import com.ddiehl.reddit.listings.AbsComment;
import com.ddiehl.reddit.listings.CommentStub;
import com.ddiehl.reddit.listings.Link;
import com.ddiehl.reddit.listings.Listing;
import com.ddiehl.reddit.listings.ListingResponse;
import com.facebook.stetho.okhttp.StethoInterceptor;
import com.google.gson.FieldNamingPolicy;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.squareup.okhttp.Cache;
import com.squareup.okhttp.MediaType;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.RequestBody;
import com.squareup.otto.Bus;

import java.io.File;
import java.util.List;

import retrofit.GsonConverterFactory;
import retrofit.Response;
import retrofit.Retrofit;
import retrofit.RxJavaCallAdapterFactory;
import rx.Observable;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action1;
import rx.schedulers.Schedulers;

public class RedditServiceAPI implements RedditService {
    private Bus mBus = BusProvider.getInstance();
    private AccessTokenManager mAccessTokenManager = HoldTheNarwhal.getAccessTokenManager();
    private Analytics mAnalytics = HoldTheNarwhal.getAnalytics();
    private RedditAPI mAPI;

    RedditServiceAPI() {
        mAPI = buildApi();
    }

    private RedditAPI buildApi() {
        final int cacheSize = 10 * 1024 * 1024; // 10 MiB
        OkHttpClient client = new OkHttpClient();
        Context context = AndroidContextProvider.getContext();
        File cache = new File(context.getCacheDir().getAbsolutePath(), "htn-http-cache");
        client.setCache(new Cache(cache, cacheSize));
        client.networkInterceptors().add(new RawResponseInterceptor());
        client.networkInterceptors().add((chain) -> {
            Request originalRequest = chain.request();
            Request newRequest = originalRequest.newBuilder()
                    .removeHeader("Authorization")
                    .addHeader("Authorization", "bearer " + mAccessTokenManager.getValidAccessToken())
                    .build();
            return chain.proceed(newRequest);
        });
        client.networkInterceptors().add(new LoggingInterceptor());
        client.networkInterceptors().add(new StethoInterceptor());

        Gson gson = new GsonBuilder()
                .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
                .registerTypeAdapter(ListingResponse.class, new ListingResponseDeserializer())
                .registerTypeAdapter(Listing.class, new ListingDeserializer())
                .registerTypeAdapter(AbsComment.class, new AbsCommentDeserializer())
                .create();

        Retrofit restAdapter = new Retrofit.Builder()
                .client(client)
                .baseUrl(ENDPOINT_AUTHORIZED)
                .addConverterFactory(GsonConverterFactory.create(gson))
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .build();

        return restAdapter.create(RedditAPI.class);
    }

    @Override
    public void onGetUserIdentity(@NonNull GetUserIdentityEvent event) {
        mAPI.getUserIdentity()
                .subscribeOn(Schedulers.io()).unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(
                        response -> {
                            mBus.post(new UserIdentityRetrievedEvent(response.body()));
                            mAnalytics.logSignIn(response.body());
                        },
                        error -> {
                            mBus.post(error);
                            mBus.post(new UserIdentityRetrievedEvent(error));
                        });
    }

    @Override
    public void onGetUserSettings(@NonNull GetUserSettingsEvent event) {
        mAPI.getUserSettings()
                .subscribeOn(Schedulers.io()).unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(
                        response -> mBus.post(new UserSettingsRetrievedEvent(response.body())),
                        error -> {
                            mBus.post(error);
                            mBus.post(new UserSettingsRetrievedEvent(error));
                        });
    }

    @Override
    public void onUpdateUserSettings(@NonNull UpdateUserSettingsEvent event) {
        String json = new Gson().toJson(event.getPrefs());
        mAPI.updateUserSettings(RequestBody.create(MediaType.parse("application/json"), json))
                .subscribeOn(Schedulers.io()).unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(
                        response -> mBus.post(new UserSettingsUpdatedEvent()),
                        error -> {
                            mBus.post(error);
                            mBus.post(new UserSettingsUpdatedEvent(error));
                        });
    }

    private Observable<AccessToken> requireAccessToken() {
        return mAccessTokenManager.getAccessToken();
    }

    @Override
    public Observable<ListingResponse> onLoadLinks(
            @Nullable String subreddit, @Nullable String sort,
            @Nullable String timespan, @Nullable String after) {
        return requireAccessToken().flatMap(accessToken -> Observable.create(
                subscriber -> mAPI.getLinks(sort, subreddit, timespan, after)
                        .subscribeOn(Schedulers.io()).unsubscribeOn(Schedulers.io())
                        .observeOn(AndroidSchedulers.mainThread())
                        .subscribe(response -> subscriber.onNext(response.body()),
                                subscriber::onError)));
    }

    @Override
    public void onLoadLinkComments(@NonNull LoadLinkCommentsEvent event) {
        String subreddit = event.getSubreddit();
        String article = event.getArticle();
        String sort = event.getSort();
        String commentId = event.getCommentId();
        mAPI.getComments(subreddit, article, sort, commentId)
                .subscribeOn(Schedulers.io()).unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(
                        response -> mBus.post(new LinkCommentsLoadedEvent(response.body())),
                        error -> {
                            mBus.post(error);
                            mBus.post(new LinkCommentsLoadedEvent(error));
                        });
    }
<commit_msg>Refactored operators for Observables in RedditServiceAPI<commit_after>package com.ddiehl.android.htn.io;

import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.TextUtils;

import com.ddiehl.android.htn.AccessTokenManager;
import com.ddiehl.android.htn.AndroidContextProvider;
import com.ddiehl.android.htn.BusProvider;
import com.ddiehl.android.htn.HoldTheNarwhal;
import com.ddiehl.android.htn.analytics.Analytics;
import com.ddiehl.android.htn.events.requests.FriendAddEvent;
import com.ddiehl.android.htn.events.requests.FriendDeleteEvent;
import com.ddiehl.android.htn.events.requests.FriendNoteSaveEvent;
import com.ddiehl.android.htn.events.requests.GetSubredditInfoEvent;
import com.ddiehl.android.htn.events.requests.GetUserIdentityEvent;
import com.ddiehl.android.htn.events.requests.GetUserSettingsEvent;
import com.ddiehl.android.htn.events.requests.HideEvent;
import com.ddiehl.android.htn.events.requests.LoadLinkCommentsEvent;
import com.ddiehl.android.htn.events.requests.LoadMoreChildrenEvent;
import com.ddiehl.android.htn.events.requests.LoadUserProfileListingEvent;
import com.ddiehl.android.htn.events.requests.LoadUserProfileSummaryEvent;
import com.ddiehl.android.htn.events.requests.ReportEvent;
import com.ddiehl.android.htn.events.requests.SaveEvent;
import com.ddiehl.android.htn.events.requests.UpdateUserSettingsEvent;
import com.ddiehl.android.htn.events.requests.VoteEvent;
import com.ddiehl.android.htn.events.responses.FriendAddedEvent;
import com.ddiehl.android.htn.events.responses.FriendDeletedEvent;
import com.ddiehl.android.htn.events.responses.FriendInfoLoadedEvent;
import com.ddiehl.android.htn.events.responses.HideSubmittedEvent;
import com.ddiehl.android.htn.events.responses.LinkCommentsLoadedEvent;
import com.ddiehl.android.htn.events.responses.ListingsLoadedEvent;
import com.ddiehl.android.htn.events.responses.MoreChildrenLoadedEvent;
import com.ddiehl.android.htn.events.responses.SaveSubmittedEvent;
import com.ddiehl.android.htn.events.responses.SubredditInfoLoadedEvent;
import com.ddiehl.android.htn.events.responses.TrophiesLoadedEvent;
import com.ddiehl.android.htn.events.responses.UserIdentityRetrievedEvent;
import com.ddiehl.android.htn.events.responses.UserInfoLoadedEvent;
import com.ddiehl.android.htn.events.responses.UserSettingsRetrievedEvent;
import com.ddiehl.android.htn.events.responses.UserSettingsUpdatedEvent;
import com.ddiehl.android.htn.events.responses.VoteSubmittedEvent;
import com.ddiehl.reddit.Hideable;
import com.ddiehl.reddit.Savable;
import com.ddiehl.reddit.Votable;
import com.ddiehl.reddit.adapters.AbsCommentDeserializer;
import com.ddiehl.reddit.adapters.ListingDeserializer;
import com.ddiehl.reddit.adapters.ListingResponseDeserializer;
import com.ddiehl.reddit.identity.AccessToken;
import com.ddiehl.reddit.identity.Friend;
import com.ddiehl.reddit.identity.UserIdentity;
import com.ddiehl.reddit.listings.AbsComment;
import com.ddiehl.reddit.listings.CommentStub;
import com.ddiehl.reddit.listings.Link;
import com.ddiehl.reddit.listings.Listing;
import com.ddiehl.reddit.listings.ListingResponse;
import com.facebook.stetho.okhttp.StethoInterceptor;
import com.google.gson.FieldNamingPolicy;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.squareup.okhttp.Cache;
import com.squareup.okhttp.MediaType;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.RequestBody;
import com.squareup.otto.Bus;

import java.io.File;
import java.util.List;

import retrofit.GsonConverterFactory;
import retrofit.Response;
import retrofit.Retrofit;
import retrofit.RxJavaCallAdapterFactory;
import rx.Observable;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action1;
import rx.schedulers.Schedulers;

public class RedditServiceAPI implements RedditService {
    private Bus mBus = BusProvider.getInstance();
    private AccessTokenManager mAccessTokenManager = HoldTheNarwhal.getAccessTokenManager();
    private Analytics mAnalytics = HoldTheNarwhal.getAnalytics();
    private RedditAPI mAPI;

    RedditServiceAPI() {
        mAPI = buildApi();
    }

    private RedditAPI buildApi() {
        final int cacheSize = 10 * 1024 * 1024; // 10 MiB
        OkHttpClient client = new OkHttpClient();
        Context context = AndroidContextProvider.getContext();
        File cache = new File(context.getCacheDir().getAbsolutePath(), "htn-http-cache");
        client.setCache(new Cache(cache, cacheSize));
        client.networkInterceptors().add(new RawResponseInterceptor());
        client.networkInterceptors().add((chain) -> {
            Request originalRequest = chain.request();
            Request newRequest = originalRequest.newBuilder()
                    .removeHeader("Authorization")
                    .addHeader("Authorization", "bearer " + mAccessTokenManager.getValidAccessToken())
                    .build();
            return chain.proceed(newRequest);
        });
        client.networkInterceptors().add(new LoggingInterceptor());
        client.networkInterceptors().add(new StethoInterceptor());

        Gson gson = new GsonBuilder()
                .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
                .registerTypeAdapter(ListingResponse.class, new ListingResponseDeserializer())
                .registerTypeAdapter(Listing.class, new ListingDeserializer())
                .registerTypeAdapter(AbsComment.class, new AbsCommentDeserializer())
                .create();

        Retrofit restAdapter = new Retrofit.Builder()
                .client(client)
                .baseUrl(ENDPOINT_AUTHORIZED)
                .addConverterFactory(GsonConverterFactory.create(gson))
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .build();

        return restAdapter.create(RedditAPI.class);
    }

    @Override
    public void onGetUserIdentity(@NonNull GetUserIdentityEvent event) {
        mAPI.getUserIdentity()
                .subscribeOn(Schedulers.io()).unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(
                        response -> {
                            mBus.post(new UserIdentityRetrievedEvent(response.body()));
                            mAnalytics.logSignIn(response.body());
                        },
                        error -> {
                            mBus.post(error);
                            mBus.post(new UserIdentityRetrievedEvent(error));
                        });
    }

    @Override
    public void onGetUserSettings(@NonNull GetUserSettingsEvent event) {
        mAPI.getUserSettings()
                .subscribeOn(Schedulers.io()).unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(
                        response -> mBus.post(new UserSettingsRetrievedEvent(response.body())),
                        error -> {
                            mBus.post(error);
                            mBus.post(new UserSettingsRetrievedEvent(error));
                        });
    }

    @Override
    public void onUpdateUserSettings(@NonNull UpdateUserSettingsEvent event) {
        String json = new Gson().toJson(event.getPrefs());
        mAPI.updateUserSettings(RequestBody.create(MediaType.parse("application/json"), json))
                .subscribeOn(Schedulers.io()).unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(
                        response -> mBus.post(new UserSettingsUpdatedEvent()),
                        error -> {
                            mBus.post(error);
                            mBus.post(new UserSettingsUpdatedEvent(error));
                        });
    }

    private Observable<AccessToken> requireAccessToken() {
        return mAccessTokenManager.getAccessToken();
    }

    @Override
    public Observable<ListingResponse> onLoadLinks(
            @Nullable String subreddit, @Nullable String sort,
            @Nullable String timespan, @Nullable String after) {
        return requireAccessToken().concatMap(token ->
                mAPI.getLinks(sort, subreddit, timespan, after)
                        .subscribeOn(Schedulers.io()).unsubscribeOn(Schedulers.io())
                        .observeOn(AndroidSchedulers.mainThread())
                        .map(Response::body));
    }

    @Override
    public void onLoadLinkComments(@NonNull LoadLinkCommentsEvent event) {
        String subreddit = event.getSubreddit();
        String article = event.getArticle();
        String sort = event.getSort();
        String commentId = event.getCommentId();
        mAPI.getComments(subreddit, article, sort, commentId)
                .subscribeOn(Schedulers.io()).unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(
                        response -> mBus.post(new LinkCommentsLoadedEvent(response.body())),
                        error -> {
                            mBus.post(error);
                            mBus.post(new LinkCommentsLoadedEvent(error));
                        });
    }

{'fraction_non_alphanumeric': 0.09990404094253119, 'fraction_numerical': 0.0013860752745495255, 'mean_word_length': 2.98534098151689, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6345771', 'n_tokens_mistral': 5337, 'n_tokens_neox': 5214, 'n_words': 733}