net.qvex.dommel.data.DommelDataService.java Source code

Java tutorial

Introduction

Here is the source code for net.qvex.dommel.data.DommelDataService.java

Source

/*
 * This file is part of Dommel Monitor.
 *
 * Dommel Monitor is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Dommel Monitor is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Dommel Monitor. If not, see <http://www.gnu.org/licenses/>.
 * 
 * @author Dirk Van Haerenborgh (vhdirk)
 * 
 * Note:
 *   Big parts of this file originate from Mobile Vikings for Android by
 *   Lorenzo Bernardi and Ben Van Daele (redmine.djzio.be/projects/mvfa)
 * 
 *   Parsing the Dommel webpage is inspired by phptemeler by Jan De Luyck
 *   (phptelemeter.kcore.org)
 * 
 */

package net.qvex.dommel.data;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.HTTP;

import android.app.AlarmManager;
import android.app.IntentService;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.os.IBinder;
import android.os.ResultReceiver;
import android.os.SystemClock;
import android.preference.PreferenceManager;
import android.util.Log;

public class DommelDataService extends IntentService {
    // Android Intent actions

    public static final String MESSAGE_STATUS = "net.qvex.dommel.data.Message.Status";

    public static final String FIELD_EXCEPTION = "net.qvex.dommel.data.Field.Exception";
    public static final String FIELD_STATUS = "net.qvex.dommel.data.Field.Status";
    public static final String FIELD_MANUAL = "net.qvex.dommel.data.Field.Update";

    public static final int STATUS_RUNNING = 1;
    public static final int STATUS_FINISHED = 2;
    public static final int STATUS_ERROR = -1;

    // Dommel provider info
    private static final String URL_LOGIN = "https://crm.schedom-europe.net/index.php";
    private static final String URL_PACKAGES = "https://crm.schedom-europe.net/user.php?op=view&tile=mypackages";
    private static final String URL_STATS_INIT = "https://crm.schedom-europe.net/include/scripts/linked/dslinfo/dslinfo.php";
    private static final String URL_LOGOUT = "https://crm.schedom-europe.net/index.php?op=logout";
    private static final String USER_AGENT = "Mozilla/5.0 (Linux; U; Android 2.3; en-gb) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1";
    private DefaultHttpClient httpclient;

    //
    private float volume_used;
    private float volume_remaining;
    private float volume_total;
    private boolean unlimited;
    private int days_left;
    private Calendar reset_date;
    private SharedPreferences prefs;

    /**
     * A constructor is required, and must call the super IntentService(String)
     * constructor with a name for the worker thread.
     */
    public DommelDataService() {
        super("DommelDataService");

        this.volume_used = -1;
        this.volume_remaining = -1;
        this.unlimited = false;
        this.days_left = -1;
        this.reset_date = Calendar.getInstance();
    }

    /**
     * Does the actual work.
     */

    @Override
    protected void onHandleIntent(Intent intent) {
        String action = intent.getAction();

        prefs = PreferenceManager.getDefaultSharedPreferences(this);

        final boolean manualUpdate = intent.getBooleanExtra(FIELD_MANUAL, false);

        // send broadcast containing error message
        Intent i = new Intent(MESSAGE_STATUS);
        i.putExtra(FIELD_MANUAL, manualUpdate);

        try {
            i.putExtra(FIELD_STATUS, STATUS_RUNNING);
            sendBroadcast(i);

            update();

            i.putExtra(FIELD_STATUS, STATUS_FINISHED);
            sendBroadcast(i);

        } catch (Exception e) {

        }

    }

    /**
     * The IntentService calls this method from the default worker thread with
     * the intent that started the service. When this method returns,
     * IntentService stops the service, as appropriate.
     */
    protected void update() {
        prefs = PreferenceManager.getDefaultSharedPreferences(this);
        String username = prefs.getString("username", null);
        String password = prefs.getString("password", null);

        this.httpclient = new DefaultHttpClient();

        // store the result in the sharedpreferences

        try {
            // first check for internet connectivity

            @SuppressWarnings("unused")
            boolean success = getData(username, password);
            // TODO: what if this is not successful

            // When HttpClient instance is no longer needed,
            // shut down the connection manager to ensure
            // immediate deallocation of all system resources
            this.httpclient.getConnectionManager().shutdown();

            // send broadcast that everything succeeded
            //            sendBroadcast(usageBroadcast);

        } catch (ClientProtocolException e) {
            this.handleError(e);
            //System.out.println(e.toString());
        } catch (IOException e) {
            this.handleError(e);
            //System.out.println(e.toString());
        } catch (Exception e) {
            this.handleError(e);
            //System.out.println(e.toString());
        }

    }

    public boolean getData(String username, String password) throws ClientProtocolException, IOException {

        // adapted from phptelemeter
        unlimited = false;

        /* login */
        Map<String, String> urlParameters = new HashMap<String, String>();
        urlParameters.put("op", "login");
        urlParameters.put("new_language", "english");
        urlParameters.put("submit", "login");
        urlParameters.put("username", username);
        urlParameters.put("password", password);

        String res;

        //        try{
        res = this.httpPost(URL_LOGIN, urlParameters);
        //
        //        }catch(Exception e)
        //        {
        //        // TODO: check for errors in res. possibly just catch nullpointer
        //        // exception..
        //            throw new Exception(e);
        //        }

        /* go to the packages page, and get the serv_id and client_id */
        res = this.httpGet(URL_PACKAGES);
        // TODO: check for errors in res

        String[] lines = res.split("\n");
        String log = null;
        int pos = 0;
        /* figure out the stats exact url */
        for (int i = 0; i < lines.length; i++) {
            pos = lines[i].indexOf(URL_STATS_INIT);
            if (pos >= 0) {
                log = lines[i].substring(pos);
                break;
            }
        }

        String url_stats = log.substring(0, log.indexOf("'"));

        /* and get the data */
        String data = this.httpGet(url_stats);

        /* logout */
        res = this.httpGet(URL_LOGOUT);

        lines = data.split("/n");
        String data2 = null;
        pos = 0;

        /* find the entry position */
        for (int i = 0; i < lines.length; i++) {
            pos = lines[i].indexOf("total traffic downloaded in broadband");
            if (pos >= 0) {
                data2 = lines[i].substring(pos);
                break;
            }
        }

        lines = data2.split("<br>");

        /* set some default positions */
        int pos_remaining = -1;
        int pos_traffic = -1;
        int pos_reset_date = -1;
        int pos_total = -1;
        @SuppressWarnings("unused")
        int strpos_total = -1;

        /* position finding & data cleanup */
        for (int i = 0; i < lines.length; i++) {
            lines[i] = stripTags(lines[i]);

            //System.out.println(lines[i]);

            if (lines[i].contains("total traffic downloaded")) {
                pos_traffic = i;
            } else if (lines[i].contains("next counter reset")) {
                pos_reset_date = i;
            } else if (lines[i].contains("remaining")) {
                pos_remaining = i;
                if (lines[i].contains("unlimited")) {
                    unlimited = true;
                }
            } else if (lines[i].contains("maximum datatransfer")) {
                pos_total = i;
                /* data cleanup */
                int test_ind = lines[i].indexOf("maximum datatransfer:");
                if (test_ind >= 0 && test_ind + 1 < lines[i].length()) {
                    lines[i] = lines[i].substring(test_ind + 21);
                }
            }

            /* data cleanup */
            int test_ind = lines[i].indexOf(":");
            if (test_ind >= 0 && test_ind + 1 < lines[i].length()) {
                lines[i] = lines[i].substring(test_ind + 2);
            }

        }

        /* stats */
        /* total used */
        volume_used = Float.parseFloat(lines[pos_traffic].substring(0, lines[pos_traffic].length() - 3)) * 1024;

        volume_remaining = 0;

        /* remaining, if exists? */
        if (pos_remaining >= 0) {
            if (!unlimited) {
                volume_remaining = Float
                        .parseFloat(lines[pos_remaining].substring(0, lines[pos_remaining].length() - 3)) * 1024;

                if (pos_total >= 0) {
                    volume_total = Float.parseFloat(lines[pos_total].substring(0, 4)) * 1024;
                }
            } else {
                // Unlimited account
                volume_remaining = Float.POSITIVE_INFINITY;
            }
        }

        /* reset date */
        String reset_date_str = lines[pos_reset_date].substring(0, 10);
        DateFormat df = new SimpleDateFormat("dd/MM/yyyy");
        try {
            reset_date.setTime(df.parse(reset_date_str));
        } catch (ParseException e) {
            e.printStackTrace();
            // TODO: handle error
            return false;
        }

        days_left = calculateDaysLeft(reset_date);

        Date now = new Date();

        Editor edit = prefs.edit();
        edit.putFloat("volume_used", volume_used);
        edit.putFloat("volume_remaining", volume_remaining);
        edit.putFloat("volume_total", volume_total);
        edit.putLong("reset_date", reset_date.getTimeInMillis());
        edit.putInt("days_left", days_left);
        edit.putBoolean("unlimited", unlimited);
        edit.putLong("last_update", now.getTime());
        edit.putBoolean("last_update_success", true);

        return edit.commit();

    }

    private String httpGet(String targetURL) throws ClientProtocolException, IOException {
        return executeHttp(targetURL, new HashMap<String, String>(), 0);
    }

    private String httpPost(String targetURL, Map<String, String> urlParameters)
            throws ClientProtocolException, IOException {
        return executeHttp(targetURL, urlParameters, 1);
    }

    private String executeHttp(String targetURL, Map<String, String> urlParameters, int method)
            throws ClientProtocolException, IOException {

        List<NameValuePair> nvps = new ArrayList<NameValuePair>();
        Iterator<Map.Entry<String, String>> it = urlParameters.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry<String, String> pairs = (Map.Entry<String, String>) it.next();
            nvps.add(new BasicNameValuePair((String) pairs.getKey(), (String) pairs.getValue()));
        }
        HttpResponse response = null;
        if (method == 1) {

            HttpPost httpost = new HttpPost(targetURL);
            httpost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
            response = httpclient.execute(httpost);

        } else {

            HttpGet httpget = new HttpGet(targetURL);
            response = httpclient.execute(httpget);

        }

        HttpEntity entity = response.getEntity();

        InputStream is = entity.getContent();
        BufferedReader rd = new BufferedReader(new InputStreamReader(is));
        String line;
        StringBuilder resp = new StringBuilder();
        while ((line = rd.readLine()) != null) {
            resp.append(line);
            resp.append('\n');
        }
        rd.close();

        is.close();

        return resp.toString();
    }

    public void handleError(Exception e) {
        Date now = new Date();

        Editor edit = prefs.edit();
        edit.putLong("last_update", now.getTime());
        edit.putBoolean("last_update_success", false);
        edit.commit();

        // send broadcast containing error message
        Intent i = new Intent(MESSAGE_STATUS);
        i.putExtra(FIELD_STATUS, STATUS_ERROR);
        i.putExtra(FIELD_EXCEPTION, e);
        sendBroadcast(i);
    }

    public static String stripTags(String text) {
        return text.replaceAll("\\<.*?\\>", "");
    }

    public static int calculateDaysLeft(Calendar reset_date) {
        Calendar today = Calendar.getInstance();
        return daysBetween(today, reset_date);
    }

    public static int daysBetween(Calendar startCal, Calendar endCal) {

        Calendar date = (Calendar) startCal.clone();
        int daysBetween = 0;
        while (date.before(endCal)) {
            date.add(Calendar.DAY_OF_MONTH, 1);
            daysBetween++;
        }
        return daysBetween;
    }

    //
    // public boolean isOnline() {
    // ConnectivityManager cm = (ConnectivityManager)
    // getSystemService(Context.CONNECTIVITY_SERVICE);
    // NetworkInfo netInfo = cm.getActiveNetworkInfo();
    // if (netInfo != null && netInfo.isConnectedOrConnecting()) {
    // return true;
    // }
    // return false;
    // }

    public boolean getDebug() {
        return prefs.getBoolean("set_debug", false);
    }

}

//public class InvalidCredentialsException extends java.lang.Exception
//{
//    public InvalidCredentialsException(){
//    }
//
//}