/** * 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; }
/** * @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; } }
/** * Write the contents of the JSONObject as JSON text to a writer. For compactness, no whitespace * is added. * * <p>Warning: This method assumes that the data structure is acyclical. * * @return The writer. * @throws JSONException */ public Writer write(Writer writer) throws JSONException { try { boolean b = false; Iterator keys = keys(); writer.write('{'); while (keys.hasNext()) { if (b) { writer.write(','); } Object k = keys.next(); writer.write(quote(k.toString())); writer.write(':'); Object v = this.myHashMap.get(k); if (v instanceof JSONObject) { ((JSONObject) v).write(writer); } else if (v instanceof JSONArray) { ((JSONArray) v).write(writer); } else { writer.write(valueToString(v)); } b = true; } writer.write('}'); return writer; } catch (IOException e) { throw new JSONException(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; }
/** * Construct a JSONObject from a subset of another JSONObject. An array of strings is used to * identify the keys that should be copied. Missing keys are ignored. * * @param jo A JSONObject. * @param sa An array of strings. * @exception JSONException If a value is a non-finite number. */ public JSONObject(JSONObject jo, String[] sa) throws JSONException { this(); for (int i = 0; i < sa.length; i += 1) { putOpt(sa[i], jo.opt(sa[i])); } }