com.rothconsulting.android.websms.connector.orange.ConnectorOrange.java Source code

Java tutorial

Introduction

Here is the source code for com.rothconsulting.android.websms.connector.orange.ConnectorOrange.java

Source

/*
 * Copyright (C) 2010 Koni
 * 
 * This file is only usefull as part of WebSMS.
 * 
 * This program 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.
 * 
 * This program 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
 * this program; If not, see <http://www.gnu.org/licenses/>.
 */
package com.rothconsulting.android.websms.connector.orange;

import java.net.HttpURLConnection;
import java.util.ArrayList;

import org.apache.http.HttpResponse;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.message.BasicNameValuePair;

import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.util.Log;
import android.widget.Toast;

import com.google.analytics.tracking.android.GoogleAnalytics;
import com.google.analytics.tracking.android.Tracker;

import de.ub0r.android.websms.connector.common.Connector;
import de.ub0r.android.websms.connector.common.ConnectorCommand;
import de.ub0r.android.websms.connector.common.ConnectorSpec;
import de.ub0r.android.websms.connector.common.ConnectorSpec.SubConnectorSpec;
import de.ub0r.android.websms.connector.common.Utils;
import de.ub0r.android.websms.connector.common.Utils.HttpOptions;
import de.ub0r.android.websms.connector.common.WebSMSException;

/**
 * AsyncTask to manage IO to Orange.ch API.
 * 
 * @author koni
 */
public class ConnectorOrange extends Connector {
    /** Tag for output. */
    private static final String TAG = "Orange";
    /** Dummy String */
    private static final String DUMMY = "???";
    /** Entrance URL */
    private static final String URL_LOGIN_STARTUP = "https://my.orange.ch/idmp/UI/Login?realm=my.orange.ch";
    /** Login URL */
    private static final String URL_LOGIN_ACTION = "https://my.orange.ch/idmp/UI/Login";
    /** SMS Composer -> get SMS credit */
    // private static final String URL_DASHBOARD = "https://my.orange.ch/de/dashboard";
    private static final String URL_SMS_COMPOSER_BALANCE = "https://my.orange.ch/de/messaging/sms-composer/ph";
    /** Dashboard -> get prepay credit */
    private static final String URL_PREPAY_CREDIT = "https://my.orange.ch/de/dashboard/content/prepay/usage";
    /** SMS URL */
    private static final String URL_SENDSMS = "https://my.orange.ch/de/messaging/sms-composer.content";
    /** Prepay Credit */
    private String PREPAY_CREDIT = "";
    /** SMS Credit */
    private String SENT_SMS = DUMMY;
    /** SMS form(token) */
    private String SMS_FORM_TOKEN = "";
    /** HTTP User agent. */
    private static final String USER_AGENT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:24.0) Gecko/20100101 Firefox/24.0";
    /** SMS Encoding */
    private static final String ENCODING = "UTF-8";
    /** Check whether this connector is bootstrapping. */
    private static boolean inBootstrap = false;
    /** The secret login token from parsing the http response */
    private String LOGIN_TOKEN = DUMMY;
    /** My Ad-ID */
    private static final String AD_UNITID = "a14ed1536d6c700";
    /** My Analytics-ID */
    private static final String ANALYTICS_ID = "UA-38114228-3";

    private Tracker mGaTracker;
    private GoogleAnalytics mGaInstance;

    /**
     * {@inheritDoc}
     */
    @Override
    public final ConnectorSpec initSpec(final Context context) {
        final String name = context.getString(R.string.connector_orange_name);
        ConnectorSpec c = new ConnectorSpec(name);
        c.setAuthor(context.getString(R.string.connector_orange_author));
        c.setBalance(null);
        c.setLimitLength(140);
        c.setAdUnitId(AD_UNITID);
        c.setCapabilities(ConnectorSpec.CAPABILITIES_BOOTSTRAP | ConnectorSpec.CAPABILITIES_UPDATE
                | ConnectorSpec.CAPABILITIES_SEND | ConnectorSpec.CAPABILITIES_PREFS);
        c.addSubConnector("orange", c.getName(), SubConnectorSpec.FEATURE_MULTIRECIPIENTS);
        return c;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public final ConnectorSpec updateSpec(final Context context, final ConnectorSpec connectorSpec) {
        this.log("************************************************");
        this.log("*** Start updateSpec");
        this.log("************************************************");
        final SharedPreferences p = PreferenceManager.getDefaultSharedPreferences(context);
        if (p.getBoolean(Preferences.PREFS_ENABLED, false)) {
            if (p.getString(Preferences.PREFS_USER, "").length() > 0 && p.getString(Preferences.PREFS_PASSWORD, "") // .
                    .length() > 0) {
                connectorSpec.setReady();
            } else {
                connectorSpec.setStatus(ConnectorSpec.STATUS_ENABLED);
            }
        } else {
            connectorSpec.setStatus(ConnectorSpec.STATUS_INACTIVE);
        }
        this.log("************************************************");
        this.log("*** End updateSpec");
        this.log("************************************************");
        return connectorSpec;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected final void doBootstrap(final Context context, final Intent intent) throws WebSMSException {
        this.log("************************************************");
        this.log("*** Start doBootstrap");
        this.log("************************************************");

        final SharedPreferences p = PreferenceManager.getDefaultSharedPreferences(context);

        if (inBootstrap && !this.SENT_SMS.equals(DUMMY) && !this.LOGIN_TOKEN.equals(DUMMY)) {
            this.log("already in bootstrap: skip bootstrap");
            return;
        }

        this.log("Enter in new bootstrap");
        this.log("LOGIN_TOKEN=" + this.LOGIN_TOKEN);

        if (this.LOGIN_TOKEN.equals(DUMMY)) {
            // Get LOGIN_TOKEN (SunQueryParamsString)
            this.sendData(ConnectorOrange.URL_LOGIN_STARTUP, context, null);
        }
        this.log("**** got the Token=" + this.LOGIN_TOKEN);

        if (this.LOGIN_TOKEN.equals(DUMMY)) {
            this.LOGIN_TOKEN = "cmVhbG09bXkub3JhbmdlLmNo";
        }

        inBootstrap = true;

        String username = p.getString(Preferences.PREFS_USER, "");
        String password = p.getString(Preferences.PREFS_PASSWORD, "");

        ArrayList<BasicNameValuePair> postParameter = new ArrayList<BasicNameValuePair>();

        postParameter.add(new BasicNameValuePair("IDButton", "Submit"));
        postParameter.add(new BasicNameValuePair("IDToken1", username));
        postParameter.add(new BasicNameValuePair("IDToken2", password));
        postParameter.add(new BasicNameValuePair("Login.Submit", "Anmeldung"));
        postParameter.add(new BasicNameValuePair("SunQueryParamsString", this.LOGIN_TOKEN));
        postParameter.add(new BasicNameValuePair("encoded", "false"));
        postParameter.add(new BasicNameValuePair("goto", "null"));
        postParameter.add(new BasicNameValuePair("gotoOnFail", ""));
        postParameter.add(new BasicNameValuePair("gx_charset", ConnectorOrange.ENCODING));
        postParameter.add(new BasicNameValuePair("iPSPCookie", "false"));

        // Do the Login
        this.log("**** Do the Login");
        this.sendData(URL_LOGIN_ACTION, context, postParameter);

        this.setBalance(context);

        this.log("**** at end of bootstrap LOGIN_TOKEN = " + this.LOGIN_TOKEN);
        this.log("************************************************");
        this.log("*** Ende doBootstrap");
        this.log("************************************************");
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected final void doUpdate(final Context context, final Intent intent) throws WebSMSException {
        this.log("************************************************");
        this.log("*** Start doUpdate");
        this.log("************************************************");

        this.doBootstrap(context, intent);

        // Get singleton.
        this.mGaInstance = GoogleAnalytics.getInstance(context);
        // To set the default tracker, use:
        // First get a tracker using a new property ID.
        Tracker newTracker = this.mGaInstance.getTracker(ANALYTICS_ID);
        // Then make newTracker the default tracker globally.
        this.mGaInstance.setDefaultTracker(newTracker);
        // Get default tracker.
        this.mGaTracker = this.mGaInstance.getDefaultTracker();

        // Get SMS credit form dashboard
        ArrayList<BasicNameValuePair> postParameter = new ArrayList<BasicNameValuePair>();
        this.sendData(URL_SMS_COMPOSER_BALANCE, context, postParameter);

        this.setBalance(context);

        // Google analytics
        if (this.mGaTracker != null) {
            this.log("Tracking ID=" + this.mGaTracker.getTrackingId());
            this.mGaTracker.sendEvent(TAG, "doUpdate", "Balance: " + this.getSpec(context).getBalance(), 0L);
        }

        this.log("************************************************");
        this.log("*** Ende doUpdate");
        this.log("************************************************");
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected final void doSend(final Context context, final Intent intent) throws WebSMSException {
        this.log("************************************************");
        this.log("*** Start doSend SMS");
        this.log("************************************************");
        this.doBootstrap(context, intent);

        this.sendData(URL_SENDSMS, context, null);

        ConnectorCommand command = new ConnectorCommand(intent);

        // SMS Text
        String text = command.getText();
        this.log("text.length()=" + text.length());
        this.log("text=" + text);

        int sent = 0;
        if (!this.SENT_SMS.equals(DUMMY)) {
            try {
                sent = Integer.valueOf(this.SENT_SMS);
            } catch (NumberFormatException e) {
                this.log("*** Cannot convert SMS_CREDIT to integer: " + this.SENT_SMS);
            }
        }
        // Building POST parameter
        ArrayList<BasicNameValuePair> postParameter = new ArrayList<BasicNameValuePair>();
        postParameter.add(new BasicNameValuePair("form[_token]", this.SMS_FORM_TOKEN));
        postParameter.add(new BasicNameValuePair("form[message]", text));
        postParameter.add(new BasicNameValuePair("form[sentTillNow]", "" + sent));
        postParameter.add(new BasicNameValuePair("form[submitted]", "1"));
        postParameter.add(new BasicNameValuePair("submit", "0"));

        // SMS Recipients
        String[] to = command.getRecipients();
        this.log("to[0]    =" + to[0]);
        if (to == null || to.length > 10) {
            String error = context.getString(R.string.connector_orange_more_than_10);
            this.log("----- ERROR: " + error);
            Toast.makeText(context, R.string.connector_orange_more_than_10, Toast.LENGTH_LONG).show();
        }
        this.log("to.length=" + to.length);
        // Send SMS
        for (int i = 0; i < to.length; i++) {
            if (to[i] != null && to[i].length() > 1) {

                int index1 = to[i].indexOf("<");
                int index2 = to[i].indexOf(">");
                String toNumber = to[i].substring(index1 + 1, index2);

                postParameter.add(new BasicNameValuePair("form[to][fullNumber]", toNumber));

                // Google analytics
                if (this.mGaTracker != null) {
                    this.log("Tracking ID=" + this.mGaTracker.getTrackingId());
                    this.mGaTracker.sendEvent(TAG, "Send SMS", "Count receiver: " + i + 1, 0L);
                }

                this.log("***** POST Parameter=" + postParameter.toString());
                this.sendData(URL_SENDSMS, context, postParameter);
            }
        }

        this.doUpdate(context, intent);

        this.setBalance(context);

        this.log("************************************************");
        this.log("*** Ende doSend SMS");
        this.log("************************************************");
    }

    /**
     * Sending the SMS
     * 
     * @param fullTargetURL
     * @param context
     * @param postParameter
     * @throws WebSMSException
     */
    private void sendData(final String fullTargetURL, final Context context,
            final ArrayList<BasicNameValuePair> postParameter) throws WebSMSException {

        this.log("************************************************");
        this.log("*** Start sendData");
        this.log("************************************************");
        try {

            this.log("URL: " + fullTargetURL);
            // send data
            this.log("prepare: getHttpClient(...)");

            HttpOptions httpOptions = new HttpOptions();
            httpOptions.url = fullTargetURL;
            httpOptions.userAgent = USER_AGENT;
            // httpOptions.encoding = ENCODING;
            httpOptions.trustAll = true;
            this.log("UrlEncodedFormEntity()");
            if (postParameter != null) {
                httpOptions.postData = new UrlEncodedFormEntity(postParameter, ENCODING);
            }

            this.log("send data: getHttpClient(...)");
            HttpResponse response = Utils.getHttpClient(httpOptions);

            int respStatus = response.getStatusLine().getStatusCode();
            this.log("response status=" + respStatus);
            this.log("response=\n" + response);
            if (respStatus != HttpURLConnection.HTTP_OK) {
                throw new WebSMSException(context, R.string.error_http, "" + respStatus);
            }
            String htmlText = Utils.stream2str(response.getEntity().getContent()).trim();
            if (htmlText == null || htmlText.length() == 0) {
                throw new WebSMSException(context, R.string.error_service);
            }
            this.log("----- Start HTTP RESPONSE--");
            this.log(htmlText);
            this.log("----- End HTTP RESPONSE--");

            // ================
            // Start parse HTML
            // ================

            // Get Login token
            if (fullTargetURL.equals(ConnectorOrange.URL_LOGIN_STARTUP)) {
                this.LOGIN_TOKEN = HtmlUtil.getHtmlString(htmlText, "SunQueryParamsString", 29, 69, " />", -1);
            } else
            // Get prepayed credit
            if (fullTargetURL.equals(ConnectorOrange.URL_LOGIN_ACTION)
                    || fullTargetURL.equals(ConnectorOrange.URL_PREPAY_CREDIT)) {
                String prepayCredit = HtmlUtil.getHtmlString(htmlText, ">CHF", 5, 10, null, 0);

                if (prepayCredit != null && !prepayCredit.equals("")) {
                    this.PREPAY_CREDIT = prepayCredit.replace("<", "");
                }
            } else
            // Get SMS credit
            if (fullTargetURL.equals(ConnectorOrange.URL_SMS_COMPOSER_BALANCE)) {
                String smsCredit = HtmlUtil.getHtmlString(htmlText, "sent_sms_counter\">", 18, 20, null, 0);

                if (smsCredit.indexOf("<") > 0) {
                    smsCredit = smsCredit.substring(0, 1);
                }
                if (smsCredit != null && !smsCredit.equals("")) {
                    this.SENT_SMS = smsCredit;
                }
            } else
            // Get form[_token]
            if (fullTargetURL.equals(ConnectorOrange.URL_SENDSMS)) {
                String formToken = HtmlUtil.getHtmlString(htmlText, "form[_token]", 21, 66, " />", -1);

                if (formToken != null && !formToken.equals("")) {
                    this.SMS_FORM_TOKEN = formToken;
                }
            }

            // ================
            // End parse HTML
            // ================

            htmlText = null;

        } catch (Exception e) {
            Log.e(TAG, "Unknown Error", e);
            throw new WebSMSException(e.getMessage());
        }
        this.log("************************************************");
        this.log("*** Ende sendData");
        this.log("************************************************");

    }

    void setBalance(final Context context) {
        String sms = "";
        String credit = "";

        if (!this.SENT_SMS.equals(DUMMY)) {
            try {
                sms = "" + (20 - Integer.valueOf(this.SENT_SMS));
                if (Integer.valueOf(sms) <= 0) {
                    Toast.makeText(context, R.string.connector_orange_balance_negativ, Toast.LENGTH_LONG).show();
                }
            } catch (NumberFormatException e) {
                this.log("*** Cannot convert SMS_CREDIT to integer: " + this.SENT_SMS);
                sms = "";
            }
        }
        if (!this.PREPAY_CREDIT.equals("")) {
            credit = " CHF=" + this.PREPAY_CREDIT;
        } else {
            this.getPrepayCredit(context);
            credit = this.PREPAY_CREDIT;
        }
        this.getSpec(context).setBalance(sms + credit);
    }

    private void getPrepayCredit(final Context context) {
        this.sendData(ConnectorOrange.URL_PREPAY_CREDIT, context, null);
    }

    /**
     * central logger
     * 
     * @param message
     */
    private void log(final String message) {
        // Log.d(TAG, message);
    }
}