package com.airlocksoftware.hackernews.loader; import java.io.IOException; import org.jsoup.Connection; import org.jsoup.Connection.Method; import org.jsoup.nodes.Document; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.os.AsyncTask; import com.airlocksoftware.hackernews.cache.DbHelperSingleton; import com.airlocksoftware.hackernews.data.ConnectionManager; import com.airlocksoftware.hackernews.data.UserPrefs; import com.airlocksoftware.hackernews.model.Vote; /** * When the user performs a vote, it gets added to the Votes table and this service attempts to run. If successful, it * removes the vote from the queue. Otherwise it leaves it there to run in the future. **/ public class AsyncVotingService extends AsyncTask<Void, Void, Void> { private static final String BAD_UPVOTE_RESPONSE = "Can't make that vote."; private Context mApplicationContext; public AsyncVotingService(Context applicationContext) { mApplicationContext = applicationContext; } @Override protected Void doInBackground(Void... empty) { UserPrefs prefs = new UserPrefs(mApplicationContext); SQLiteDatabase db = DbHelperSingleton.getInstance(mApplicationContext) .getWritableDatabase(); Cursor c = db.rawQuery("SELECT * FROM " + new Vote().getTableName(), null); if (c.moveToFirst()) { for (int i = 0; i < c.getCount(); i++) { Vote vote = new Vote(); vote.readFromCursor(c); if (upvote(vote, prefs.getUserCookie())) { // if successful, remove vote from queue vote.delete(db); // TODO if a vote has already happened, response is the same } c.moveToNext(); } } c.close(); return null; } @Override protected void onCancelled(Void empty) { } private boolean upvote(Vote vote, String cookie) { String voteUrl = getVoteUrl(vote); Connection connection = ConnectionManager.authConnect(voteUrl, cookie); try { Connection.Response response = getResponse(connection); if (response.statusCode() == 200) { if (response.body() != null) return true; Document doc = response.parse(); String text = doc.text(); return !text.equals(BAD_UPVOTE_RESPONSE); } } catch (IOException e) { e.printStackTrace(); } return false; } private Connection.Response getResponse(Connection connection) throws IOException { return connection.method(Method.GET) .timeout(ConnectionManager.TIMEOUT_MILLIS) .execute(); } private String getVoteUrl(Vote vote) { return "/vote?for=" + Long.toString(vote.itemId) + "&dir=up&by=" + vote.username + "&auth=" + vote.auth + "&go_to=" + vote.whence; } }