ChannelDiscoveryService.java

  1package eu.siacs.conversations.services;
  2
  3import android.support.annotation.NonNull;
  4import android.util.Log;
  5
  6import com.google.common.cache.Cache;
  7import com.google.common.cache.CacheBuilder;
  8
  9import java.io.IOException;
 10import java.util.Collections;
 11import java.util.List;
 12import java.util.concurrent.Executors;
 13import java.util.concurrent.TimeUnit;
 14
 15import eu.siacs.conversations.Config;
 16import eu.siacs.conversations.http.HttpConnectionManager;
 17import eu.siacs.conversations.http.services.MuclumbusService;
 18import okhttp3.OkHttpClient;
 19import retrofit2.Call;
 20import retrofit2.Callback;
 21import retrofit2.Response;
 22import retrofit2.Retrofit;
 23import retrofit2.converter.gson.GsonConverterFactory;
 24
 25public class ChannelDiscoveryService {
 26
 27    private final XmppConnectionService service;
 28
 29
 30    private MuclumbusService muclumbusService;
 31
 32    private final Cache<String, List<MuclumbusService.Room>> cache;
 33
 34    ChannelDiscoveryService(XmppConnectionService service) {
 35        this.service = service;
 36        this.cache = CacheBuilder.newBuilder().expireAfterWrite(5, TimeUnit.MINUTES).build();
 37    }
 38
 39    void initializeMuclumbusService() {
 40        OkHttpClient.Builder builder = new OkHttpClient.Builder();
 41        if (service.useTorToConnect()) {
 42            try {
 43                builder.proxy(HttpConnectionManager.getProxy());
 44            } catch (IOException e) {
 45                throw new RuntimeException("Unable to use Tor proxy", e);
 46            }
 47        }
 48        Retrofit retrofit = new Retrofit.Builder()
 49                .client(builder.build())
 50                .baseUrl(Config.CHANNEL_DISCOVERY)
 51                .addConverterFactory(GsonConverterFactory.create())
 52                .callbackExecutor(Executors.newSingleThreadExecutor())
 53                .build();
 54        this.muclumbusService = retrofit.create(MuclumbusService.class);
 55    }
 56
 57    void discover(String query, OnChannelSearchResultsFound onChannelSearchResultsFound) {
 58        final boolean all = query == null || query.trim().isEmpty();
 59        Log.d(Config.LOGTAG, "discover channels. query=" + query);
 60        List<MuclumbusService.Room> result = cache.getIfPresent(all ? "" : query);
 61        if (result != null) {
 62            onChannelSearchResultsFound.onChannelSearchResultsFound(result);
 63            return;
 64        }
 65        if (all) {
 66            discoverChannels(onChannelSearchResultsFound);
 67        } else {
 68            discoverChannels(query, onChannelSearchResultsFound);
 69        }
 70    }
 71
 72    private void discoverChannels(OnChannelSearchResultsFound listener) {
 73        Call<MuclumbusService.Rooms> call = muclumbusService.getRooms(1);
 74        try {
 75            call.enqueue(new Callback<MuclumbusService.Rooms>() {
 76                @Override
 77                public void onResponse(@NonNull Call<MuclumbusService.Rooms> call, @NonNull Response<MuclumbusService.Rooms> response) {
 78                    final MuclumbusService.Rooms body = response.body();
 79                    if (body == null) {
 80                        Log.d(Config.LOGTAG, "code from muclumbus=" + response.code());
 81                        listener.onChannelSearchResultsFound(Collections.emptyList());
 82                        return;
 83                    }
 84                    cache.put("", body.items);
 85                    listener.onChannelSearchResultsFound(body.items);
 86                }
 87
 88                @Override
 89                public void onFailure(@NonNull Call<MuclumbusService.Rooms> call, @NonNull Throwable throwable) {
 90                    Log.d(Config.LOGTAG, "Unable to query muclumbus on " + Config.CHANNEL_DISCOVERY, throwable);
 91                    listener.onChannelSearchResultsFound(Collections.emptyList());
 92                }
 93            });
 94        } catch (Exception e) {
 95            e.printStackTrace();
 96        }
 97    }
 98
 99    private void discoverChannels(final String query, OnChannelSearchResultsFound listener) {
100        Call<MuclumbusService.SearchResult> searchResultCall = muclumbusService.search(new MuclumbusService.SearchRequest(query));
101
102        searchResultCall.enqueue(new Callback<MuclumbusService.SearchResult>() {
103            @Override
104            public void onResponse(@NonNull Call<MuclumbusService.SearchResult> call, @NonNull Response<MuclumbusService.SearchResult> response) {
105                final MuclumbusService.SearchResult body = response.body();
106                if (body == null) {
107                    Log.d(Config.LOGTAG, "code from muclumbus=" + response.code());
108                    listener.onChannelSearchResultsFound(Collections.emptyList());
109                    return;
110                }
111                cache.put(query, body.result.items);
112                listener.onChannelSearchResultsFound(body.result.items);
113            }
114
115            @Override
116            public void onFailure(@NonNull Call<MuclumbusService.SearchResult> call, @NonNull Throwable throwable) {
117                Log.d(Config.LOGTAG, "Unable to query muclumbus on " + Config.CHANNEL_DISCOVERY, throwable);
118                listener.onChannelSearchResultsFound(Collections.emptyList());
119            }
120        });
121    }
122
123    public interface OnChannelSearchResultsFound {
124        void onChannelSearchResultsFound(List<MuclumbusService.Room> results);
125    }
126}