/* * Copyright 2012 Feedlr * * 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.chalmers.feedlr.client; import java.util.ArrayList; import java.util.List; import org.scribe.exceptions.OAuthException; import org.scribe.model.OAuthRequest; import org.scribe.model.Response; import org.scribe.model.Token; import org.scribe.model.Verb; import org.scribe.oauth.OAuthService; import com.chalmers.feedlr.listener.RequestListener; import com.chalmers.feedlr.model.TwitterItem; import com.chalmers.feedlr.model.User; import com.chalmers.feedlr.parser.TwitterJSONParser; import com.chalmers.feedlr.util.ClientStore; import android.content.Context; import android.util.Log; public class TwitterHelper { //Constants public static final String CREDENTIALS = "https://api.twitter.com/1.1/account/verify_credentials.json"; public static final String TIMELINE = "https://api.twitter.com/1/statuses/home_timeline.json?include_entities=false&exclude_replies=true&count=100&include_rts=false"; public static final String USER_IDS = "https://api.twitter.com/1.1/friends/ids.json?user_id="; public static final String USER_NAMES = "https://api.twitter.com/1.1/users/lookup.json?include_entities=false&user_id="; public static final String USER_TWEETS = "https://api.twitter.com/1.1/statuses/user_timeline.json?contributor_details=false&exclude_replies=true&trim_user=false&count=100&user_id="; private OAuthService twitter; private Context context; public TwitterHelper(Context context) { twitter = Clients.getTwitter(); this.context = context; } /* * Makes the class run in a new thread. * * @param Runnable */ private void runAsync(final Runnable runnable) { new Thread() { @Override public void run() { runnable.run(); } }.start(); } /* * Sends a request to Twitter for the users "timeline". This includes posts from * those the user have chosen to follow on Twitter. * * @return List<TwitterItem> containing all the posts. */ public List<TwitterItem> getTimeline() { long time = System.currentTimeMillis(); String response = request(TIMELINE); if (response == null) { return null; } Log.i(TwitterJSONParser.class.getName(), "Timeline request time in millis: " + (System.currentTimeMillis() - time)); return new TwitterJSONParser().parseTweets(response); } /* * Sends a request to Twitter to get a specified user tweets. * * @return List<TwitterItem> containing all the posts of a specified user. */ public List<TwitterItem> getUserTweets(String userID) { long time = System.currentTimeMillis(); StringBuilder url = new StringBuilder(); url.append(USER_TWEETS).append(userID); String response = request(url.toString()); if (response == null) { return null; } Log.i(TwitterJSONParser.class.getName(), "User tweets request time in millis: " + (System.currentTimeMillis() - time)); return new TwitterJSONParser().parseTweets(response); } /* * Sends a request to Twitter to get all the twitter users that * the user currently follows. * * @return List<User> */ public List<User> getFollowing() { long time = System.currentTimeMillis(); long userID = getAuthorizedUserID(); if (userID == 0) { return null; } StringBuilder url = new StringBuilder(); url.append(USER_IDS).append(userID); String response = request(url.toString()); if (response == null) { return null; } Log.i(TwitterJSONParser.class.getName(), "ID request time in millis: " + (System.currentTimeMillis() - time)); String[] ids = new TwitterJSONParser().parseUserIDs(response); return getTwitterUserNamesFromID(ids); } /* * Get the authorized user ID registered with Twitter. * * @return long with the User ID. */ private long getAuthorizedUserID() { long userID = ClientStore.getTwitterUserID(context); if (userID != 0) { return userID; } long time = System.currentTimeMillis(); String response = request(CREDENTIALS); if (response == null) { return 0; } Log.i(TwitterJSONParser.class.getName(), "Credentials request time in millis: " + (System.currentTimeMillis() - time)); userID = new TwitterJSONParser().parseCredentials(response); ClientStore.saveTwitterUserID(userID, context); return userID; } /* * Sends a request to Twitter to get the user names from a specified twitter ID. * * @param String[] of IDs to be used in the request. * * @return A List of users. */ private List<User> getTwitterUserNamesFromID(String[] ids) { final List<User> users = new ArrayList<User>(); StringBuilder url = new StringBuilder(); url.append(USER_NAMES); url.append(ids[0]); for (int i = 1; i < ids.length; i++) { if (i % 100 == 0) { String response = request(url.toString()); users.addAll(new TwitterJSONParser().parseUserNames(response)); url = new StringBuilder(); url.append(USER_NAMES); url.append(ids[i]); } else { url.append(",").append(ids[i]); } } String response = request(url.toString()); if (response == null) { return null; } users.addAll(new TwitterJSONParser().parseUserNames(response)); for (User u : users) { u.setSource("twitter"); } return users; } /* * Sends a request to Twitter to get all of a specified user tweets. * * @param twitterUsersInFeed list of users * * @param listener the listener to be used in the request */ public void getTweetsForUsers(List<User> twitterUsersInFeed, final RequestListener listener) { for (final User user : twitterUsersInFeed) { runAsync(new Runnable() { @Override public void run() { List<TwitterItem> tweets = getUserTweets(user.getId()); listener.onComplete(tweets); } }); } } /* * Sends a request to Twitter. * * @param String The URL which the request is aimed at. * * @return String with the content from the request */ private synchronized String request(String requestURL) { try { OAuthRequest request = new OAuthRequest(Verb.GET, requestURL); Token accessToken = ClientStore.getTwitterAccessToken(context); twitter.signRequest(accessToken, request); Response response = request.send(); if (response.isSuccessful()) { return response.getBody(); } else { Log.e(getClass().getName(), "Unsuccessful response returned"); } } catch (OAuthException e) { Log.e(getClass().getName(), "Problem establishing connection"); } return null; } }