com.luorrak.ouroboros.util.NetworkHelper.java Source code

Java tutorial

Introduction

Here is the source code for com.luorrak.ouroboros.util.NetworkHelper.java

Source

package com.luorrak.ouroboros.util;

import android.app.Activity;
import android.app.DownloadManager;
import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Environment;
import android.support.design.widget.Snackbar;
import android.util.Base64;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ProgressBar;

import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.koushikdutta.async.future.FutureCallback;
import com.koushikdutta.async.http.body.Part;
import com.koushikdutta.async.http.body.StringPart;
import com.koushikdutta.ion.Ion;
import com.koushikdutta.ion.Response;
import com.luorrak.ouroboros.R;
import com.luorrak.ouroboros.api.JsonParser;
import com.luorrak.ouroboros.reply.ReplyCommentFragment;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;

import java.io.File;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Ouroboros - An 8chan browser
 * Copyright (C) 2015  Luorrak
 *
 * 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/>.
 */
public class NetworkHelper {
    private final String LOG_TAG = NetworkHelper.class.getSimpleName();
    private boolean needDNSBLCaptcha = false;
    private boolean genericCaptcha = false;

    public void postReply(final Context context, final Reply reply, final SharedPreferences sharedPreferences,
            final JsonParser jsonParser, final InfiniteDbHelper infiniteDbHelper, final View view) {
        String postUrl = ChanUrls.getReplyUrl();
        String referalUrl = ChanUrls.getThreadHtmlUrl(reply.board, reply.resto);

        if (needDNSBLCaptcha) {
            ArrayList<Part> dnsblparameters = new ArrayList<Part>();
            needDNSBLCaptcha = false;
            dnsblparameters.add(new StringPart("captcha_text", reply.captchaText));
            dnsblparameters.add(new StringPart("captcha_cookie", reply.captchaCookie));
            reply.captchaText = "";
            reply.captchaCookie = "";
            Ion.with(context).load(ChanUrls.getDnsblUrl()).addMultipartParts(dnsblparameters).asString().tryGet();
            needDNSBLCaptcha = false;
        }

        reply.email = reply.sage ? "sage" : reply.email;

        ArrayList<Part> parameters = new ArrayList<Part>();
        parameters.add(new StringPart("board", reply.board));
        parameters.add(new StringPart("name", reply.name));
        parameters.add(new StringPart("email", reply.email));
        parameters.add(new StringPart("subject", reply.subject));
        parameters.add(new StringPart("body", reply.comment));
        parameters.add(new StringPart("password", reply.password));
        parameters.add(new StringPart("json_response", "1"));
        parameters.add(new StringPart("captcha_text", reply.captchaText));
        parameters.add(new StringPart("captcha_cookie", reply.captchaCookie));
        if (reply.resto.equals("0")) {
            parameters.add(new StringPart("page", "1"));
            parameters.add(new StringPart("post", "New Topic"));
        } else {
            parameters.add(new StringPart("post", "New Reply"));
            parameters.add(new StringPart("thread", reply.resto)); //only if new thread else nothing
        }

        if (reply.filePath != null) {
            for (int i = 0; i < reply.filePath.size(); i++) {
                if (i == 0) {
                    parameters.add(new CustomFilePart("file", new File(reply.filePath.get(i))));
                } else {
                    int fileNumber = i + 1;
                    parameters.add(new CustomFilePart("file" + fileNumber, new File(reply.filePath.get(i))));
                }
            }
        }

        if (genericCaptcha) {
            genericCaptcha = false;
        }

        Ion.with(context).load(postUrl).setHeader("Referer", referalUrl).setHeader("Origin", "https://8ch.net")
                .addMultipartParts(parameters).asJsonObject().withResponse()
                .setCallback(new FutureCallback<Response<JsonObject>>() {
                    @Override
                    public void onCompleted(Exception e, Response<JsonObject> jsonObjectResponse) {
                        ReplyCommentFragment.finishedPosting();
                        String boardName;
                        String userPostNo;
                        ProgressBar progressBar = (ProgressBar) ((Activity) context)
                                .findViewById(R.id.progress_bar);
                        progressBar.setVisibility(View.INVISIBLE);
                        if (e != null) {
                            Snackbar.make(view, "Data did NOT post successfully", Snackbar.LENGTH_LONG).show();
                            return;
                        }
                        if (jsonObjectResponse.getHeaders().code() == 200) {
                            captchaTest(jsonObjectResponse.getResult());
                            if (needDNSBLCaptcha) {
                                Snackbar.make(view, "Please fill out DNSBL Captcha", Snackbar.LENGTH_LONG).show();

                                EditText captchaText = (EditText) ((Activity) context)
                                        .findViewById(R.id.post_comment_captcha_editText); //messy
                                captchaText.setVisibility(View.VISIBLE);

                                getDnsblCaptcha(context, view);
                                return;
                            } else if (genericCaptcha) {
                                Snackbar.make(view, "Please fill out Captcha", Snackbar.LENGTH_LONG).show();

                                EditText captchaText = (EditText) ((Activity) context)
                                        .findViewById(R.id.post_comment_captcha_editText); //messy
                                captchaText.setVisibility(View.VISIBLE);

                                getCaptcha(context, view);
                                return;
                            } else if (jsonObjectResponse.getResult().has("error")) {
                                //unknown error
                                Snackbar.make(view, jsonObjectResponse.getResult().get("error").getAsString(),
                                        Snackbar.LENGTH_LONG).show();
                                return;
                            }

                            boardName = jsonParser.getSubmittedBoardName(jsonObjectResponse.getResult());
                            userPostNo = jsonParser.getUserPostNo(jsonObjectResponse.getResult());

                            infiniteDbHelper.insertUserPostEntry(boardName, userPostNo, reply.resto, reply.subject,
                                    reply.comment);

                            sharedPreferences.edit().remove(SaveReplyText.nameEditTextKey)
                                    .remove(SaveReplyText.emailEditTextKey).remove(SaveReplyText.subjectEditTextKey)
                                    .remove(SaveReplyText.commentEditTextKey).apply();

                            ((Activity) context).finish();
                        } else {
                            //There is a crash here sometimes.
                            Log.e(LOG_TAG, "Failed Post " + jsonObjectResponse.getHeaders().message() + " code "
                                    + jsonObjectResponse.getHeaders().code());
                            Snackbar.make(view, "Data did NOT post successfully", Snackbar.LENGTH_LONG).show();
                        }

                    }
                });
    }

    private void getCaptcha(final Context context, final View view) {
        Ion.with(context).load(ChanUrls.getCaptchaEntrypoint()).asString()
                .setCallback(new FutureCallback<String>() {
                    @Override
                    public void onCompleted(Exception e, String rawHTML) {
                        if (e != null) {
                            Snackbar.make(view, "Error retrieving CAPTCHA", Snackbar.LENGTH_LONG).show();
                            return;
                        }
                        ImageView captchaImage = (ImageView) ((Activity) context)
                                .findViewById(R.id.post_comment_captcha_image); //messy
                        captchaImage.setVisibility(View.VISIBLE);
                        Document captchaHtml = Jsoup.parse(rawHTML);

                        Pattern cookieIdPattern = Pattern.compile("CAPTCHA ID: (?:(?!<).)*");
                        Matcher matcher = cookieIdPattern.matcher(rawHTML);

                        captchaImage.setTag(matcher.find() ? matcher.group(0).substring(12) : "");
                        String strBase64Image = captchaHtml.select("body > img").attr("src");
                        String strBase64ImageBytes = strBase64Image.substring(strBase64Image.indexOf(",") + 1);
                        byte[] decodedbytes = Base64.decode(strBase64ImageBytes, Base64.DEFAULT);
                        Bitmap decodeImage = BitmapFactory.decodeByteArray(decodedbytes, 0, decodedbytes.length);
                        captchaImage.setImageBitmap(decodeImage);
                    }
                });
    }

    private String captchaTest(JsonObject jsonObject) {
        JsonElement error = jsonObject.get("error");

        if (error == null) {
            return null;
        } else if (error.getAsString().contains("dnsbls_bypass.php")) {
            needDNSBLCaptcha = true;
            return "needDNSBLCaptcha";
        } else if (error.getAsString().contains("entrypoint.php")) {
            genericCaptcha = true;
            return "Captcha";
        } else {
            return null;
        }
    }

    private void getDnsblCaptcha(final Context context, final View view) {
        Ion.with(context).load(ChanUrls.getDnsblUrl()).asString().setCallback(new FutureCallback<String>() {
            @Override
            public void onCompleted(Exception e, String rawHTML) {
                if (e != null) {
                    Snackbar.make(view, "Error retrieving DNSBL CAPTCHA", Snackbar.LENGTH_LONG).show();
                    return;
                }

                ImageView captchaImage = (ImageView) ((Activity) context)
                        .findViewById(R.id.post_comment_captcha_image); //messy
                captchaImage.setVisibility(View.VISIBLE);

                Document dnsblHtml = Jsoup.parse(rawHTML);
                captchaImage.setTag(dnsblHtml.select("body > form > input.captcha_cookie").attr("value"));
                String strBase64Image = dnsblHtml.select("body > form > img").attr("src");
                String strBase64ImageBytes = strBase64Image.substring(strBase64Image.indexOf(",") + 1);
                byte[] decodedbytes = Base64.decode(strBase64ImageBytes, Base64.DEFAULT);
                Bitmap decodeImage = BitmapFactory.decodeByteArray(decodedbytes, 0, decodedbytes.length);
                captchaImage.setImageBitmap(decodeImage);
            }
        });
    }

    public void getImageNoCrossfade(ImageView imageView, String imageUrl) {
        Ion.with(imageView).load(imageUrl).withBitmapInfo();
    }

    public void downloadFile(String boardName, String tim, String ext, Context context) {
        DownloadManager.Request request = new DownloadManager.Request(
                Uri.parse(ChanUrls.getImageUrl(boardName, tim, ext)));
        request.setDescription(tim + ext);
        request.setTitle(tim + ext);
        request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS + "/Ouroboros", tim + ext);

        DownloadManager manager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
        manager.enqueue(request);
    }
}