package com.pr0gramm.statistics.networking; import com.google.gson.Gson; import com.pr0gramm.statistics.Main; import com.pr0gramm.statistics.api.User; import okhttp3.*; import java.io.IOException; import java.util.ArrayList; import java.util.LinkedList; import java.util.logging.Level; /** * Created by koray on 28/01/2017. */ public class UserDownloader { private boolean started = false; private boolean finished = false; private OkHttpClient client = new OkHttpClient(); private ArrayList<User> users = new ArrayList<User>(); private LinkedList<String> userNames = new LinkedList<String>(); private Gson gson = new Gson(); private UserDownloaderCallback callback; private int limit; private int enqueuedRequests = 0; private int finishedRequests = 0; public UserDownloader(ArrayList<String> userNames) { this(userNames, null, -1); } public UserDownloader(ArrayList<String> userNames, UserDownloaderCallback callback) { this(userNames, callback, -1); } public UserDownloader(ArrayList<String> userNames, UserDownloaderCallback callback, int limit) { this.userNames = new LinkedList<String>(userNames); this.callback = callback; this.limit = limit; this.enqueuedRequests = this.userNames.size(); } public void startDownloading() throws UnsupportedOperationException { if (started || finished) { throw new UnsupportedOperationException("You can't start the downloader twice!"); } started = true; Request.Builder requestBuilder = new Request.Builder(); downloadNextUser(); } private void downloadNextUser() { Request.Builder requestBuilder = new Request.Builder(); String name = userNames.poll(); if (name == null) { return; } /* if (name == null) { finishDownloader(); return; } */ final String url = "https://pr0gramm.com/api/profile/info?name=" + name; requestBuilder.url(url); requestBuilder.get(); Request request = requestBuilder.build(); newCall(request); new java.util.Timer().schedule( new java.util.TimerTask() { @Override public void run() { downloadNextUser(); } }, 20 ); } private void newCall(final Request request) { // enqueuedRequests++; client.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { Main.getLogger().log(Level.WARNING, "******* 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) { Main.getLogger().log(Level.WARNING, "******* NON 200 STATUS CODE *******"); Main.getLogger().log(Level.WARNING, request.url().toString()); Main.getLogger().log(Level.WARNING, response.body().string()); addFinishedRequest(); finishIfFinished(); } else { addFinishedRequest(); parseResponse(response.body().string()); finishIfFinished(); } } }); } private synchronized void addFinishedRequest() { finishedRequests++; } private synchronized void finishIfFinished() { if (finishedRequests >= enqueuedRequests) { finishDownloader(); } } private synchronized void parseResponse(String response) { User user = gson.fromJson(response, User.class); if (user != null && user.getUser() != null) { users.add(user); Main.getLogger().log(Level.INFO, "NEXT USER DOWNLOADED: " + user.getUser().getName()); } } private synchronized void finishDownloader() { finished = true; if (callback != null) { callback.finishedLoading(users); } } public boolean isStarted() { return started; } public boolean isFinished() { return finished; } }