com.achow101.bitcointalkforum.fragments.PMReplyFragment.java Source code

Java tutorial

Introduction

Here is the source code for com.achow101.bitcointalkforum.fragments.PMReplyFragment.java

Source

/*
 * Copyright (c) 2015 Andrew Chow
 *
 * 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.achow101.bitcointalkforum.fragments;

import android.app.Activity;
import android.content.Context;
import android.database.DataSetObserver;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.text.Html;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import com.achow101.bitcointalkforum.R;
import com.achow101.bitcointalkforum.items.SummaryPost;

import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

public class PMReplyFragment extends Fragment {

    private OnPostListener mListener;

    private String mReplyURL;
    private String mSessId;

    private PostReply mPostReply;
    private String mPostURL;
    private String mTopicID;
    private String mSC;

    private EditText mSubjectText;
    private EditText mMessageText;
    private ListView mTopicSummary;
    private Button mPost;
    private ProgressBar mProgressView;

    private TextView mSubjectLabel;
    private TextView mMessageLabel;
    private TextView mSummaryLabel;

    private GetReplyPage mGetReplyPage;

    public static PMReplyFragment newInstance(String replyURL, String sessId) {
        PMReplyFragment fragment = new PMReplyFragment();
        Bundle args = new Bundle();
        args.putString("Reply URL", replyURL);
        args.putString("Session ID", sessId);
        fragment.setArguments(args);
        return fragment;
    }

    public PMReplyFragment() {
        // Required empty public constructor
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View v = inflater.inflate(R.layout.fragment_reply, container, false);

        // Get reply url and sessid
        mReplyURL = getArguments().getString("Reply URL");
        mSessId = getArguments().getString("Session ID");

        // Get layout stuff
        mSubjectText = (EditText) v.findViewById(R.id.subject_text);
        mMessageText = (EditText) v.findViewById(R.id.message_text);
        mTopicSummary = (ListView) v.findViewById(R.id.topic_summary_list);
        mPost = (Button) v.findViewById(R.id.post_button);
        mProgressView = (ProgressBar) v.findViewById(R.id.progress);
        mSubjectLabel = (TextView) v.findViewById(R.id.subject_textview);
        mMessageLabel = (TextView) v.findViewById(R.id.message_textView);
        mSummaryLabel = (TextView) v.findViewById(R.id.topic_summary_textview);

        // getting data
        showProgress(true);
        mProgressView.setVisibility(View.VISIBLE);
        mGetReplyPage = new GetReplyPage(mReplyURL, mSessId);
        mGetReplyPage.execute((Void) null);

        return v;
    }

    public void showProgress(final boolean show) {
        // Show and hide ui stuff
        mProgressView.setVisibility(show ? View.VISIBLE : View.GONE);
        mSubjectText.setVisibility(show ? View.GONE : View.VISIBLE);
        mMessageText.setVisibility(show ? View.GONE : View.VISIBLE);
        mTopicSummary.setVisibility(show ? View.GONE : View.VISIBLE);
        mPost.setVisibility(show ? View.GONE : View.VISIBLE);
        mProgressView.setVisibility(show ? View.GONE : View.VISIBLE);
        mSubjectLabel.setVisibility(show ? View.GONE : View.VISIBLE);
        mMessageLabel.setVisibility(show ? View.GONE : View.VISIBLE);
        mSummaryLabel.setVisibility(show ? View.GONE : View.VISIBLE);
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        try {
            mListener = (OnPostListener) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString() + " must implement OnPostListener");
        }
    }

    @Override
    public void onDetach() {
        super.onDetach();
        mListener = null;
    }

    private class TopicSummaryAdapter implements ListAdapter {
        private List<SummaryPost> posts;

        public TopicSummaryAdapter(List<SummaryPost> posts) {
            this.posts = posts;
        }

        @Override
        public boolean areAllItemsEnabled() {
            return false;
        }

        @Override
        public boolean isEnabled(int position) {
            return false;
        }

        @Override
        public void registerDataSetObserver(DataSetObserver observer) {

        }

        @Override
        public void unregisterDataSetObserver(DataSetObserver observer) {

        }

        @Override
        public int getCount() {
            return posts.size();
        }

        @Override
        public Object getItem(int position) {
            return posts.get(position);
        }

        @Override
        public long getItemId(int position) {
            return 0;
        }

        @Override
        public boolean hasStableIds() {
            return false;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {

            View v = convertView;
            if (v == null) {
                LayoutInflater infalInflater = (LayoutInflater) getContext()
                        .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                v = infalInflater.inflate(R.layout.summary_post, null);
            }

            TextView posterInfo = (TextView) v.findViewById(R.id.poster);
            TextView post = (TextView) v.findViewById(R.id.post);

            posterInfo.setText(posts.get(position).getPoster());
            post.setText(posts.get(position).getText());

            return v;
        }

        @Override
        public int getItemViewType(int position) {
            return 0;
        }

        @Override
        public int getViewTypeCount() {
            return 1;
        }

        @Override
        public boolean isEmpty() {
            return false;
        }
    }

    private class GetReplyPage extends AsyncTask<Void, Void, List<List<Object>>> {
        private String mReplyURL;
        private String mSessId;

        public GetReplyPage(String replyURL, String sessId) {
            this.mReplyURL = replyURL;
            this.mSessId = sessId;
        }

        @Override
        protected List<List<Object>> doInBackground(Void... params) {
            List<List<Object>> out = new ArrayList<List<Object>>();
            List<Object> subjMess = new ArrayList<Object>();
            List<Object> postSummary = new ArrayList<Object>();
            List<Object> postData = new ArrayList<>();

            try {
                Document doc = Jsoup.connect(mReplyURL).cookie("PHPSESSID", mSessId).get();

                // retrieve subject
                String subject = doc.select("td > input[name=subject]").first().attr("value");

                // retrieve recipient
                String to = doc.select("td > input[name=to]").first().attr("value");

                // Retrieve any existing message (e.g. quotes)
                String message = doc.select("td > textarea.editor[name=message]").first().text();

                // Add subject and message to a list
                subjMess.add(subject);
                subjMess.add(message);
                subjMess.add(to);

                // Get posters and posts for topic summary
                Elements posters = doc.select(" td.windowbg2 > table > tbody > tr");
                Elements posts = doc.select("table.bordercolor > tbody > tr > td.windowbg");

                if (!posters.isEmpty() && !posts.isEmpty()) {
                    Element poster = posters.first();
                    Element post = posts.last();

                    SummaryPost postObj = new SummaryPost(poster.text(),
                            Html.fromHtml(post.html(), new ImageGetter(), null));
                    postSummary.add(postObj);
                }

                // Get post URL
                postData.add(doc.select("form#postmodify").attr("action"));

                // Get topic id
                postData.add(doc.select("input[type=hidden][name=replied_to]").first().attr("value"));

                // Get secret key
                postData.add(doc.select("input[type=hidden][name=sc]").first().attr("value"));

                // Get seqnum
                postData.add(doc.select("input[type=hidden][name=seqnum]").first().attr("value"));

                // Get f
                postData.add(doc.select("input[type=hidden][name=f]").first().attr("value"));

                // get l
                postData.add(doc.select("input[type=hidden][name=l]").first().attr("value"));

            } catch (IOException e) {
                e.printStackTrace();
            }

            out.add(subjMess);
            out.add(postSummary);
            out.add(postData);

            return out;
        }

        private class ImageGetter implements Html.ImageGetter {

            @Override
            public Drawable getDrawable(String source) {
                // Download bitmap
                if (!source.contains("bitcointalk.org"))
                    source = "https://bitcointalk.org" + source;
                BitmapDrawable bmp = null;
                try {
                    URL url = new URL(source);
                    HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                    connection.setDoInput(true);
                    connection.connect();
                    InputStream input = connection.getInputStream();
                    bmp = new BitmapDrawable(getResources(), input);
                    bmp.setBounds(0, 0, bmp.getIntrinsicWidth() * 10, bmp.getIntrinsicHeight() * 10);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return bmp;
            }
        }

        @Override
        protected void onPostExecute(List<List<Object>> result) {
            showProgress(false);
            mProgressView.setVisibility(View.GONE);
            mGetReplyPage = null;

            if (result.size() > 0) {
                final List<Object> subjMess = result.get(0);
                List<Object> posts = result.get(1);

                // Set subject and message texts initial text
                mSubjectText.setText((String) subjMess.get(0));
                mMessageText.setText((String) subjMess.get(1));

                // TODO: add stuff for quick icons like smileys and text formatting

                // Set topic summary list
                List<SummaryPost> summaryPosts = new ArrayList<>();
                for (Object post : posts) {
                    summaryPosts.add((SummaryPost) post);
                }
                TopicSummaryAdapter mAdp = new TopicSummaryAdapter(summaryPosts);
                mTopicSummary.setAdapter(mAdp);

                // Set the post url
                mPostURL = (String) result.get(2).get(0);
                mTopicID = (String) result.get(2).get(1);
                mSC = (String) result.get(2).get(2);
                final String to = (String) subjMess.get(2);
                final String seqnum = (String) result.get(2).get(3);
                final String f = (String) result.get(2).get(4);
                final String l = (String) result.get(2).get(5);

                // Set posting behavior
                mPost.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        mPostReply = new PostReply(to, mPostURL, mSubjectText.getText().toString(),
                                mMessageText.getText().toString(), mSC, mTopicID, mSessId, seqnum, f, l);
                        mPostReply.execute((Void) null);
                        mListener.onPMPageSelected(0);
                    }
                });

            } else {
                Toast toast = Toast.makeText(getContext(), "An error occurred", Toast.LENGTH_LONG);
                toast.show();
            }
        }
    }

    private class PostReply extends AsyncTask<Void, Void, Void> {
        private String postURL;
        private String sc;
        private String subject;
        private String message;
        private String id;
        private String sessId;
        private String seqnum;
        private String f;
        private String l;
        private String to;

        public PostReply(String to, String postURL, String subject, String message, String sc, String id,
                String sessId, String seqnum, String f, String l) {
            this.postURL = postURL;
            this.sc = sc;
            this.subject = subject;
            this.message = message;
            this.id = id;
            this.sessId = sessId;
            this.seqnum = seqnum;
            this.f = f;
            this.l = l;
            this.to = to;
        }

        @Override
        protected Void doInBackground(Void... params) {

            try {
                Connection.Response res = Jsoup.connect(postURL).data("to", to).data("sc", sc)
                        .data("subject", subject).data("message", message).data("replied_to", id)
                        .data("seqnum", seqnum).data("f", f).data("l", l).cookie("PHPSESSID", sessId)
                        .method(Connection.Method.POST).execute();
            } catch (IOException e) {
                e.printStackTrace();
            }

            return null;
        }
    }

    public interface OnPostListener {
        public void onPMPageSelected(int page);
    }

}