org.manalith.ircbot.plugin.tweetreader.TweetReader.java Source code

Java tutorial

Introduction

Here is the source code for org.manalith.ircbot.plugin.tweetreader.TweetReader.java

Source

/*
org.manalith.ircbot.plugin.twitreader/TwitReaderRunner.java
ManalithBot - An open source IRC bot based on the PircBot Framework.
Copyright (C) 2011, 2012  Seong-ho, Cho <darkcircle.0426@gmail.com>
    
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 org.manalith.ircbot.plugin.tweetreader;

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

import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.PropertiesConfiguration;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.jsoup.Jsoup;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.htmlunit.HtmlUnitDriver;

import twitter4j.ResponseList;
import twitter4j.Status;
import twitter4j.Twitter;
import twitter4j.TwitterException;
import twitter4j.TwitterFactory;
import twitter4j.auth.AccessToken;
import twitter4j.auth.RequestToken;
import twitter4j.conf.Configuration;
import twitter4j.conf.ConfigurationBuilder;

public class TweetReader {

    public static enum TwitterUrlType {
        UserHome("http(s)?\\:\\/\\/twitter\\.com\\/(\\#\\!\\/)?([a-zA-Z0-9\\_]{1,15}(\\/)?){1}"), Tweet(
                "http(s)?\\:\\/\\/twitter\\.com\\/(\\#\\!\\/)?[a-zA-Z0-9\\_]{1,15}\\/status\\/[0-9]+"), Photo(
                        "http(s)?\\:\\/\\/twitter\\.com\\/(\\#\\!\\/)?[a-zA-Z0-9\\_]{1,15}\\/status\\/[0-9]+/photo/[0-9]{1}(/|(/large))?");

        Pattern pattern;

        TwitterUrlType(String textPattern) {
            pattern = Pattern.compile(textPattern);
        }
    }

    private static final String TARGET_DATE_PATTERN = "yyyy MM dd? E? HH:mm:ss";

    private String consumerKey;
    private String consumerSecret;
    private String username;
    private String password;

    private PropertiesConfiguration config;

    private WebDriver driver;
    private JavascriptExecutor jse;

    private Twitter tweet;
    private RequestToken requestToken;

    public TweetReader(String resourcePath, String consumerKey, String consumerSecret)
            throws ConfigurationException {

        try {
            config = new PropertiesConfiguration(resourcePath + "keybox.property");
        } catch (ConfigurationException e) {
            config = new PropertiesConfiguration();
            config.setFile(new File(resourcePath + "keybox.property"));
            config.save();
        }

        setConsumerKey(consumerKey);
        setConsumerSecret(consumerSecret);
    }

    public void setConsumerKey(String consumerKey) {
        this.consumerKey = consumerKey;
    }

    public void setConsumerSecret(String consumerSecret) {
        this.consumerSecret = consumerSecret;
    }

    public void setTwitterUsernameOrEmail(String username) {
        this.username = username;
    }

    public void setTwitterPassword(String password) {
        this.password = password;
    }

    private void setAcecssToken(String accessToken, String accessSecret) {
        setAccessToken(new AccessToken(accessToken, accessSecret));
    }

    private void setAccessToken(AccessToken accessToken) {
        tweet.setOAuthAccessToken(accessToken);
    }

    private enum UrlType {
        TweetURL, UserURL, PhotoURL
    }

    private void initWebAutomateObject() {
        driver = new HtmlUnitDriver();
        ((HtmlUnitDriver) driver).setJavascriptEnabled(true);
        jse = (JavascriptExecutor) driver;
    }

    private void initTwitter4j() throws TwitterException {
        ConfigurationBuilder builder = new ConfigurationBuilder();
        Configuration config = builder.setDebugEnabled(false).setJSONStoreEnabled(true)
                .setOAuthConsumerKey(consumerKey).setOAuthConsumerSecret(consumerSecret).build();

        tweet = new TwitterFactory(config).getInstance();
        requestToken = tweet.getOAuthRequestToken();
    }

    private String getTwitterAuthorizationPINPageSource() {
        String url = requestToken.getAuthenticationURL();
        driver.get(url);
        jse.executeScript("document.getElementById('username_or_email').setAttribute('value','" + username + "')"); // Twitter ID
        jse.executeScript("document.getElementById('password').setAttribute('value','" + password + "')"); // Twitter Password
        jse.executeScript("document.getElementById('allow').click()");
        driver.getPageSource();

        return driver.getPageSource();
    }

    private String getTwitterAuthPINString() throws TwitterException {
        return Jsoup.parse(getTwitterAuthorizationPINPageSource()).getAllElements()
                .select("div#oauth_pin>p>kbd>code").text();

    }

    private void authorizeTwitter() throws TwitterException, ConfigurationException {
        // init selenium web automation object
        initWebAutomateObject();

        // to success authorization for owners' twitter account
        AccessToken accessToken = tweet.getOAuthAccessToken(requestToken, getTwitterAuthPINString());

        setAccessToken(accessToken);
        tweet.verifyCredentials().getId(); // pass.

        config.setProperty("com.twitter.accessKey", accessToken.getToken());
        config.setProperty("com.twitter.accessSecret", accessToken.getTokenSecret());
        config.save();

    }

    private Status getStatus(String url, UrlType type) throws TwitterException {
        Status stat = null;
        String[] urlArray = url.split("\\/");

        switch (type) {
        case TweetURL:
        case PhotoURL:
            int statusIdIdx = 0;
            for (; statusIdIdx < urlArray.length; statusIdIdx++)
                if (urlArray[statusIdIdx++].equals("status"))
                    break;

            long tweetId = NumberUtils.toLong(urlArray[statusIdIdx]);
            stat = tweet.showStatus(tweetId);

            if (stat == null)
                return null;

            break;
        case UserURL:
            String screenName = urlArray[urlArray.length - 1];
            ResponseList<Status> resp = tweet.getUserTimeline(screenName);

            if (resp.size() == 0)
                return null;

            stat = resp.get(0);
            break;
        }

        return stat;
    }

    private String getText(String twitterurl, UrlType type) {
        if (type == null)
            return null;

        // init twitter4j
        try {
            initTwitter4j();
        } catch (TwitterException e) {
            return e.getMessage();
        }

        if (StringUtils.isEmpty(config.getString("com.twitter.accessKey"))
                || StringUtils.isEmpty(config.getString("com.twitter.accessSecret"))) {
            try {
                authorizeTwitter();
            } catch (TwitterException e) {
                return "[twitter4j.TwitterException] " + e.getMessage();
            } catch (ConfigurationException e) {
                return "[org.apache.common.configuration.ConfigutaionException] " + e.getMessage();
            }
        } else {
            String accessToken = config.getString("com.twitter.accessKey");
            String accessSecret = config.getString("com.twitter.accessSecret");

            setAcecssToken(accessToken, accessSecret);
        }

        Status stat = null;
        try {
            stat = getStatus(twitterurl, type);
        } catch (TwitterException e) {
            return "[twitter4j.TwitterException] " + e.getMessage();
        }

        if (stat == null)
            return null;

        String author = stat.getUser().getName();
        String createdAt = DateFormatUtils.format(stat.getCreatedAt(), TARGET_DATE_PATTERN);
        String message = stat.getText();

        return String.format("?: %s, ?: %s, : %s", author, createdAt, message);
    }

    private UrlType validateUrl(String url) {
        if (StringUtils.isEmpty(url))
            return null;

        if (TwitterUrlType.Tweet.pattern.matcher(url).matches())
            return UrlType.TweetURL;

        if (TwitterUrlType.UserHome.pattern.matcher(url).matches())
            return UrlType.UserURL;

        if (TwitterUrlType.Photo.pattern.matcher(url).matches())
            return UrlType.PhotoURL;

        return null;
    }

    public String read(String[] strs) {
        for (String str : strs) {
            String result = getText(str, validateUrl(str));
            if (result != null)
                return result;
        }

        return null;
    }
}