com.tanmay.blip.networking.XKCDDownloader.java Source code

Java tutorial

Introduction

Here is the source code for com.tanmay.blip.networking.XKCDDownloader.java

Source

/*
 * Copyright 2015, Tanmay Parikh
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.tanmay.blip.networking;

import android.app.IntentService;
import android.content.Intent;
import android.support.v4.content.LocalBroadcastManager;

import com.crashlytics.android.Crashlytics;
import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;
import com.tanmay.blip.BlipApplication;
import com.tanmay.blip.database.DatabaseManager;
import com.tanmay.blip.database.SharedPrefs;
import com.tanmay.blip.models.Comic;

import java.io.IOException;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

public class XKCDDownloader extends IntentService {

    public static final String LATEST_URL = "http://xkcd.com/info.0.json";
    public static final String COMICS_URL = "http://xkcd.com/%d/info.0.json";

    public static final String DOWNLOAD_PROGRESS = "com.tanmay.blip.DOWNLOAD_PROGRESS";
    public static final String DOWNLOAD_SUCCESS = "com.tanmay.blip.DOWNLOAD_SUCCESS";
    public static final String DOWNLOAD_FAIL = "com.tanmay.blip.DOWNLOAD_FAIL";

    public static final String DOWNLOAD_TODAY = "com.tanmay.blip.DOWNLOAD_TODAY";
    public static final String DOWNLOAD_ALL = "com.tanmay.blip.DOWNLOAD_ALL";
    public static final String DOWNLOAD_SPECIFIC = "com.tanmay.blip.DOWNLOAD_SPECIFIC";
    public static final String DOWNLOAD_TRANSCRIPT = "com.tanmay.blip.DOWNLOAD_TRANSCRIPT";
    public static final String DOWNLOAD_LAST_TEN = "com.tanmay.blip.DOWNLOAD_LAST_TEN";

    public static final String COMIC_NUM = "comicNum";
    public static final String PROGRESS = "progress";
    public static final String TITLE = "title";

    public XKCDDownloader() {
        super("XKCDDownloaderService");
    }

    public XKCDDownloader(String name) {
        super(name);
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        switch (intent.getAction()) {
        case DOWNLOAD_TODAY:
            downloadToday();
            break;
        case DOWNLOAD_ALL:
            downloadAll();
            break;
        case DOWNLOAD_SPECIFIC:
            downloadSpecific(intent.getExtras().getInt(COMIC_NUM));
            break;
        case DOWNLOAD_TRANSCRIPT:
            downloadAllMissingTranscripts();
            break;
        case DOWNLOAD_LAST_TEN:
            redownloadLastTen();
        }
    }

    private void downloadSpecific(int i) {
        Gson gson = new Gson();
        DatabaseManager databaseManager = new DatabaseManager(this);
        String url = String.format(COMICS_URL, i);
        Request request = new Request.Builder().url(url).build();
        try {
            Response response = BlipApplication.getInstance().client.newCall(request).execute();
            if (!response.isSuccessful())
                throw new IOException();
            Comic comic = gson.fromJson(response.body().string(), Comic.class);
            databaseManager.addComic(comic);
            LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent(DOWNLOAD_SUCCESS));
        } catch (IOException e) {
            e.printStackTrace();
            LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent(DOWNLOAD_FAIL));
        }
    }

    private void downloadToday() {
        DatabaseManager databaseManager = new DatabaseManager(this);
        Gson gson = new Gson();
        Request request = new Request.Builder().url(LATEST_URL).build();
        try {
            Response response = BlipApplication.getInstance().client.newCall(request).execute();
            if (!response.isSuccessful())
                throw new IOException();
            Comic comic = gson.fromJson(response.body().string(), Comic.class);
            if (!databaseManager.comicExists(comic))
                databaseManager.addComic(comic);
            LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent(DOWNLOAD_SUCCESS));
        } catch (IOException e) {
            e.printStackTrace();
            LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent(DOWNLOAD_FAIL));
        }
    }

    private void redownloadLastTen() {
        final Gson gson = new Gson();
        final DatabaseManager databaseManager = new DatabaseManager(this);
        try {
            Request todayReq = new Request.Builder().url(LATEST_URL).build();
            Response response = BlipApplication.getInstance().client.newCall(todayReq).execute();
            if (!response.isSuccessful())
                throw new IOException();
            Comic comic = gson.fromJson(response.body().string(), Comic.class);
            final CountDownLatch latch = new CountDownLatch(10);
            final Executor executor = Executors.newFixedThreadPool(5);
            int num = comic.getNum();
            for (int i = num - 9; i <= num; i++) {
                final int index = i;
                executor.execute(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            String url = String.format(COMICS_URL, index);
                            Request request = new Request.Builder().url(url).build();
                            Response response = BlipApplication.getInstance().client.newCall(request).execute();
                            if (!response.isSuccessful())
                                throw new IOException();
                            String responseBody = response.body().string();
                            Comic comic = null;
                            try {
                                comic = gson.fromJson(responseBody, Comic.class);
                            } catch (JsonSyntaxException e) {
                                Crashlytics.log(1, "XKCDDownloader", e.getMessage() + " POS:" + index);
                            }
                            if (comic != null) {
                                if (databaseManager.comicExists(comic)) {
                                    databaseManager.updateComic(comic);
                                } else {
                                    databaseManager.addComic(comic);
                                }
                            }
                        } catch (IOException e) {
                            e.printStackTrace();
                            LocalBroadcastManager.getInstance(XKCDDownloader.this)
                                    .sendBroadcast(new Intent(DOWNLOAD_FAIL));
                        } finally {
                            latch.countDown();
                        }
                    }
                });
            }

            try {
                latch.await();
            } catch (InterruptedException e) {
                LocalBroadcastManager.getInstance(XKCDDownloader.this).sendBroadcast(new Intent(DOWNLOAD_FAIL));
            }

            SharedPrefs.getInstance().setLastRedownladTime(System.currentTimeMillis());
            LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent(DOWNLOAD_SUCCESS));

        } catch (IOException e) {
            LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent(DOWNLOAD_FAIL));
        }
    }

    private void downloadAllMissingTranscripts() {
        final Gson gson = new Gson();
        final DatabaseManager databaseManager = new DatabaseManager(this);
        List<Integer> nums = databaseManager.getAllMissingTranscripts();

        final CountDownLatch latch = new CountDownLatch(nums.size());
        final Executor executor = Executors.newFixedThreadPool(nums.size() / 2);
        for (int i : nums) {
            final int index = i;
            executor.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        String url = String.format(COMICS_URL, index);
                        Request request = new Request.Builder().url(url).build();
                        Response response = BlipApplication.getInstance().client.newCall(request).execute();
                        if (!response.isSuccessful())
                            throw new IOException();
                        String responseBody = response.body().string();
                        Comic comic = null;
                        try {
                            comic = gson.fromJson(responseBody, Comic.class);
                        } catch (JsonSyntaxException e) {
                            Crashlytics.log(1, "XKCDDownloader", e.getMessage() + " POS:" + index);
                        }
                        if (comic != null) {
                            databaseManager.updateComic(comic);
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                        LocalBroadcastManager.getInstance(XKCDDownloader.this)
                                .sendBroadcast(new Intent(DOWNLOAD_FAIL));
                    } finally {
                        latch.countDown();
                    }
                }
            });
        }

        try {
            latch.await();
        } catch (InterruptedException e) {
            LocalBroadcastManager.getInstance(XKCDDownloader.this).sendBroadcast(new Intent(DOWNLOAD_FAIL));
        }
        SharedPrefs.getInstance().setLastTranscriptCheckTime(System.currentTimeMillis());
        LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent(DOWNLOAD_SUCCESS));

    }

    private void downloadAll() {
        final Gson gson = new Gson();
        final DatabaseManager databaseManager = new DatabaseManager(this);
        Request request = new Request.Builder().url(LATEST_URL).build();
        try {
            final Response response = BlipApplication.getInstance().client.newCall(request).execute();
            if (!response.isSuccessful())
                throw new IOException();
            Comic comic = gson.fromJson(response.body().string(), Comic.class);

            final int num = comic.getNum();
            final CountDownLatch latch = new CountDownLatch(num);
            final Executor executor = Executors.newFixedThreadPool(10);

            for (int i = 1; i <= num; i++) {
                final int index = i;
                executor.execute(new Runnable() {

                    @Override
                    public void run() {
                        try {
                            if (index != 404) {
                                String url = String.format(COMICS_URL, index);
                                Request newReq = new Request.Builder().url(url).build();
                                Response newResp = BlipApplication.getInstance().client.newCall(newReq).execute();
                                if (!newResp.isSuccessful())
                                    throw new IOException();
                                String resp = newResp.body().string();
                                Comic comic1 = null;
                                try {
                                    comic1 = gson.fromJson(resp, Comic.class);
                                } catch (JsonSyntaxException e) {
                                    Crashlytics.log(1, "XKCDDownloader", e.getMessage() + " POS:" + index);
                                }
                                if (comic1 != null) {
                                    databaseManager.addComic(comic1);
                                    double progress = ((double) databaseManager.getCount() / num) * 100;
                                    Intent intent = new Intent(DOWNLOAD_PROGRESS);
                                    intent.putExtra(PROGRESS, progress);
                                    intent.putExtra(TITLE, comic1.getTitle());
                                    LocalBroadcastManager.getInstance(XKCDDownloader.this).sendBroadcast(intent);
                                }
                            }
                        } catch (IOException e) {
                            e.printStackTrace();
                            LocalBroadcastManager.getInstance(XKCDDownloader.this)
                                    .sendBroadcast(new Intent(DOWNLOAD_FAIL));
                        } finally {
                            latch.countDown();
                        }
                    }
                });
            }

            try {
                latch.await();
            } catch (InterruptedException e) {
                throw new IOException(e);
            }

            LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent(DOWNLOAD_SUCCESS));
        } catch (IOException e) {
            e.printStackTrace();
            LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent(DOWNLOAD_FAIL));
        }
    }

}