package Twitter_Control_Panel;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URLDecoder;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import twitter4j.Query;
import twitter4j.QueryResult;
import twitter4j.Status;
import twitter4j.Tweet;
import twitter4j.Twitter;
import twitter4j.TwitterException;
import twitter4j.TwitterFactory;
import twitter4j.User;
import twitter4j.http.AccessToken;
import twitter4j.http.RequestToken;
import com.extentech.ExtenXLS.ExcelTools;
import com.extentech.toolkit.Logger;
import com.extentech.toolkit.StringTool;
/**
* This class is the server-side controller for the Sheetster Twitter Control
* Panel Doc App
*
* Combined with a "Control Panel" spreadsheet, this program will provide the
* following services:
*
* - Provide data feeds of interesting statistical data for reporting in
* Sheetster - Provide watch lists and keyword searches that can be used to: a)
* search for a list of keywords in the tweets of new followers, triggering alt
* reply messages and workflows b) search for a list of keywords in the tweets
* of current followers and watched/followed users, triggering alerts and
* workflows - Report and monitor SEO metrics such as "Follower vs. Followed"
* and "Influence among Influencers" - Allow for automated tweeting from a
* canned list of tweets, on a schedule or in re: to watched lists of keywords,
* users
*
*
* @author John McMahon :: Jun 14, 2011 :: Copyright ©2011 Extentech Inc.
*
*/
public class Tweetster extends SheetsterRESTClient {
private Date lastTweetDate = null; // the time of the current tweet
private String lastTweet = "Sheetster FTW!"; // the current tweet "status line"
private String userName = ""; // the twitter user name
private long updateInterval = 0000l; // default 3 seconds
private boolean running = true; // running flag
// maintain the location of important cells here
private static String DOCUMENT_ID = "34"; // change to your doc id
private static String SHEET_CONTROL = "Control Panel";
private static String SHEET_DATA = "data";
private static String CELL_USERNAME = "D5";
private static String CELL_LASTTWEET = "D6";
private static String CELL_LASTMENTION = "D7";
private static String CELL_DATA_DATE = "G5";
private static String CELL_FOLLOWING_CT = "G6";
private static String CELL_FOLLOWER_CT = "G7";
private static String CELL_CURRENT_TWEET = "C9";
private static String NAME_WATCHLIST = "watchlist";
private static String NAME_KEYWORDLIST = "keywords";
private static String NAME_AUTO_TWEET = "auto_tweet_content";
private static String NAME_AUTO_TWEET_DT = "auto_tweet_date";
/**
* @return Returns the running.
*/
public boolean isRunning() {
return running;
}
/**
* @param running
* The running to set.
*/
public void setRunning(boolean running) {
this.running = running;
}
/**
* @return Returns the updateInterval.
*/
public long getUpdateInterval() {
return updateInterval;
}
/**
* @param updateInterval
* The updateInterval to set.
*/
public void setUpdateInterval(long updateInterval) {
this.updateInterval = updateInterval;
}
/**
* @return Returns the lastTweet.
*/
public String getlastTweet() {
return lastTweet;
}
/**
* @param lastTweet
* The lastTweet to set.
*/
public void setlastTweet(String lastTweet) {
this.lastTweet = lastTweet;
}
/**
* @return Returns the twitter.
*/
public Twitter getTwitter() {
return twitter;
}
/**
* @param twitter
* The twitter to set.
*/
public void setTwitter(Twitter twitter) {
this.twitter = twitter;
}
private Twitter twitter;
/**
* Create a new Tweetster Instance
*
* @param twc
* the twitter client
* @throws Exception
*/
public Tweetster() throws Exception {
init();
}
/**
* launch the Tweetster process
*
* @param args
*/
public static void main(String args[]) {
try {
Tweetster tweets = new Tweetster();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* Initialize the server communication
* @throws Exception
*
*/
private void init() throws Exception {
// defaults
setMemeId(DOCUMENT_ID); // the id of the previously uploaded Sheetster template (Sheetster_Twitter_Control_Panel.v2.xlsx
authenticate();
try {
// The factory instance is re-useable and thread safe.
twitter = new TwitterFactory().getInstance();
// insert the appropriate consumer key and consumer secret here
twitter.setOAuthConsumer("",
"");
RequestToken requestToken;
requestToken = twitter.getOAuthRequestToken();
AccessToken accessToken = null;
BufferedReader br = new BufferedReader(new InputStreamReader(
System.in));
while (null == accessToken) {
System.out
.println("Open the following URL and grant access to your account:");
String orul = requestToken.getAuthorizationURL();
Logger.logInfo(orul);
launchBrowser(orul);
System.out
.print("Enter the PIN(if aviailable) or just hit enter.[PIN]:");
String pin = br.readLine();
try {
if (pin.length() > 0) {
accessToken = twitter.getOAuthAccessToken(requestToken,
pin);
} else {
accessToken = twitter.getOAuthAccessToken();
}
} catch (TwitterException te) {
if (401 == te.getStatusCode()) {
Logger.logInfo("Unable to get the access token.");
} else {
te.printStackTrace();
}
}
}
// persist to the accessToken for future reference.
Logger.logInfo(String.valueOf(twitter.verifyCredentials().getId()));
Logger.logInfo("token : " + accessToken.getToken());
Logger.logInfo("tokenSecret : " + accessToken.getTokenSecret());
mainLoop();
} catch (IOException e) {
Logger.logErr("Problem running Tweetster.", e);
} catch (TwitterException ex) {
Logger.logErr("Fatal Error with Twitter Client.", ex);
}
System.exit(0);
}
/**
* the main program logic loop, runs until exit()
*
*/
public void mainLoop() {
while (isRunning()) {
try {
// TODO: avail ourselves of these
// twitter.getId()
// twitter.getIncomingFriendships(cursor);
// ResponseList blockingUserList = twitter.getBlockingUsers();
// AccountTotals acctjson = twitter.getAccountTotals();
// UserStreamListener usl = twitter.getUserListMembers(listOwnerScreenName, listId, cursor)
// usl.onFollow(arg0, arg1);
// twitter.createFriendship(userId);
// process main tasks
Logger.logInfo("Authenticating User");
authenticate();
// update the static fields in the sheet
setSheetname(SHEET_CONTROL);
Logger.logInfo("Accessing Timeline");
List statuses = twitter.getUserTimeline();
// get the Twitter user account object
User uxr = null;
if(statuses != null &&
statuses.size()>0)
uxr = statuses.get(0).getUser();
// for (Status status : statuses) { // process all lastTweets
// Logger.logInfo(status.getUser().getName() + ":" +
// status.getText());
// }
this.addCell(Tweetster.CELL_USERNAME, uxr.getScreenName());
this.userName = this.getCell(Tweetster.CELL_USERNAME).toString();
this.addCell(Tweetster.CELL_FOLLOWING_CT, uxr.getFriendsCount()); // friends are followers? ok.
this.addCell(Tweetster.CELL_FOLLOWER_CT, uxr.getFollowersCount());
// spreadsheets FTW!
Date cal = new Date();
this.addCell(Tweetster.CELL_DATA_DATE, cal.toLocaleString()); // TODO: get a better calendar
if(statuses.size()>0){
this.lastTweet = statuses.get(0).getText();
this.lastTweet = URLDecoder.decode(this.lastTweet, "utf-8"); // TODO: improve this.
this.addCell(Tweetster.CELL_CURRENT_TWEET, lastTweet);
this.lastTweetDate = statuses.get(0).getCreatedAt();
this.addCell(Tweetster.CELL_LASTTWEET, lastTweetDate);
}
setSheetname(SHEET_DATA);
// perform searches on users and keywords
// this can get interesting... very interesting.
TreeMap keywordTweets = new TreeMap();
String[] keywords = this.getList(this.NAME_KEYWORDLIST);
Object[][] tweets;
for(String k : keywords){
k = StringTool.allTrim(k);
k = StringTool.strip(k, "'");
if(k.length()>2){
Logger.logInfo("Searching tweets containing: " + k);
try{ // touchy
tweets = searchTweets(k);
for(Object[] t : tweets){
// TODO: analysis etc.
Logger.logInfo("Tweet from " + t[0] + ": " +t[1]);
keywordTweets.put(t[0], t[1]); // deduped and sorted... we want the users more than tweets...
// this.addCell(celladdr, val)
Object[] objarr = {t[0], t[1]};
for(int x=0;x