package com.pr0gramm.statistics.networking; import com.google.gson.Gson; import com.pr0gramm.statistics.api.Item; import com.pr0gramm.statistics.api.Result; import okhttp3.*; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; /** * Created by koray on 27/01/2017. */ public class PostDownloader { private boolean started = false; private boolean finished = false; private OkHttpClient client = new OkHttpClient(); private ArrayList<Item> items = new ArrayList<Item>(); private ArrayList<String> userNames = new ArrayList<String>(); private Gson gson = new Gson(); private PostDownloaderCallback callback; private int limit = -1; private int olderThan = -1; private int newerThan = -1; public PostDownloader() { this(null, -1, -1); } public PostDownloader(PostDownloaderCallback callback) { this(callback, -1, -1); } public PostDownloader(PostDownloaderCallback callback, int limit, int olderThan) { this.callback = callback; this.limit = limit; this.olderThan = olderThan; } public PostDownloader(PostDownloaderCallback callback, int newerThan) { this.callback = callback; this.newerThan = newerThan; } public void startDownloading() throws UnsupportedOperationException { if (started || finished) { throw new UnsupportedOperationException("You can't start the downloader twice!"); } started = true; if (olderThan > 0) { downloadNextStack(Integer.toString(olderThan)); return; } if (newerThan > 0) { downloadNewerStack(Integer.toString(newerThan)); return; } Request.Builder requestBuilder = new Request.Builder(); final String url = "https://pr0gramm.com/api/items/get?flags=7"; requestBuilder.url(url); requestBuilder.get(); Request request = requestBuilder.build(); newCall(request); } private void downloadNextStack(String lastId) { Request.Builder requestBuilder = new Request.Builder(); final String url = "https://pr0gramm.com/api/items/get?flags=7&older=" + lastId; requestBuilder.url(url); requestBuilder.get(); Request request = requestBuilder.build(); newCall(request); } private void downloadNewerStack(String newerThan) { Request.Builder requestBuilder = new Request.Builder(); final String url = "https://pr0gramm.com/api/items/get?flags=7&newer=" + newerThan; requestBuilder.url(url); requestBuilder.get(); Request request = requestBuilder.build(); newCall(request); } private void newCall(final Request request) { client.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { System.out.println("******* FAILURE *******"); e.printStackTrace(); // TODO: There should be a limit... newCall(request); } @Override public void onResponse(Call call, Response response) throws IOException { if (response.code() != 200) { System.out.println("******* NON 200 STATUS CODE *******"); System.out.println(request.url().toString()); System.out.println(response.body().string()); } else { parseResponse(response.body().string()); } } }); } private synchronized void parseResponse(String response) { Result result = gson.fromJson(response, Result.class); Item[] newItems = result.getItems(); if (newItems != null) { for (Item i : newItems) { if (!items.contains(i)) { items.add(i); } if (i.getUser() != null && !userNames.contains(i.getUser())) { userNames.add(i.getUser()); } } items.addAll(Arrays.asList(newItems)); } if (newItems != null && newItems.length > 0 && (newerThan > 0 ? !result.isAtStart() : !result.isAtEnd())) { Item lastItem = newItems[newItems.length - 1]; int lastId = lastItem.getId(); if (limit > 0 && items.size() >= limit) { finishDownloader(); return; } System.out.println("LOADING NEXT STACK! LAST ID WAS: " + lastId); System.out.println("CURRENT ITEM SIZE: " + items.size()); System.out.println("CURRENT USER SIZE: " + userNames.size()); if (newerThan > 0) { // We are downloading into the opposite direction downloadNewerStack(Integer.toString(lastId)); } else { downloadNextStack(Integer.toString(lastId)); } } else { finishDownloader(); } } private synchronized void finishDownloader() { finished = true; if (callback != null) { callback.finishedLoading(items, userNames); } } public boolean isStarted() { return started; } public boolean isFinished() { return finished; } public int getLimit() { return limit; } public void setLimit(int limit) { this.limit = limit; } }