/** * Use cursors to fetch upto jtwit.maxResults TODO More controlled paging?? * * @param url API method to call * @param screenName * @param userId * @return twitter-id numbers for friends/followers of screenName or userId Is affected by {@link * #maxResults} */ private List<Number> getUserIDs(String url, String screenName, Long userId) { Long cursor = -1L; List<Number> ids = new ArrayList<Number>(); if (screenName != null && userId != null) throw new IllegalArgumentException( "cannot use both screen_name and user_id when fetching user_ids"); Map<String, String> vars = InternalUtils.asMap("screen_name", screenName, "user_id", userId); while (cursor != 0 && !jtwit.enoughResults(ids)) { vars.put("cursor", String.valueOf(cursor)); String json = http.getPage(url, vars, http.canAuthenticate()); try { // it seems Twitter will occasionally return a raw array JSONArray jarr; if (json.charAt(0) == '[') { jarr = new JSONArray(json); cursor = 0L; } else { JSONObject jobj = new JSONObject(json); jarr = (JSONArray) jobj.get("ids"); cursor = new Long(jobj.getString("next_cursor")); } for (int i = 0; i < jarr.length(); i++) { ids.add(jarr.getLong(i)); } if (jarr.length() == 0) { // No more break; } } catch (JSONException e) { throw new TwitterException.Parsing(json, e); } } return ids; }
/** * Returns information of a given user, specified by user-id. * * @param userId The user-id of a user. * @throws exception if the user does not exist - or has been terminated (as happens to spam * bots). */ public User show(Number userId) { Map<String, String> vars = InternalUtils.asMap("user_id", userId.toString()); String json = http.getPage(jtwit.TWITTER_URL + "/users/show.json", vars, http.canAuthenticate()); try { User user = new User(new JSONObject(json), null); return user; } catch (JSONException e) { throw new TwitterException.Parsing(json, e); } }
/** * @return true if followerScreenName <i>is</i> following followedScreenName * @throws TwitterException.E403 if one of the users has protected their updates and you don't * have access. This can be counter-intuitive (and annoying) at times! Also throws E403 if one * of the users has been suspended (we use the {@link SuspendedUser} exception sub-class for * this). * @throws TwitterException.E404 if one of the users does not exist */ public boolean isFollower(String followerScreenName, String followedScreenName) { assert followerScreenName != null && followedScreenName != null; try { Map vars = InternalUtils.asMap( "source_screen_name", followerScreenName, "target_screen_name", followedScreenName); String page = http.getPage(jtwit.TWITTER_URL + "/friendships/show.json", vars, http.canAuthenticate()); JSONObject jo = new JSONObject(page); JSONObject trgt = jo.getJSONObject("relationship").getJSONObject("target"); boolean fby = trgt.getBoolean("followed_by"); return fby; } catch (TwitterException.E403 e) { if (e instanceof SuspendedUser) throw e; // Should this be a suspended user exception instead? // Let's ask Twitter // TODO check rate limits - only do if we have spare capacity String whoFirst = followedScreenName.equals(jtwit.getScreenName()) ? followerScreenName : followedScreenName; try { // this could throw a SuspendedUser exception show(whoFirst); String whoSecond = whoFirst.equals(followedScreenName) ? followerScreenName : followedScreenName; if (whoSecond.equals(jtwit.getScreenName())) throw e; show(whoSecond); } catch (TwitterException.RateLimit e2) { // ignore } // both shows worked? throw e; } catch (TwitterException e) { // FIXME investigating a weird new bug if (e.getMessage() != null && e.getMessage().contains("Two user ids or screen_names must be supplied")) throw new TwitterException( "WTF? inputs: follower=" + followerScreenName + ", followed=" + followedScreenName + ", call-by=" + jtwit.getScreenName() + "; " + e.getMessage()); throw e; } }
/** * Low-level method for fetching e.g. your friends * * @param url * @param screenName e.g. your screen-name * @return */ private List<User> getUsers(String url, String screenName) { Map<String, String> vars = InternalUtils.asMap("screen_name", screenName); List<User> users = new ArrayList<User>(); Long cursor = -1L; while (cursor != 0 && !jtwit.enoughResults(users)) { vars.put("cursor", cursor.toString()); JSONObject jobj; try { jobj = new JSONObject(http.getPage(url, vars, http.canAuthenticate())); users.addAll(User.getUsers(jobj.getString("users"))); cursor = new Long(jobj.getString("next_cursor")); } catch (JSONException e) { throw new TwitterException.Parsing(null, e); } } return users; }
/** * Returns information of a given user, specified by screen name. * * @param screenName The screen name of a user. * @throws exception if the user does not exist * @throws SuspendedUser if the user has been terminated (as happens to spam bots). * @see #show(long) */ public User show(String screenName) throws TwitterException, TwitterException.SuspendedUser { Map vars = InternalUtils.asMap("screen_name", screenName); // Test Code Debugger at work - expected closures until 2012 String json = ""; try { json = http.getPage(jtwit.TWITTER_URL + "/users/show.json", vars, http.canAuthenticate()); } catch (Exception e) { // we get here? throw new TwitterException.E404( "User " + screenName + " does not seem to exist, their user account may have been removed from the service"); } // Debuggers no longer at work if (json.length() == 0) throw new TwitterException.E404(screenName + " does not seem to exist"); try { User user = new User(new JSONObject(json), null); return user; } catch (JSONException e) { throw new TwitterException.Parsing(json, e); } }