package org.sakaiproject.profile2.logic;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.sakaiproject.profile2.dao.ProfileDao;
import org.sakaiproject.profile2.model.ExternalIntegrationInfo;
import org.sakaiproject.profile2.util.ProfileConstants;
import org.sakaiproject.profile2.util.ProfileUtils;
import twitter4j.Twitter;
import twitter4j.TwitterException;
import twitter4j.TwitterFactory;
import twitter4j.http.AccessToken;
/**
* Implementation of ProfileExternalIntegrationLogic API
*
* @author Steve Swinsburg (steve.swinsburg@gmail.com)
*
*/
public class ProfileExternalIntegrationLogicImpl implements ProfileExternalIntegrationLogic {
private static final Logger log = Logger.getLogger(ProfileExternalIntegrationLogicImpl.class);
/**
* OAuth Consumer registration details for Profile2.
*/
private final String TWITTER_OAUTH_CONSUMER_KEY="XzSPZIj0LxNaaoBz8XrgZQ";
private final String TWITTER_OAUTH_CONSUMER_SECRET="FSChsnmTufYi3X9H25YdFRxBhPXgnh2H0lMnLh7ZVG4";
/**
* {@inheritDoc}
*/
public ExternalIntegrationInfo getExternalIntegrationInfo(String userUuid) {
ExternalIntegrationInfo info = dao.getExternalIntegrationInfo(userUuid);
if(info != null) {
return info;
}
return getDefaultExternalIntegrationInfo(userUuid);
}
/**
* {@inheritDoc}
*/
public boolean updateExternalIntegrationInfo(ExternalIntegrationInfo info) {
if(dao.updateExternalIntegrationInfo(info)){
log.info("ExternalIntegrationInfo updated for user: " + info.getUserUuid());
return true;
}
return false;
}
/**
* {@inheritDoc}
*/
public Map<String,String> getTwitterOAuthConsumerDetails() {
Map<String,String> map = new HashMap<String,String>();
map.put("key", sakaiProxy.getServerConfigurationParameter("profile2.twitter.oauth.key", TWITTER_OAUTH_CONSUMER_KEY));
map.put("secret", sakaiProxy.getServerConfigurationParameter("profile2.twitter.oauth.secret", TWITTER_OAUTH_CONSUMER_SECRET));
return map;
}
/**
* {@inheritDoc}
*/
public String getTwitterName(ExternalIntegrationInfo info) {
if(info == null){
return null;
}
//get values
String token = info.getTwitterToken();
String secret = info.getTwitterSecret();
if(StringUtils.isNotBlank(token) && StringUtils.isNotBlank(secret)) {
//global config
Map<String,String> config = getTwitterOAuthConsumerDetails();
//token for user
AccessToken accessToken = new AccessToken(token, secret);
//setup
Twitter twitter = new TwitterFactory().getOAuthAuthorizedInstance(config.get("key"), config.get("secret"), accessToken);
//check
try {
return twitter.verifyCredentials().getScreenName();
} catch (TwitterException e) {
log.error("Error retrieving Twitter credentials: " + e.getClass() + ": " + e.getMessage());
}
}
return null;
}
/**
* {@inheritDoc}
*/
public boolean validateTwitterCredentials(ExternalIntegrationInfo info) {
return StringUtils.isNotBlank(getTwitterName(info));
}
/**
* {@inheritDoc}
*/
public void sendMessageToTwitter(final String userUuid, String message){
//setup class thread to call later
class TwitterUpdater implements Runnable{
private Thread runner;
private String userUuid;
private String userToken;
private String userSecret;
private String message;
public TwitterUpdater(String userUuid, String userToken, String userSecret, String message) {
this.userUuid=userUuid;
this.userToken=userToken;
this.userSecret=userSecret;
this.message=message;
runner = new Thread(this,"Profile2 TwitterUpdater thread");
runner.start();
}
//do it!
public synchronized void run() {
//global config
Map<String,String> config = getTwitterOAuthConsumerDetails();
//token for user
AccessToken accessToken = new AccessToken(userToken, userSecret);
//setup
Twitter twitter = new TwitterFactory().getOAuthAuthorizedInstance(config.get("key"), config.get("secret"), accessToken);
try {
twitter.updateStatus(message);
log.info("Twitter status updated for: " + userUuid);
//post update event
sakaiProxy.postEvent(ProfileConstants.EVENT_TWITTER_UPDATE, "/profile/"+userUuid, true);
}
catch (Exception e) {
log.error("ProfileLogic.sendMessageToTwitter() failed. " + e.getClass() + ": " + e.getMessage());
}
}
}
//is twitter enabled
if(!sakaiProxy.isTwitterIntegrationEnabledGlobally()){
return;
}
//get user info
ExternalIntegrationInfo info = getExternalIntegrationInfo(userUuid);
if(info == null){
return;
}
String token = info.getTwitterToken();
String secret = info.getTwitterSecret();
if(StringUtils.isBlank(token) || StringUtils.isBlank(secret)) {
return;
}
//PRFL-423 limit to 140 chars
//Hardcoded limit because 140 is the Twitter requirement so no need to make configurable
message = ProfileUtils.truncate(message, 140, false);
//instantiate class to send the data
new TwitterUpdater(userUuid, token, secret, message);
}
/**
* Get a default record, will only contain the userUuid
* @param userUuid
* @return
*/
private ExternalIntegrationInfo getDefaultExternalIntegrationInfo(String userUuid) {
ExternalIntegrationInfo info = new ExternalIntegrationInfo();
info.setUserUuid(userUuid);
return info;
}
private ProfileDao dao;
public void setDao(ProfileDao dao) {
this.dao = dao;
}
private SakaiProxy sakaiProxy;
public void setSakaiProxy(SakaiProxy sakaiProxy) {
this.sakaiProxy = sakaiProxy;
}
}