fr.gcastel.freeboxV6GeekIncDownloader.services.FreeboxDownloaderService.java Source code

Java tutorial

Introduction

Here is the source code for fr.gcastel.freeboxV6GeekIncDownloader.services.FreeboxDownloaderService.java

Source

/*
   Copyright 2011 Gerben CASTEL
    
   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 fr.gcastel.freeboxV6GeekIncDownloader.services;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.Header;
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.HttpClient;
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.client.params.HttpClientParams;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;

import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.Toast;

/**
 * Le service de tlchargement via freebox
 * 
 * @author Gerben
 */
public class FreeboxDownloaderService extends AsyncTask<String, Void, Void> {
    private static final String TAG = "FreeboxDownloaderService";
    private final String urlFreebox;
    private Context zeContext;
    private boolean echec = false;
    private Dialog dialog;
    private String alertDialogMessage = null;
    private boolean bypassTraitement = false;

    private enum DialogEnCours {
        NONE, PROGRESS, ALERT;
    }

    private DialogEnCours dialogueEnCours = DialogEnCours.NONE;

    /**
     * Instanciation
     * 
     * @param inUrlFreebox l'url  utiliser pour se connecter  la freebox
     */
    public FreeboxDownloaderService(String inUrlFreebox, Context context, ProgressDialog inDialog) {
        urlFreebox = inUrlFreebox;
        zeContext = context;
        dialog = inDialog;
        dialogueEnCours = DialogEnCours.PROGRESS;
    }

    public boolean isConnectedViaWifi() {
        boolean result = false;
        if (zeContext != null) {
            ConnectivityManager cm = (ConnectivityManager) zeContext.getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo info = cm.getActiveNetworkInfo();
            result = (info != null) && (info.getType() == ConnectivityManager.TYPE_WIFI);
        }
        return result;
    }

    private String loginFreebox(String password)
            throws UnsupportedEncodingException, ClientProtocolException, IOException {
        String cookieFbx = "";
        String csrfToken = "";

        // Prparation des paramtres
        HttpPost postReq = new HttpPost(urlFreebox + "/login.php");
        List<NameValuePair> parametres = new ArrayList<NameValuePair>();
        parametres.add(new BasicNameValuePair("login", "freebox"));
        parametres.add(new BasicNameValuePair("passwd", password));
        postReq.setEntity(new UrlEncodedFormEntity(parametres));

        // Envoi de la requte
        HttpParams httpParameters = new BasicHttpParams();

        // Mise en place de timeouts
        int timeoutConnection = 5000;
        HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
        int timeoutSocket = 5000;
        HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);

        HttpClient httpclient = new DefaultHttpClient(httpParameters);
        HttpParams params = httpclient.getParams();
        HttpClientParams.setRedirecting(params, false);

        HttpResponse response = httpclient.execute(postReq);

        // Ok ? (302 = moved = redirection)
        if (response.getStatusLine().getStatusCode() == 302) {
            Header cookie = response.getFirstHeader("Set-Cookie");
            cookieFbx = cookie.getValue();

            // Extraction du cookie FBXSID
            cookieFbx = cookieFbx.substring(cookieFbx.indexOf("FBXSID=\""), cookieFbx.indexOf("\";") + 1);
            Log.d(TAG, "Cookie = " + cookieFbx);
        } else {
            Log.d(TAG, "Erreur d'authentification - statusCode = " + response.getStatusLine().getStatusCode()
                    + " - reason = " + response.getStatusLine().getReasonPhrase());
            prepareAlertDialog("Erreur d'authentification");
        }

        // On a le cookie, il nous manque le csrf_token
        // On rcupre la page download !
        HttpGet downloadPageReq = new HttpGet(urlFreebox + "/download.php");
        downloadPageReq.setHeader("Cookie", "FBXSID=\"" + cookieFbx + "\";");
        response = httpclient.execute(downloadPageReq);

        // Ok ?
        if (response.getStatusLine().getStatusCode() == 200) {
            HttpEntity entity = response.getEntity();
            InputStream contentStream = entity.getContent();

            BufferedReader br = new BufferedReader(new InputStreamReader(contentStream));
            String line = br.readLine();

            while (line != null) {
                if (line.contains("input type=\"hidden\" name=\"csrf_token\"")) {
                    csrfToken = line.substring(line.indexOf("value=\"") + "value=\"".length(),
                            line.lastIndexOf("\""));
                    break;
                }
                line = br.readLine();
            }

            br.close();
            contentStream.close();

            Log.d(TAG, "csrfToken = " + csrfToken);
        } else {
            Log.d(TAG, "Erreur d'authentification - statusCode = " + response.getStatusLine().getStatusCode()
                    + " - reason = " + response.getStatusLine().getReasonPhrase());
            prepareAlertDialog("Erreur d'authentification");
        }

        // C'est moche, mais a me permet de corriger a vite fait...
        return cookieFbx + "<-->" + csrfToken;
    }

    private void prepareAlertDialog(String message) {
        dialogueEnCours = DialogEnCours.ALERT;
        alertDialogMessage = message;
    }

    private void showAlertDialog() {
        AlertDialog.Builder alertbox = new AlertDialog.Builder(zeContext);
        alertbox.setMessage(alertDialogMessage);
        alertbox.setNeutralButton("Ok", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface arg0, int arg1) {
                dialogueEnCours = DialogEnCours.NONE;
                return;
            }
        });
        alertbox.show();
    }

    private void launchDownload(String cookieCSRF, String url)
            throws UnsupportedEncodingException, ClientProtocolException, IOException {
        int splitPos = cookieCSRF.indexOf("<-->");
        String cookie = cookieCSRF.substring(0, splitPos);
        String csrfToken = cookieCSRF.substring(splitPos + 4);
        // Prparation des paramtres
        HttpPost postReq = new HttpPost(urlFreebox + "/download.cgi");
        List<NameValuePair> parametres = new ArrayList<NameValuePair>();
        parametres.add(new BasicNameValuePair("url", url));
        parametres.add(new BasicNameValuePair("user", "freebox"));
        parametres.add(new BasicNameValuePair("method", "download.http_add"));
        parametres.add(new BasicNameValuePair("csrf_token", csrfToken));
        postReq.setEntity(new UrlEncodedFormEntity(parametres));

        // Mise en place des headers
        postReq.setHeader("Cookie", cookie + ";");
        postReq.setHeader("Referer", "http://mafreebox.freebox.fr/download.php");

        // Envoi de la requte
        HttpParams httpParameters = new BasicHttpParams();

        // Mise en place de timeouts
        int timeoutConnection = 5000;
        HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
        int timeoutSocket = 5000;
        HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
        HttpClient httpclient = new DefaultHttpClient(httpParameters);
        HttpParams params = httpclient.getParams();
        HttpClientParams.setRedirecting(params, false);

        HttpResponse response = httpclient.execute(postReq);

        // Ok ? (302 = moved = redirection)
        if (response.getStatusLine().getStatusCode() != 302) {
            Log.d(TAG,
                    "Erreur lors du lancement du tlchargement - statusCode = "
                            + response.getStatusLine().getStatusCode() + " - reason = "
                            + response.getStatusLine().getReasonPhrase());
            prepareAlertDialog("Erreur lors du lancement du tlchargement.");
        }
    }

    @Override
    protected Void doInBackground(String... params) {
        try {
            if (!bypassTraitement) {
                String cookie = loginFreebox(params[1]);
                if (alertDialogMessage == null) {
                    launchDownload(cookie, params[0]);
                } else {
                    echec = true;
                }
            }
        } catch (Exception e) {
            echec = true;
        }
        return null;
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        if (!isConnectedViaWifi()) {
            Toast.makeText(zeContext, "Vous devez tre connect en Wifi pour accder  la freebox",
                    Toast.LENGTH_SHORT).show();
            bypassTraitement = true;
        } else {
            if (dialog != null) {
                dialog.show();
            }
        }
    }

    @Override
    protected void onPostExecute(Void result) {
        super.onPostExecute(result);
        dialog.hide();
        dialogueEnCours = DialogEnCours.NONE;

        if (alertDialogMessage != null) {
            showAlertDialog();
        }

        if (!bypassTraitement) {
            if (echec) {
                Toast.makeText(zeContext, "Impossible de se connecter  la freebox", Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(zeContext, "Tlchargement lanc !", Toast.LENGTH_SHORT).show();
            }
        }
    }

    public void attach(Context inContext) {
        zeContext = inContext;
        switch (dialogueEnCours) {
        case PROGRESS:
            dialog = new ProgressDialog(zeContext);
            dialog.setCancelable(true);
            ((ProgressDialog) dialog).setMessage("Connexion  la freebox");
            ((ProgressDialog) dialog).setProgressStyle(ProgressDialog.STYLE_SPINNER);
            dialog.show();
            break;
        case ALERT:
            prepareAlertDialog(alertDialogMessage);
            showAlertDialog();
            break;
        case NONE:
        default:
            break;
        }
    }

    public void detach() {
        zeContext = null;
        dialog = null;
    }
}