Java tutorial
/* * Copyright 2010 Nabeel Mukhtar * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package com.appspot.bitlyminous.handler.twitter; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Map.Entry; import java.util.logging.Level; import twitter4j.Status; import twitter4j.StatusUpdate; import twitter4j.Twitter; import twitter4j.TwitterFactory; import twitter4j.conf.ConfigurationBuilder; import twitter4j.http.AccessToken; import twitter4j.http.OAuthAuthorization; import com.appspot.bitlyminous.constant.ApplicationConstants; import com.appspot.bitlyminous.constant.ApplicationResources; import com.appspot.bitlyminous.entity.Story; import com.appspot.bitlyminous.entity.Tag; import com.appspot.bitlyminous.entity.Tags; import com.appspot.bitlyminous.entity.Url; import com.appspot.bitlyminous.entity.User; import com.appspot.bitlyminous.gateway.DeliciousGateway; import com.appspot.bitlyminous.gateway.DiggGateway; import com.appspot.bitlyminous.gateway.GatewayFactory; import com.appspot.bitlyminous.service.RecommendationService; import com.appspot.bitlyminous.service.ServiceFactory; import com.googleapis.ajax.common.PagedList; import com.googleapis.ajax.schema.WebResult; import com.googleapis.ajax.services.WebSearchQuery; /** * The Class TweetForMeHandler. */ public class TweetForMeHandler extends AbstractTwitterHandler { /** The Constant GATEWAY_FACTORY. */ private static final GatewayFactory GATEWAY_FACTORY = GatewayFactory.newInstance(); /** * Instantiates a new tweet for me handler. * * @param commandName the command name * @param context the context */ public TweetForMeHandler(String commandName, TwitterContext context) { super(commandName, context); } /* (non-Javadoc) * @see com.appspot.bitlyminous.handler.twitter.TwitterHandler#execute(twitter4j.Status) */ @Override public StatusUpdate execute(Status tweet) { try { User user = context.getUser(); if (user == null) { user = getUserByScreenName(tweet.getUser().getScreenName()); context.setUser(user); } if (user == null || user.getTwitterToken() == null || user.getTwitterSecret() == null) { StatusUpdate reply = new StatusUpdate( ApplicationResources.getLocalizedString("com.appspot.bitlyminous.message.notAuthenticated", new String[] { "@" + tweet.getUser().getScreenName(), "Twitter", shortenUrl(ApplicationConstants.TWITTER_CALLBACK_URL) })); reply.setInReplyToStatusId(tweet.getId()); return reply; } else { Twitter twitter = getTwitterClient(user.getTwitterToken().getValue(), user.getTwitterSecret().getValue()); String status = buildStatus(user.getUrls(), user.getTags()); if (status != null) { StatusUpdate reply = new StatusUpdate(status); reply.setInReplyToStatusId(tweet.getId()); twitter.updateStatus(reply); } return null; } } catch (Exception e) { logger.log(Level.SEVERE, "Error while tweeting on behalf of user.", e); } return null; } /** * Builds the status. * * @param urls the urls * @param tags the tags * * @return the string */ private String buildStatus(List<Url> urls, Tags tags) { if (tags != null) { DeliciousGateway deliciousGateway = getDeliciousGateway(); DiggGateway diggGateway = getDiggGateway(); urls = topUrls(urls, 3); List<Tag> tagList = topTags(tags.getTag(), 3); for (Url entity : urls) { WebSearchQuery googleQuery = getGoogleWebSearchQuery(); googleQuery.withRelatedSite(entity.getUrl()); List<Url> relatedUrls = new ArrayList<Url>(); if (!tagList.isEmpty()) { for (Tag tag : tagList) { try { relatedUrls.addAll(deliciousGateway.getPopularUrls(tag.getTag())); relatedUrls.addAll(convertToUrls(diggGateway.getPopularStories(tag.getTag(), 5))); } catch (Exception e) { logger.log(Level.WARNING, "Error while getting related urls.", e); } } relatedUrls.addAll(convertToUrls(googleQuery.withQuery(createQuery(tagList)).list())); relatedUrls = getBestMatches(entity, relatedUrls, 1); } if (!relatedUrls.isEmpty()) { StringBuilder builder = new StringBuilder(); builder.append(trimText(relatedUrls.get(0).getDescription(), 100)); builder.append("..."); builder.append(shortenUrl(relatedUrls.get(0).getUrl())); return builder.toString(); } } } return null; } /** * Top tags. * * @param tags the tags * @param count the count * * @return the list< tag> */ private List<Tag> topTags(List<Tag> tags, int count) { Collections.sort(tags, new Comparator<Tag>() { @Override public int compare(Tag o1, Tag o2) { return o2.getCount().compareTo(o1.getCount()); } }); List<Tag> retValue = new ArrayList<Tag>(); for (int i = 0; i < tags.size() && i < count; i++) { retValue.add(tags.get(i)); } return retValue; } /** * Top urls. * * @param urls the urls * @param count the count * * @return the list< url> */ private List<Url> topUrls(List<Url> urls, int count) { Collections.sort(urls, new Comparator<Url>() { @Override public int compare(Url o1, Url o2) { return o2.getDateSubmitted().compareTo(o1.getDateSubmitted()); } }); List<Url> retValue = new ArrayList<Url>(); for (int i = 0; i < urls.size() && i < count; i++) { retValue.add(urls.get(i)); } return retValue; } /** * Gets the twitter client. * * @param token the token * @param tokenSecret the token secret * * @return the twitter client */ protected Twitter getTwitterClient(String token, String tokenSecret) { return new TwitterFactory().getInstance(new OAuthAuthorization(new ConfigurationBuilder().build(), ApplicationConstants.TWITTER_CONSUMER_KEY, ApplicationConstants.TWITTER_CONSUMER_SECRET, new AccessToken(token, tokenSecret))); } /** * Gets the best matches. * * @param url the url * @param relatedUrls the related urls * @param count the count * * @return the best matches */ private List<Url> getBestMatches(Url url, List<Url> relatedUrls, int count) { RecommendationService recommendationService = ServiceFactory.newInstance().createRecommendationService(); List<Entry<Url, Double>> urlSimilarities = recommendationService.getUrlSimilarities(url, relatedUrls); List<Url> similarUrls = new ArrayList<Url>(); for (int i = 0; i < urlSimilarities.size() && i < count; i++) { similarUrls.add(urlSimilarities.get(i).getKey()); } return similarUrls; } /** * Gets the delicious gateway. * * @return the delicious gateway */ protected DeliciousGateway getDeliciousGateway() { return GATEWAY_FACTORY.createDeliciousGateway(ApplicationConstants.DELICIOUS_CONSUMER_KEY, ApplicationConstants.DELICIOUS_CONSUMER_SECRET, "dummy-access-token", "dummy-token-secret"); } /** * Gets the digg gateway. * * @return the digg gateway */ protected DiggGateway getDiggGateway() { return GATEWAY_FACTORY.createDiggGateway(ApplicationConstants.DIGG_CONSUMER_KEY, ApplicationConstants.DIGG_CONSUMER_SECRET, ApplicationConstants.DIGG_ACCESS_TOKEN, ApplicationConstants.DIGG_ACCESS_TOKEN_SECRET); } /** * Convert to urls. * * @param results the results * * @return the list< url> */ private List<Url> convertToUrls(PagedList<WebResult> results) { List<Url> urls = new ArrayList<Url>(); for (WebResult result : results) { Url url = new Url(); url.setDescription(result.getTitleNoFormatting()); url.setUrl(result.getUnescapedUrl()); urls.add(url); } return urls; } /** * Convert to urls. * * @param popularStories the popular stories * * @return the list< url> */ private List<Url> convertToUrls(List<Story> popularStories) { List<Url> urls = new ArrayList<Url>(); for (Story story : popularStories) { Url url = new Url(); url.setDescription(story.getDescription()); url.setUrl(story.getLink()); urls.add(url); } return urls; } /** * Creates the query. * * @param tags the tags * * @return the string */ private String createQuery(List<Tag> tags) { StringBuilder builder = new StringBuilder(); boolean first = true; for (Tag tag : tags) { if (!first) { builder.append(" OR "); } builder.append(tag.getTag()); first = false; } return builder.toString(); } }