ChannelDiscoveryService.java

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