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

Java tutorial

Introduction

Here is the source code for com.achow101.bitcointalkforum.fragments.MessagesFragment.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.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.text.Html;
import android.text.Spanned;
import android.text.method.LinkMovementMethod;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.achow101.bitcointalkforum.R;
import com.achow101.bitcointalkforum.items.Post;
import com.achow101.bitcointalkforum.items.Poster;

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

import java.io.FileOutputStream;
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 MessagesFragment extends Fragment {

    private int mPageNum;
    private String mSessId;

    private ListView mListView;
    private ProgressBar mProgressView;
    private Button mPrevButton;
    private Button mNextButton;
    private TextView mPageNumText;
    private Button newMessageButton;

    private GetPMs mGetPMsTask;

    private OnPMInteraction mListener;

    public static MessagesFragment newInstance(int page, String sessId) {
        MessagesFragment fragment = new MessagesFragment();
        Bundle args = new Bundle();
        args.putInt("Page", page);
        args.putString("Session ID", sessId);
        fragment.setArguments(args);
        return fragment;
    }

    public MessagesFragment() {
        // 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_topic, container, false);

        // Get arguments
        mPageNum = getArguments().getInt("Page");
        mSessId = getArguments().getString("Session ID");

        // Get layout stuff
        mProgressView = (ProgressBar) v.findViewById(R.id.posts_progress_bar);
        mListView = (ListView) v.findViewById(R.id.posts_list);
        mPrevButton = (Button) v.findViewById(R.id.prev_page_button);
        mNextButton = (Button) v.findViewById(R.id.next_page_button);

        // Reply button to new Button, New PM when clicked
        newMessageButton = (Button) v.findViewById(R.id.reply_button);
        newMessageButton.setText("New");
        newMessageButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mListener.onPMReplySelected("https://bitcointalk.org/index.php?action=pm;sa=send");
            }
        });

        // Set page number
        mPageNumText = (TextView) v.findViewById(R.id.page_num);
        mPageNumText.setText("Page " + mPageNum);

        // get pms
        showProgress(true);
        mGetPMsTask = new GetPMs(
                "https://bitcointalk.org/index.php?action=pm;f=inbox;sort=date;desc;start=" + ((mPageNum - 1) * 20),
                mSessId);
        mGetPMsTask.execute((Void) null);

        return v;
    }

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

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

    public interface OnPMInteraction {

        public void onPMPageSelected(int page);

        public void onPMReplySelected(String editURL);
    }

    public void showProgress(final boolean show) {
        // Show and hide ui stuff
        mProgressView.setVisibility(show ? View.VISIBLE : View.GONE);
        mListView.setVisibility(show ? View.GONE : View.VISIBLE);
        mPrevButton.setVisibility(show ? View.GONE : View.VISIBLE);
        mNextButton.setVisibility(show ? View.GONE : View.VISIBLE);
        mPageNumText.setVisibility(show ? View.GONE : View.VISIBLE);
        newMessageButton.setVisibility(show ? View.GONE : View.VISIBLE);
    }

    private class PostsListAdapter implements ListAdapter {
        private List<Post> posts;

        public PostsListAdapter(List<Post> 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 posts.get(position).getId();
        }

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

        @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.post_layout, null);
            }

            // Get post and poster
            final Post post = posts.get(position);
            Poster poster = post.getPoster();

            // Get post text views
            TextView subjectTitle = (TextView) v.findViewById(R.id.subject_title);
            TextView postTime = (TextView) v.findViewById(R.id.post_time);

            // Set post text views
            subjectTitle.setText(post.getSubject());
            postTime.setText(post.getPostedTime());

            // Get poster text views
            TextView posterTxt = (TextView) v.findViewById(R.id.poster);
            TextView rank = (TextView) v.findViewById(R.id.rank);
            TextView personalText = (TextView) v.findViewById(R.id.personal_text);
            TextView activity = (TextView) v.findViewById(R.id.activity);
            TextView specialPos = (TextView) v.findViewById(R.id.spec_pos);

            // set text for poster
            posterTxt.setText(poster.getName());
            rank.setText(poster.getRank());
            activity.setText(poster.getActivityStr());
            personalText.setText(poster.getPersonalText());

            // Get and set poster avatar image
            ImageView avatar = (ImageView) v.findViewById(R.id.avatar);
            avatar.setImageDrawable(poster.getAvatar());

            // Set special position text
            if (poster.isSpecial())
                specialPos.setText(poster.getSpecialPos());
            else {
                specialPos.setText("");
                specialPos.setVisibility(View.GONE);
            }

            // Set rank coins
            ImageView coins = (ImageView) v.findViewById(R.id.coins);
            if (poster.isSpecial() && !poster.getSpecialPos().equals("Staff")) {
                switch (poster.getSpecialPos()) {
                case "Administrator":
                    coins.setImageResource(R.drawable.admin);
                    break;
                case "Global Moderator":
                    coins.setImageResource(R.drawable.global_mod);
                    break;
                case "Founder":
                    coins.setImageResource(R.drawable.founder);
                    break;
                case "Moderator":
                    coins.setImageResource(R.drawable.moderator);
                    break;
                case "Donator":
                    coins.setImageResource(R.drawable.donator);
                    break;
                case "VIP":
                    coins.setImageResource(R.drawable.vip);
                    break;
                }
            } else {
                switch (poster.getRank()) {
                case "Brand New":
                    coins.setImageResource(R.drawable.coin);
                    break;
                case "Newbie":
                    coins.setImageResource(R.drawable.coin);
                    break;
                case "Jr. Member":
                    coins.setImageResource(R.drawable.coin);
                    break;
                case "Member":
                    coins.setImageResource(R.drawable.member);
                    break;
                case "Full Member":
                    coins.setImageResource(R.drawable.full);
                    break;
                case "Sr. Member":
                    coins.setImageResource(R.drawable.sr);
                    break;
                case "Hero Member":
                    coins.setImageResource(R.drawable.hero);
                    break;
                case "Legendary":
                    coins.setImageResource(R.drawable.legendary);
                    break;
                case "Guest":
                    coins.setVisibility(View.GONE);
                    break;
                }
            }

            // Display the post
            TextView postText = (TextView) v.findViewById(R.id.post);
            postText.setText(post.getPostBody());
            postText.setMovementMethod(LinkMovementMethod.getInstance());

            // Get the buttons
            Button quoteButton = (Button) v.findViewById(R.id.quote_button);
            Button editButton = (Button) v.findViewById(R.id.edit_button);
            Button replyButton = (Button) v.findViewById(R.id.reply_button);
            Button deleteButton = (Button) v.findViewById(R.id.delete_button);

            // Hide edit button
            editButton.setVisibility(View.GONE);

            // Set delete listener
            deleteButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    DeleteReply delRep = new DeleteReply(post.getDeleteURL(), mSessId);
                    delRep.execute((Void) null);
                }
            });

            // Set reply and quote listener
            replyButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    mListener.onPMReplySelected(post.getEditURL());
                }
            });
            quoteButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    mListener.onPMReplySelected(post.getQuoteURL());
                }
            });

            return v;
        }

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

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

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

    }

    private class GetPMs extends AsyncTask<Void, Void, List<Post>> {
        private String topicURL;
        private String sessId;

        public GetPMs(String topicURL, String sessId) {
            this.topicURL = topicURL;
            this.sessId = sessId;
        }

        @Override
        protected List<Post> doInBackground(Void... params) {
            List<Post> posts = new ArrayList<Post>();

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

                if (topicURL.contains("start=0")) {
                    FileOutputStream os = getContext().openFileOutput("messages.html", Context.MODE_PRIVATE);
                    os.write(doc.html().getBytes());
                    os.close();
                }

                // Get body
                Elements body = doc.select("div#bodyarea");

                // Get the table with posts
                Element pmTable = body.select("form[name=pmFolder] > table[cellpadding=0]").first();

                // Get the elements with pms
                Elements pmIds = pmTable.select("tbody > tr > td[style=padding: 1px 1px 0 1px;] > a[name]");

                List<Long> ids = new ArrayList<Long>();
                for (Element id : pmIds) {
                    ids.add(Long.parseLong(id.attr("name").substring(3)));
                }

                Elements pmElements = pmTable
                        .select("table[cellpadding=4] > tbody > tr:not(.windowbg):not(.windowbg2)");

                // Get data from each post
                for (int i = 0; i < pmElements.size(); i++) {
                    Element post = pmElements.get(i);

                    // Get element with posterInfo
                    Element posterInfo = post.select("td[style=overflow: hidden;]").first();

                    // Get poster name
                    String posterName = posterInfo.select("b > a[href]").text();

                    // Get poster rank and activity
                    String posterText = posterInfo.text();

                    String posterActivityStr = "";
                    String posterPersText = "";
                    if (!posterText.equals("Bitcoin Forum Guest")) {
                        posterActivityStr = posterText.substring(posterText.indexOf("Activity"),
                                posterText.indexOf(" ", posterText.indexOf("Activity") + 10));
                        posterPersText = posterText.substring(
                                posterText.indexOf(posterActivityStr) + posterActivityStr.length(),
                                posterText.lastIndexOf("Trust"));
                    } else {
                        posterName = "Bitcoin Forum";
                    }

                    // Get rank
                    String posterRank = "Brand New";
                    if (posterText.contains("Brand New"))
                        posterRank = "Brand New";
                    else if (posterText.contains("Newbie"))
                        posterRank = "Newbie";
                    else if (posterText.contains("Jr. Member"))
                        posterRank = "Jr. Member";
                    else if (posterText.contains("Full Member"))
                        posterRank = "Full Member";
                    else if (posterText.contains("Sr. Member"))
                        posterRank = "Sr. Member";
                    else if (posterText.contains("Hero Member"))
                        posterRank = "Hero Member";
                    else if (posterText.contains("Legendary"))
                        posterRank = "Legendary";
                    else if (posterText.contains("Member"))
                        posterRank = "Member";
                    else if (posterText.contains("Guest"))
                        posterRank = "Guest";
                    // get special positions
                    String specialPosition = null;
                    if (posterText.contains("Staff"))
                        specialPosition = "Staff";
                    else if (posterText.contains("Global Moderator"))
                        specialPosition = "Global Moderator";
                    else if (posterText.contains("Moderator"))
                        specialPosition = "Moderator";
                    else if (posterText.contains("Administrator"))
                        specialPosition = "Administrator";
                    else if (posterText.contains("Founder"))
                        specialPosition = "Founder";
                    else if (posterText.contains(" Donator"))
                        specialPosition = "Donator";
                    else if (posterText.contains("VIP"))
                        specialPosition = "VIP";

                    // Get poster avatar
                    Elements avatarImgs = posterInfo.select("img.avatar");
                    BitmapDrawable avatar = null;
                    if (!avatarImgs.isEmpty()) {
                        // Get avatar element data
                        Element avatarImg = avatarImgs.first();
                        String avatarURL = avatarImg.absUrl("src");

                        // Download avatar
                        URL url = new URL(avatarURL);
                        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                        connection.setDoInput(true);
                        connection.connect();
                        InputStream input = connection.getInputStream();
                        avatar = new BitmapDrawable(getResources(), input);
                        avatar.setBounds(0, 0, avatar.getIntrinsicWidth() * 100, avatar.getIntrinsicHeight() * 100);
                    }

                    // Create poster object
                    Poster poster = new Poster(posterName, avatar, posterPersText, posterActivityStr, posterRank);
                    if (specialPosition != null)
                        poster.setSpecialPos(specialPosition);

                    // Get header element
                    Element pmHead = post.select("td.windowbg > table > tbody > tr > td[align=left]").first();

                    if (pmHead == null)
                        pmHead = post.select("td.windowbg2 > table > tbody > tr > td[align=left]").first();

                    // Get header right
                    Element pmHeadRight = post.select("td.windowbg > table > tbody > tr > td[align=right]").first();
                    if (pmHeadRight == null)
                        pmHeadRight = post.select("td.windowbg2 > table > tbody > tr > td[align=right]").first();

                    // Get quote reply and delete strings
                    String quoteURL = pmHeadRight.select("a[href]").first().attr("href");
                    String replyURL = pmHeadRight.select("a[href]").get(1).attr("href");
                    String deleteURL = pmHeadRight.select("a[href]").get(2).attr("href");

                    // Get subject and post times
                    String subject = pmHead.select("b").first().text();
                    String pmedTime = pmHead.text().replaceAll(subject, "");

                    // Get elements with post and header
                    Element pm = post.select("div.personalmessage").first();

                    // Get body of post
                    String postBodyStr = pm.html();
                    Spanned postBody = Html.fromHtml(postBodyStr, new ImageGetter(), null);

                    // Create post object
                    Post postObj = new Post(poster, pmedTime, subject, postBody, ids.get(i), quoteURL, replyURL,
                            deleteURL);
                    posts.add(postObj);
                }

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

            return posts;
        }

        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<Post> result) {
            showProgress(false);
            mGetPMsTask = null;

            if (mPageNum == 1) {
                mPrevButton.setClickable(false);
                mPrevButton.setVisibility(View.GONE);
                if (result.size() < 20) {
                    mNextButton.setClickable(false);
                    mNextButton.setVisibility(View.GONE);
                } else {
                    mNextButton.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            mListener.onPMPageSelected(mPageNum + 1);
                        }
                    });
                }
            } else {
                if (result.size() <= 20) {
                    mNextButton.setClickable(false);
                    mNextButton.setVisibility(View.GONE);
                    mPrevButton.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            mListener.onPMPageSelected(mPageNum - 1);
                        }
                    });
                } else {
                    mPrevButton.setClickable(true);
                    mNextButton.setClickable(true);
                    mPrevButton.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            mListener.onPMPageSelected(mPageNum - 1);
                        }
                    });
                    mNextButton.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            mListener.onPMPageSelected(mPageNum + 1);
                        }
                    });
                }
            }

            PostsListAdapter mAdapter = new PostsListAdapter(result);
            mListView.setAdapter(mAdapter);
        }

        @Override
        protected void onCancelled() {
            mGetPMsTask = null;
            showProgress(false);
        }
    }

    private class DeleteReply extends AsyncTask<Void, Void, Void> {
        private String deleteURL;
        private String sessId;

        public DeleteReply(String deleteURL, String sessId) {
            this.deleteURL = deleteURL;
            this.sessId = sessId;
        }

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

            try {
                Document deleteDoc = Jsoup.connect(deleteURL).cookie("PHPSESSID", sessId).get();
            } catch (IOException e) {
                e.printStackTrace();
            }

            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            mListener.onPMPageSelected(0);
        }
    }

}