Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base fork: sferik/twitter
...
head fork: fredxinfan/twitter
Checking mergeability… Don't worry, you can still create the pull request.
  • 16 commits
  • 39 files changed
  • 0 commit comments
  • 2 contributors
Commits on Aug 29, 2012
@twoism twoism do not attempt to parse 302s 0e6c1c1
Commits on Sep 07, 2012
@sferik Disable identity map by default
The identity map was causing more issues than expected:
* #260
* #285
* #302

It should be disabled by default.
c5efc1b
@sferik Fix "instance variable @identity_map_class not initialized" warning 74a6a9d
@sferik Remove deprecated `RateLimit.instance` method ca09c1b
@sferik Removed deprecated `Twitter::Tweet#oembed` method aa177ce
@sferik Rename resources for v1.1 cc22df6
@sferik Remove notification methods; use `Twitter::API#friendship_update` ins…
…tead
57bf687
@sferik Remove `Twitter::API#end_session` 5290e78
@sferik Add `Twitter::Tweet#retweet?` method and `Twitter::Tweet#retweet` alias a848c06
@sferik Merge pull request #311 from twoism/do_not_parse_redirects
do not attempt to parse 302s
4aeecde
Commits on Sep 08, 2012
@sferik Major changes for Twitter API v1.1 fc560a5
Commits on Sep 10, 2012
@sferik Remove deprecated methods
* Twitter::API#no_retweet_ids
* Twitter::API#retweeted_to_user
* Twitter::API#trends_daily
* Twitter::API#trends_weekly
ea3edcc
@sferik Remove Twitter::API#rate_limited? 525beab
@sferik Remove Twitter::Client#rate_limit e05d888
@sferik Remove media endpoint
In API v1.1, Twitter::API#update_with_media uses the default endpoint.

See: https://dev.twitter.com/discussions/10644?page=1#comment-22487
a793fb8
@sferik Remove Twitter::API#rate_limit_status 0859ad3
Showing with 593 additions and 1,020 deletions.
  1. +1 −1  README.md
  2. +187 −432 lib/twitter/api.rb
  3. +1 −2  lib/twitter/base.rb
  4. +0 −4 lib/twitter/client.rb
  5. +1 −2  lib/twitter/configurable.rb
  6. +6 −6 lib/twitter/core_ext/hash.rb
  7. +1 −7 lib/twitter/default.rb
  8. +2 −0  lib/twitter/error.rb
  9. +1 −7 lib/twitter/rate_limit.rb
  10. +0 −21 lib/twitter/rate_limit_status.rb
  11. +1 −5 lib/twitter/response/parse_json.rb
  12. +5 −6 lib/twitter/tweet.rb
  13. +0 −1  spec/fixtures/false.json
  14. +1 −0  spec/fixtures/following.json
  15. 0  spec/fixtures/{id_list.json → ids_list.json}
  16. 0  spec/fixtures/{id_list2.json → ids_list2.json}
  17. +1 −0  spec/fixtures/not_following.json
  18. +0 −1  spec/fixtures/relationship.json
  19. +1 −1  spec/fixtures/statuses.json
  20. +0 −1  spec/fixtures/true.json
  21. +16 −16 spec/helper.rb
  22. +0 −33 spec/twitter/api/account_spec.rb
  23. +93 −34 spec/twitter/api/blocks_spec.rb
  24. +12 −6 spec/twitter/api/direct_messages_spec.rb
  25. +32 −50 spec/twitter/api/friendships_spec.rb
  26. +32 −0 spec/twitter/api/help_spec.rb
  27. +0 −41 spec/twitter/api/legal_spec.rb
  28. +17 −74 spec/twitter/api/lists_spec.rb
  29. +0 −49 spec/twitter/api/notifications_spec.rb
  30. +2 −2 spec/twitter/api/saved_searches_spec.rb
  31. +86 −70 spec/twitter/api/statuses_spec.rb
  32. +25 −45 spec/twitter/api/trends_spec.rb
  33. +5 −14 spec/twitter/base_spec.rb
  34. +2 −25 spec/twitter/client_spec.rb
  35. +4 −4 spec/twitter/cursor_spec.rb
  36. +18 −8 spec/twitter/identifiable_spec.rb
  37. +17 −7 spec/twitter/rate_limit_spec.rb
  38. +0 −16 spec/twitter/rate_limit_status_spec.rb
  39. +23 −29 spec/twitter/tweet_spec.rb
View
2  README.md
@@ -273,7 +273,7 @@ Here are some fun facts about the 3.0 release:
* The entire library is implemented in just 2,000 lines of code
* With over 5,000 lines of specs, the spec-to-code ratio is over 2.5:1
-* The spec suite contains 674 examples and runs in under 2 seconds on a MacBook
+* The spec suite contains 644 examples and runs in under 2 seconds on a MacBook
* This project has 100% C0 code coverage (the tests execute every line of
source code at least once)
* At the time of release, this library is comprehensive: you can request all
View
619 lib/twitter/api.rb
@@ -12,7 +12,6 @@
require 'twitter/list'
require 'twitter/oembed'
require 'twitter/place'
-require 'twitter/rate_limit_status'
require 'twitter/relationship'
require 'twitter/saved_search'
require 'twitter/search_results'
@@ -25,169 +24,9 @@
module Twitter
module API
DEFAULT_CURSOR = -1
+ DEFAULT_TWEETS_PER_REQUEST = 20
MAX_USERS_PER_REQUEST = 100
- METHOD_RATE_LIMITED = {
- :accept => false,
- :activity_about_me => true,
- :activity_by_friends => true,
- :block => true,
- :block? => true,
- :blocked_ids => true,
- :blocking => true,
- :configuration => true,
- :contributees => true,
- :contributors => true,
- :current_user => true,
- :d => false,
- :deny => false,
- :direct_message => true,
- :direct_message_create => false,
- :direct_message_destroy => false,
- :direct_messages => true,
- :direct_messages_received => true,
- :direct_messages_sent => true,
- :disable_notifications => false,
- :enable_notifications => false,
- :end_session => false,
- :fav => false,
- :fave => false,
- :favorite => false,
- :favorite_create => false,
- :favorite_destroy => false,
- :favorites => true,
- :follow => false,
- :follow! => false,
- :follower_ids => true,
- :following_followers_of => true,
- :friend_ids => true,
- :friendship => true,
- :friendship? => true,
- :friendship_create => false,
- :friendship_create! => false,
- :friendship_destroy => false,
- :friendship_show => true,
- :friendship_update => false,
- :friendships => true,
- :friendships_incoming => true,
- :friendships_outgoing => true,
- :geo_search => true,
- :home_timeline => true,
- :initialize => false,
- :languages => true,
- :list => true,
- :list_add_member => false,
- :list_add_members => false,
- :list_create => false,
- :list_destroy => false,
- :list_member? => true,
- :list_members => true,
- :list_remove_member => false,
- :list_remove_members => false,
- :list_subscribe => false,
- :list_subscriber? => true,
- :list_subscribers => true,
- :list_timeline => true,
- :list_unsubscribe => false,
- :list_update => false,
- :lists => true,
- :lists_subscribed_to => true,
- :local_trends => true,
- :m => false,
- :media_timeline => true,
- :memberships => true,
- :mentions => true,
- :network_timeline => true,
- :no_retweet_ids => true,
- :oembed => true,
- :oembeds => true,
- :phoenix_search => true,
- :place => true,
- :place_create => true,
- :places_nearby => true,
- :places_similar => true,
- :privacy => true,
- :rate_limit_status => false,
- :rate_limited? => false,
- :related_results => true,
- :related_statuses => true,
- :related_tweets => true,
- :recommendations => true,
- :relationship => true,
- :report_spam => true,
- :retweet => true,
- :retweeted_by => true,
- :retweeted_by_me => true,
- :retweeted_by_user => true,
- :retweeted_to => true,
- :retweeted_to_me => true,
- :retweeted_to_user => true,
- :retweeters_of => true,
- :retweets => true,
- :retweets_of_me => true,
- :reverse_geocode => true,
- :saved_search => true,
- :saved_search_create => false,
- :saved_search_destroy => false,
- :saved_searches => true,
- :search => true,
- :settings => true,
- :status => true,
- :status_activity => true,
- :status_destroy => false,
- :statuses => true,
- :statuses_activity => true,
- :subscriptions => true,
- :suggest_users => true,
- :suggestions => true,
- :tos => true,
- :trend_locations => true,
- :trends => true,
- :trends_daily => true,
- :trends_weekly => true,
- :tweet_activity => true,
- :tweet_destroy => false,
- :unblock => false,
- :unfavorite => false,
- :unfollow => false,
- :update => false,
- :update_delivery_device => false,
- :update_profile => false,
- :update_profile_background_image => false,
- :update_profile_colors => false,
- :update_profile_image => false,
- :update_with_media => false,
- :user => true,
- :user? => true,
- :user_search => true,
- :user_timeline => true,
- :users => true,
- :verify_credentials => true,
- }
-
- # Check whether a method is rate limited
- #
- # @raise [ArgumentError] Error raised when supplied argument is not a key in the METHOD_RATE_LIMITED hash.
- # @return [Boolean]
- # @param method_name [Symbol]
- def rate_limited?(method_name)
- method_rate_limited = METHOD_RATE_LIMITED[method_name.to_sym]
- raise ArgumentError.new("no method `#{method_name}' for #{self.class}") if method_rate_limited.nil?
- method_rate_limited
- end
-
- # Returns the remaining number of API requests available to the requesting user
- #
- # @see https://dev.twitter.com/docs/api/1.1/get/account/rate_limit_status
- # @rate_limited No
- # @authentication_required Requires user context
- # @raise [Twitter::Error::Unauthorized] Error raised when supplied user credentials are not valid.
- # @return [Twitter::RateLimitStatus]
- # @param options [Hash] A customizable set of options.
- # @example Return the remaining number of API requests available to the requesting user
- # Twitter.rate_limit_status
- def rate_limit_status(options={})
- object_from_response(Twitter::RateLimitStatus, :get, "/1.1/account/rate_limit_status.json", options)
- end
+ MAX_TWEETS_PER_REQUEST = 200
# Returns the requesting user if authentication was successful, otherwise raises {Twitter::Error::Unauthorized}
#
@@ -205,20 +44,6 @@ def verify_credentials(options={})
end
alias current_user verify_credentials
- # Ends the session of the authenticating user
- #
- # @see https://dev.twitter.com/docs/api/1.1/post/account/end_session
- # @rate_limited No
- # @authentication_required Requires user context
- # @raise [Twitter::Error::Unauthorized] Error raised when supplied user credentials are not valid.
- # @return [Hash]
- # @param options [Hash] A customizable set of options.
- # @example End the session of the authenticating user
- # Twitter.end_session
- def end_session(options={})
- post("/1.1/account/end_session.json", options)[:body]
- end
-
# Sets which device Twitter delivers updates to for the authenticating user
#
# @see https://dev.twitter.com/docs/api/1.1/post/account/update_delivery_device
@@ -399,7 +224,7 @@ def direct_messages_sent(options={})
# Destroys direct messages
#
- # @see https://dev.twitter.com/docs/api/1.1/post/direct_messages/destroy/:id
+ # @see https://dev.twitter.com/docs/api/1.1/post/direct_messages/destroy
# @note This method requires an access token with RWD (read, write & direct message) permissions. Consult The Application Permission Model for more information.
# @rate_limited No
# @authentication_required Requires user context
@@ -413,7 +238,10 @@ def direct_messages_sent(options={})
# @param ids [Array<Integer>, Set<Integer>] An array of Tweet IDs.
# @param options [Hash] A customizable set of options.
def direct_message_destroy(*args)
- destroy(Twitter::DirectMessage, :post, "/1.1/direct_messages/destroy", args)
+ options = args.extract_options!
+ args.flatten.threaded_map do |id|
+ object_from_response(Twitter::DirectMessage, :post, "/1.1/direct_messages/destroy.json", options.merge(:id => id))
+ end
end
# Sends a new direct message to the specified user from the authenticating user
@@ -431,14 +259,15 @@ def direct_message_destroy(*args)
# Twitter.direct_message_create(7505382, "I'm sending you this message via @gem!") # Same as above
def direct_message_create(user, text, options={})
options.merge_user!(user)
- object_from_response(Twitter::DirectMessage, :post, "/1.1/direct_messages/new.json", options.merge(:text => text))
+ options[:text] = text
+ object_from_response(Twitter::DirectMessage, :post, "/1.1/direct_messages/new.json", options)
end
alias d direct_message_create
alias m direct_message_create
# Returns a direct message
#
- # @see https://dev.twitter.com/docs/api/1.1/get/direct_messages/show/%3Aid
+ # @see https://dev.twitter.com/docs/api/1.1/get/direct_messages/show
# @note This method requires an access token with RWD (read, write & direct message) permissions. Consult The Application Permission Model for more information.
# @rate_limited Yes
# @authentication_required Requires user context
@@ -449,7 +278,8 @@ def direct_message_create(user, text, options={})
# @example Return the direct message with the id 1825786345
# Twitter.direct_message(1825786345)
def direct_message(id, options={})
- object_from_response(Twitter::DirectMessage, :get, "/1.1/direct_messages/show/#{id}.json", options)
+ options[:id] = id
+ object_from_response(Twitter::DirectMessage, :get, "/1.1/direct_messages/show.json", options)
end
# @note This method requires an access token with RWD (read, write & direct message) permissions. Consult The Application Permission Model for more information.
@@ -471,14 +301,14 @@ def direct_message(id, options={})
# @overload direct_messages(*ids)
# Returns direct messages
#
- # @see https://dev.twitter.com/docs/api/1.1/get/direct_messages/show/%3Aid
+ # @see https://dev.twitter.com/docs/api/1.1/get/direct_messages/show
# @param ids [Array<Integer>, Set<Integer>] An array of Tweet IDs.
# @example Return the direct message with the id 1825786345
# Twitter.direct_messages(1825786345)
# @overload direct_messages(*ids, options)
# Returns direct messages
#
- # @see https://dev.twitter.com/docs/api/1.1/get/direct_messages/show/%3Aid
+ # @see https://dev.twitter.com/docs/api/1.1/get/direct_messages/show
# @param ids [Array<Integer>, Set<Integer>] An array of Tweet IDs.
# @param options [Hash] A customizable set of options.
def direct_messages(*args)
@@ -487,7 +317,7 @@ def direct_messages(*args)
direct_messages_received(options)
else
args.flatten.threaded_map do |id|
- object_from_response(Twitter::DirectMessage, :get, "/1.1/direct_messages/show/#{id}.json", options)
+ direct_message(id, options)
end
end
end
@@ -544,23 +374,20 @@ def friend_ids(*args)
# Test for the existence of friendship between two users
#
- # @see https://dev.twitter.com/docs/api/1.1/get/friendships/exists
- # @note Consider using {Twitter::API::Friendships#friendship} instead of this method.
+ # @see https://dev.twitter.com/docs/api/1.1/get/friendships/show
# @rate_limited Yes
# @authentication_required Requires user context
# @raise [Twitter::Error::Unauthorized] Error raised when supplied user credentials are not valid.
# @return [Boolean] true if user_a follows user_b, otherwise false.
- # @param user_a [Integer, String, Twitter::User] The Twitter user ID, screen name, or object of the subject user.
- # @param user_b [Integer, String, Twitter::User] The Twitter user ID, screen name, or object of the user to test for following.
+ # @param source [Integer, String, Twitter::User] The Twitter user ID, screen name, or object of the source user.
+ # @param target [Integer, String, Twitter::User] The Twitter user ID, screen name, or object of the target user.
# @param options [Hash] A customizable set of options.
# @example Return true if @sferik follows @pengwynn
# Twitter.friendship?('sferik', 'pengwynn')
# Twitter.friendship?('sferik', 14100886) # Same as above
# Twitter.friendship?(7505382, 14100886) # Same as above
- def friendship?(user_a, user_b, options={})
- options.merge_user!(user_a, nil, "a")
- options.merge_user!(user_b, nil, "b")
- get("/1.1/friendships/exists.json", options)[:body]
+ def friendship?(source, target, options={})
+ friendship(source, target, options).source.following?
end
# Returns an array of numeric IDs for every user who has a pending request to follow the authenticating user
@@ -575,7 +402,8 @@ def friendship?(user_a, user_b, options={})
# @example Return an array of numeric IDs for every user who has a pending request to follow the authenticating user
# Twitter.friendships_incoming
def friendships_incoming(options={})
- cursor_from_response(:ids, nil, :get, "/1.1/friendships/incoming.json", {:cursor => DEFAULT_CURSOR}.merge(options))
+ merge_default_cursor!(options)
+ cursor_from_response(:ids, nil, :get, "/1.1/friendships/incoming.json", options)
end
# Returns an array of numeric IDs for every protected user for whom the authenticating user has a pending follow request
@@ -590,7 +418,8 @@ def friendships_incoming(options={})
# @example Return an array of numeric IDs for every protected user for whom the authenticating user has a pending follow request
# Twitter.friendships_outgoing
def friendships_outgoing(options={})
- cursor_from_response(:ids, nil, :get, "/1.1/friendships/outgoing.json", {:cursor => DEFAULT_CURSOR}.merge(options))
+ merge_default_cursor!(options)
+ cursor_from_response(:ids, nil, :get, "/1.1/friendships/outgoing.json", options)
end
# Returns detailed information about the relationship between two users
@@ -636,7 +465,7 @@ def follow(*args)
options = args.extract_options!
# Twitter always turns on notifications if the "follow" option is present, even if it's set to false
# so only send follow if it's true
- options.merge!(:follow => true) if options.delete(:follow)
+ options[:follow] = true if !!options.delete(:follow)
existing_friends = Thread.new do
friend_ids.ids
end
@@ -666,10 +495,11 @@ def follow!(*args)
options = args.extract_options!
# Twitter always turns on notifications if the "follow" option is present, even if it's set to false
# so only send follow if it's true
- options.merge!(:follow => true) if options.delete(:follow)
+ options[:follow] = true if !!options.delete(:follow)
args.flatten.threaded_map do |user|
begin
- object_from_response(Twitter::User, :post, "/1.1/friendships/create.json", options.merge_user(user))
+ options.merge_user!(user)
+ object_from_response(Twitter::User, :post, "/1.1/friendships/create.json", options)
rescue Twitter::Error::Forbidden
# This error will be raised if the user doesn't have permission to
# follow list_member, for whatever reason.
@@ -737,21 +567,6 @@ def friendship_update(user, options={})
object_from_response(Twitter::Relationship, :post, "/1.1/friendships/update.json", options)
end
- # Returns an array of user_ids that the currently authenticated user does not want to see retweets from.
- #
- # @see https://dev.twitter.com/docs/api/1.1/get/friendships/no_retweet_ids
- # @rate_limited Yes
- # @authentication_required Requires user context
- # @raise [Twitter::Error::Unauthorized] Error raised when supplied user credentials are not valid.
- # @return [Array<Integer>]
- # @param options [Hash] A customizable set of options.
- # @option options [Boolean] :stringify_ids Many programming environments will not consume our ids due to their size. Provide this option to have ids returned as strings instead. Read more about Twitter IDs, JSON and Snowflake.
- # @example Enable rewteets and devise notifications for @sferik
- # Twitter.no_retweet_ids
- def no_retweet_ids(options={})
- get("/1.1/friendships/no_retweet_ids.json", options)[:body]
- end
-
# Allows the authenticating user to accept the specified users' follow requests
#
# @note Undocumented
@@ -915,7 +730,7 @@ def languages(options={})
# Returns {https://twitter.com/privacy Twitter's Privacy Policy}
#
- # @see https://dev.twitter.com/docs/api/1.1/get/legal/privacy
+ # @see https://dev.twitter.com/docs/api/1.1/get/help/privacy
# @rate_limited Yes
# @authentication_required Requires user context
# @raise [Twitter::Error::Unauthorized] Error raised when supplied user credentials are not valid.
@@ -923,12 +738,12 @@ def languages(options={})
# @example Return {https://twitter.com/privacy Twitter's Privacy Policy}
# Twitter.privacy
def privacy(options={})
- get("/1.1/legal/privacy.json", options)[:body][:privacy]
+ get("/1.1/help/privacy.json", options)[:body][:privacy]
end
# Returns {https://twitter.com/tos Twitter's Terms of Service}
#
- # @see https://dev.twitter.com/docs/api/1.1/get/legal/tos
+ # @see https://dev.twitter.com/docs/api/1.1/get/help/tos
# @rate_limited Yes
# @authentication_required Requires user context
# @raise [Twitter::Error::Unauthorized] Error raised when supplied user credentials are not valid.
@@ -936,28 +751,7 @@ def privacy(options={})
# @example Return {https://twitter.com/tos Twitter's Terms of Service}
# Twitter.tos
def tos(options={})
- get("/1.1/legal/tos.json", options)[:body][:tos]
- end
-
- # Returns all lists the authenticating or specified user subscribes to, including their own
- #
- # @see https://dev.twitter.com/docs/api/1.1/get/lists/all
- # @rate_limited Yes
- # @authentication_required Requires user context
- # @raise [Twitter::Error::Unauthorized] Error raised when supplied user credentials are not valid.
- # @return [Array<Twitter::List>]
- # @overload lists_subscribed_to(options={})
- # @param options [Hash] A customizable set of options.
- # @example Return all lists the authenticating user subscribes to
- # Twitter.lists_subscribed_to
- # @overload lists_subscribed_to(user, options={})
- # @param user [Integer, String, Twitter::User] A Twitter user ID, screen name, or object.
- # @param options [Hash] A customizable set of options.
- # @example Return all lists the specified user subscribes to
- # Twitter.lists_subscribed_to('sferik')
- # Twitter.lists_subscribed_to(8863586)
- def lists_subscribed_to(*args)
- objects_from_response(Twitter::List, :get, "/1.1/lists/all.json", args)
+ get("/1.1/help/tos.json", options)[:body][:tos]
end
# Show tweet timeline for members of the specified list
@@ -1402,28 +1196,21 @@ def list_create(name, options={})
end
# List the lists of the specified user
+ # Returns all lists the authenticating or specified user subscribes to, including their own.
#
- # @see https://dev.twitter.com/docs/api/1.1/get/lists
- # @note Private lists will be included if the authenticated user is the same as the user whose lists are being returned.
+ # @see https://dev.twitter.com/docs/api/1.1/get/lists/list
# @rate_limited Yes
# @authentication_required Requires user context
# @raise [Twitter::Error::Unauthorized] Error raised when supplied user credentials are not valid.
# @return [Twitter::Cursor]
- # @overload lists(options={})
- # @param options [Hash] A customizable set of options.
- # @option options [Integer] :cursor (-1) Breaks the results into pages. Provide values as returned in the response objects's next_cursor and previous_cursor attributes to page back and forth in the list.
- # @example List the authenticated user's lists
- # Twitter.lists
- # @overload lists(user, options={})
- # @param user [Integer, String, Twitter::User] A Twitter user ID, screen name, or object.
- # @param options [Hash] A customizable set of options.
- # @option options [Integer] :cursor (-1) Breaks the results into pages. Provide values as returned in the response objects's next_cursor and previous_cursor attributes to page back and forth in the list.
- # @example List @sferik's lists
- # Twitter.lists('sferik')
- # Twitter.lists(7505382)
+ # @param options [Hash] A customizable set of options.
+ # @option options [Integer] :cursor (-1) Breaks the results into pages. Provide values as returned in the response objects's next_cursor and previous_cursor attributes to page back and forth in the list.
+ # @example List the authenticated user's lists
+ # Twitter.lists
def lists(*args)
- lists_from_response(:get, "/1.1/lists.json", args)
+ lists_from_response(:get, "/1.1/lists/list.json", args)
end
+ alias lists_subscribed_to lists
# Show the specified list
#
@@ -1452,44 +1239,6 @@ def list(*args)
list_from_response(:get, "/1.1/lists/show.json", args)
end
- # Enables device notifications for updates from the specified users to the authenticating user
- #
- # @see https://dev.twitter.com/docs/api/1.1/post/notifications/follow
- # @rate_limited No
- # @authentication_required Requires user context
- # @raise [Twitter::Error::Unauthorized] Error raised when supplied user credentials are not valid.
- # @return [Array<Twitter::User>] The specified users.
- # @overload enable_notifications(*users)
- # @param users [Array<Integer, String, Twitter::User>, Set<Integer, String, Twitter::User>] An array of Twitter user IDs, screen names, or objects.
- # @example Enable device notifications for updates from @sferik
- # Twitter.enable_notifications('sferik')
- # Twitter.enable_notifications(7505382) # Same as above
- # @overload enable_notifications(*users, options)
- # @param users [Array<Integer, String, Twitter::User>, Set<Integer, String, Twitter::User>] An array of Twitter user IDs, screen names, or objects.
- # @param options [Hash] A customizable set of options.
- def enable_notifications(*args)
- threaded_users_from_response(:post, "/1.1/notifications/follow.json", args)
- end
-
- # Disables notifications for updates from the specified users to the authenticating user
- #
- # @see https://dev.twitter.com/docs/api/1.1/post/notifications/leave
- # @rate_limited No
- # @authentication_required Requires user context
- # @raise [Twitter::Error::Unauthorized] Error raised when supplied user credentials are not valid.
- # @return [Array<Twitter::User>] The specified users.
- # @overload disable_notifications(*users)
- # @param users [Array<Integer, String, Twitter::User>, Set<Integer, String, Twitter::User>] An array of Twitter user IDs, screen names, or objects.
- # @example Disable device notifications for updates from @sferik
- # Twitter.disable_notifications('sferik')
- # Twitter.disable_notifications(7505382) # Same as above
- # @overload disable_notifications(*users, options)
- # @param users [Array<Integer, String, Twitter::User>, Set<Integer, String, Twitter::User>] An array of Twitter user IDs, screen names, or objects.
- # @param options [Hash] A customizable set of options.
- def disable_notifications(*args)
- threaded_users_from_response(:post, "/1.1/notifications/leave.json", args)
- end
-
# The users specified are blocked by the authenticated user and reported as spammers
#
# @see https://dev.twitter.com/docs/api/1.1/post/report_spam
@@ -1516,7 +1265,7 @@ def report_spam(*args)
# @overload saved_search(options={})
# Returns the authenticated user's saved search queries
#
- # @see https://dev.twitter.com/docs/api/1.1/get/saved_searches
+ # @see https://dev.twitter.com/docs/api/1.1/get/saved_searches/list
# @param options [Hash] A customizable set of options.
# @example Return the authenticated user's saved search queries
# Twitter.saved_searches
@@ -1536,7 +1285,7 @@ def report_spam(*args)
def saved_searches(*args)
options = args.extract_options!
if args.empty?
- collection_from_response(Twitter::SavedSearch, :get, "/1.1/saved_searches.json", options)
+ collection_from_response(Twitter::SavedSearch, :get, "/1.1/saved_searches/list.json", options)
else
args.flatten.threaded_map do |id|
object_from_response(Twitter::SavedSearch, :get, "/1.1/saved_searches/show/#{id}.json", options)
@@ -1590,12 +1339,15 @@ def saved_search_create(query, options={})
# @param ids [Array<Integer>, Set<Integer>] An array of Tweet IDs.
# @param options [Hash] A customizable set of options.
def saved_search_destroy(*args)
- destroy(Twitter::SavedSearch, :post, "/1.1/saved_searches/destroy", args)
+ options = args.extract_options!
+ args.flatten.threaded_map do |id|
+ object_from_response(Twitter::SavedSearch, :post, "/1.1/saved_searches/destroy/#{id}.json", options)
+ end
end
# Returns tweets that match a specified query.
#
- # @see https://dev.twitter.com/docs/api/1.1/get/search
+ # @see https://dev.twitter.com/docs/api/1.1/get/search/tweets
# @see https://dev.twitter.com/docs/using-search
# @see https://dev.twitter.com/docs/history-rest-search-api
# @note As of April 1st 2010, the Search API provides an option to retrieve "popular tweets" in addition to real-time search results. In an upcoming release, this will become the default and clients that don't want to receive popular tweets in their search results will have to explicitly opt-out. See the result_type parameter below for more information.
@@ -1637,7 +1389,7 @@ def phoenix_search(q, options={})
search_collection_from_response(:get, "/phoenix_search.phoenix", options.merge(:q => q))
end
- # @see https://dev.twitter.com/docs/api/1.1/get/favorites
+ # @see https://dev.twitter.com/docs/api/1.1/get/favorites/list
# @rate_limited Yes
# @authentication_required Requires user context
# @raise [Twitter::Error::Unauthorized] Error raised when supplied user credentials are not valid.
@@ -1661,17 +1413,15 @@ def phoenix_search(q, options={})
# Twitter.favorites('sferik')
def favorites(*args)
options = args.extract_options!
- url = if user = args.pop
- "/1.1/favorites/#{user}.json"
- else
- "/1.1/favorites.json"
+ if user = args.pop
+ options.merge_user!(user)
end
- collection_from_response(Twitter::Tweet, :get, url, options)
+ collection_from_response(Twitter::Tweet, :get, "/1.1/favorites/list.json", options)
end
# Favorites the specified Tweets as the authenticating user
#
- # @see https://dev.twitter.com/docs/api/1.1/post/favorites/create/:id
+ # @see https://dev.twitter.com/docs/api/1.1/post/favorites/create
# @rate_limited No
# @authentication_required Requires user context
# @raise [Twitter::Error::Unauthorized] Error raised when supplied user credentials are not valid.
@@ -1684,7 +1434,10 @@ def favorites(*args)
# @param ids [Array<Integer>, Set<Integer>] An array of Tweet IDs.
# @param options [Hash] A customizable set of options.
def favorite(*args)
- threaded_tweets_from_response(:post, "/1.1/favorites/create", args)
+ options = args.extract_options!
+ args.flatten.threaded_map do |id|
+ object_from_response(Twitter::Tweet, :post, "/1.1/favorites/create.json", options.merge(:id => id))
+ end
end
alias fav favorite
alias fave favorite
@@ -1692,7 +1445,7 @@ def favorite(*args)
# Un-favorites the specified Tweets as the authenticating user
#
- # @see https://dev.twitter.com/docs/api/1.1/post/favorites/destroy/:id
+ # @see https://dev.twitter.com/docs/api/1.1/post/favorites/destroy
# @rate_limited No
# @authentication_required Requires user context
# @raise [Twitter::Error::Unauthorized] Error raised when supplied user credentials are not valid.
@@ -1705,7 +1458,10 @@ def favorite(*args)
# @param ids [Array<Integer>, Set<Integer>] An array of Tweet IDs.
# @param options [Hash] A customizable set of options.
def unfavorite(*args)
- threaded_tweets_from_response(:post, "/1.1/favorites/destroy", args)
+ options = args.extract_options!
+ args.flatten.threaded_map do |id|
+ object_from_response(Twitter::Tweet, :post, "/1.1/favorites/destroy.json", options.merge(:id => id))
+ end
end
alias favorite_destroy unfavorite
@@ -1724,8 +1480,8 @@ def unfavorite(*args)
# @option options [Boolean, String, Integer] :trim_user Each tweet returned in a timeline will include a user object with only the author's numerical ID when set to true, 't' or 1.
# @option options [Boolean, String, Integer] :exclude_replies This parameter will prevent replies from appearing in the returned timeline. Using exclude_replies with the count parameter will mean you will receive up-to count tweets - this is because the count parameter retrieves that many tweets before filtering out retweets and replies.
# @option options [Boolean, String, Integer] :include_rts Specifies that the timeline should include native retweets in addition to regular tweets. Note: If you're using the trim_user parameter in conjunction with include_rts, the retweets will no longer contain a full user object.
+ # @option options [Boolean, String, Integer] :contributor_details Specifies that the contributors element should be enhanced to include the screen_name of the contributor.
# @option options [Boolean, String, Integer] :include_entities Specifies that each tweet should include an 'entities' node including metadata about the tweet such as: user_mentions, urls, and hashtags.
- # @option options [Boolean] :contributor_details Specifies that the contributors element should be enhanced to include the screen_name of the contributor.
# @example Return the 20 most recent Tweets, including retweets if they exist, posted by the authenticating user and the users they follow
# Twitter.home_timeline
def home_timeline(options={})
@@ -1734,7 +1490,7 @@ def home_timeline(options={})
# Returns the 20 most recent mentions (statuses containing @username) for the authenticating user
#
- # @see https://dev.twitter.com/docs/api/1.1/get/statuses/mentions
+ # @see https://dev.twitter.com/docs/api/1.1/get/statuses/mentions_timeline
# @note This method can only return up to 800 Tweets.
# @rate_limited Yes
# @authentication_required Requires user context
@@ -1747,70 +1503,69 @@ def home_timeline(options={})
# @option options [Boolean, String, Integer] :trim_user Each tweet returned in a timeline will include a user object with only the author's numerical ID when set to true, 't' or 1.
# @example Return the 20 most recent mentions (statuses containing @username) for the authenticating user
# Twitter.mentions
- def mentions(options={})
- collection_from_response(Twitter::Tweet, :get, "/1.1/statuses/mentions.json", options)
+ def mentions_timeline(options={})
+ collection_from_response(Twitter::Tweet, :get, "/1.1/statuses/mentions_timeline.json", options)
end
+ alias mentions mentions_timeline
# Returns the 20 most recent retweets posted by the specified user
#
- # @see https://dev.twitter.com/docs/api/1.1/get/statuses/retweeted_by_user
+ # @see https://dev.twitter.com/docs/api/1.1/get/statuses/user_timeline
+ # @note This method can only return up to 3,200 Tweets.
# @rate_limited Yes
# @authentication_required Requires user context
# @raise [Twitter::Error::Unauthorized] Error raised when supplied user credentials are not valid.
# @return [Array<Twitter::Tweet>]
+ # @param user [Integer, String, Twitter::User] A Twitter user ID, screen name, or object.
# @param options [Hash] A customizable set of options.
# @option options [Integer] :since_id Returns results with an ID greater than (that is, more recent than) the specified ID.
# @option options [Integer] :max_id Returns results with an ID less than (that is, older than) or equal to the specified ID.
# @option options [Integer] :count Specifies the number of records to retrieve. Must be less than or equal to 200.
# @option options [Boolean, String, Integer] :trim_user Each tweet returned in a timeline will include a user object with only the author's numerical ID when set to true, 't' or 1.
- # @example Return the 20 most recent retweets posted by the authenticating user
+ # @option options [Boolean, String, Integer] :exclude_replies This parameter will prevent replies from appearing in the returned timeline. Using exclude_replies with the count parameter will mean you will receive up-to count tweets - this is because the count parameter retrieves that many tweets before filtering out retweets and replies.
+ # @option options [Boolean, String, Integer] :contributor_details Specifies that the contributors element should be enhanced to include the screen_name of the contributor.
+ # @example Return the 20 most recent retweets posted by @sferik
# Twitter.retweeted_by_user('sferik')
def retweeted_by_user(user, options={})
- collection_from_response(Twitter::Tweet, :get, "/1.1/statuses/retweeted_by_user.json", options.merge_user!(user))
+ options[:include_rts] = true
+ count = options[:count] || DEFAULT_TWEETS_PER_REQUEST
+ collect_with_count(count) do |count_options|
+ select_retweets(user_timeline(user, options.merge(count_options)))
+ end
end
alias retweeted_by retweeted_by_user
# Returns the 20 most recent retweets posted by the authenticating user
#
- # @see https://dev.twitter.com/docs/api/1.1/get/statuses/retweeted_by_me
+ # @see https://dev.twitter.com/docs/api/1.1/get/statuses/user_timeline
+ # @note This method can only return up to 3,200 Tweets.
# @rate_limited Yes
# @authentication_required Requires user context
# @raise [Twitter::Error::Unauthorized] Error raised when supplied user credentials are not valid.
# @return [Array<Twitter::Tweet>]
+ # @param user [Integer, String, Twitter::User] A Twitter user ID, screen name, or object.
# @param options [Hash] A customizable set of options.
# @option options [Integer] :since_id Returns results with an ID greater than (that is, more recent than) the specified ID.
# @option options [Integer] :max_id Returns results with an ID less than (that is, older than) or equal to the specified ID.
# @option options [Integer] :count Specifies the number of records to retrieve. Must be less than or equal to 200.
# @option options [Boolean, String, Integer] :trim_user Each tweet returned in a timeline will include a user object with only the author's numerical ID when set to true, 't' or 1.
+ # @option options [Boolean, String, Integer] :exclude_replies This parameter will prevent replies from appearing in the returned timeline. Using exclude_replies with the count parameter will mean you will receive up-to count tweets - this is because the count parameter retrieves that many tweets before filtering out retweets and replies.
+ # @option options [Boolean, String, Integer] :contributor_details Specifies that the contributors element should be enhanced to include the screen_name of the contributor.
# @example Return the 20 most recent retweets posted by the authenticating user
# Twitter.retweeted_by_me
def retweeted_by_me(options={})
- collection_from_response(Twitter::Tweet, :get, "/1.1/statuses/retweeted_by_me.json", options)
- end
-
- # Returns the 20 most recent retweets posted by users the specified user follows
- #
- # @see https://dev.twitter.com/docs/api/1.1/get/statuses/retweeted_to_user
- # @rate_limited Yes
- # @authentication_required Requires user context
- # @raise [Twitter::Error::Unauthorized] Error raised when supplied user credentials are not valid.
- # @return [Array<Twitter::Tweet>]
- # @param user [Integer, String, Twitter::User] A Twitter user ID, screen name, or object.
- # @param options [Hash] A customizable set of options.
- # @option options [Integer] :since_id Returns results with an ID greater than (that is, more recent than) the specified ID.
- # @option options [Integer] :max_id Returns results with an ID less than (that is, older than) or equal to the specified ID.
- # @option options [Integer] :count Specifies the number of records to retrieve. Must be less than or equal to 200.
- # @option options [Boolean, String, Integer] :trim_user Each tweet returned in a timeline will include a user object with only the author's numerical ID when set to true, 't' or 1.
- # @example Return the 20 most recent retweets posted by users followed by the specified user
- # Twitter.retweeted_to_user('sferik')
- def retweeted_to_user(user, options={})
- collection_from_response(Twitter::Tweet, :get, "/1.1/statuses/retweeted_to_user.json", options.merge_user!(user))
+ options[:include_rts] = true
+ count = options[:count] || DEFAULT_TWEETS_PER_REQUEST
+ collect_with_count(count) do |count_options|
+ select_retweets(user_timeline(options.merge(count_options)))
+ end
end
- alias retweeted_to retweeted_to_user
+ alias retweeted_by retweeted_by_user
# Returns the 20 most recent retweets posted by users the authenticating user follow.
#
- # @see https://dev.twitter.com/docs/api/1.1/get/statuses/retweeted_to_me
+ # @see https://dev.twitter.com/docs/api/1.1/get/statuses/home_timeline
+ # @note This method can only return up to 800 Tweets, including retweets.
# @rate_limited Yes
# @authentication_required Requires user context
# @raise [Twitter::Error::Unauthorized] Error raised when supplied user credentials are not valid.
@@ -1820,15 +1575,23 @@ def retweeted_to_user(user, options={})
# @option options [Integer] :max_id Returns results with an ID less than (that is, older than) or equal to the specified ID.
# @option options [Integer] :count Specifies the number of records to retrieve. Must be less than or equal to 200.
# @option options [Boolean, String, Integer] :trim_user Each tweet returned in a timeline will include a user object with only the author's numerical ID when set to true, 't' or 1.
+ # @option options [Boolean, String, Integer] :exclude_replies This parameter will prevent replies from appearing in the returned timeline. Using exclude_replies with the count parameter will mean you will receive up-to count tweets - this is because the count parameter retrieves that many tweets before filtering out retweets and replies.
+ # @option options [Boolean, String, Integer] :contributor_details Specifies that the contributors element should be enhanced to include the screen_name of the contributor.
+ # @option options [Boolean, String, Integer] :include_entities Specifies that each tweet should include an 'entities' node including metadata about the tweet such as: user_mentions, urls, and hashtags.
# @example Return the 20 most recent retweets posted by users followed by the authenticating user
# Twitter.retweeted_to_me
def retweeted_to_me(options={})
- collection_from_response(Twitter::Tweet, :get, "/1.1/statuses/retweeted_to_me.json", options)
+ options[:include_rts] = true
+ count = options[:count] || DEFAULT_TWEETS_PER_REQUEST
+ collect_with_count(count) do |count_options|
+ select_retweets(home_timeline(options.merge(count_options)))
+ end
end
# Returns the 20 most recent tweets of the authenticated user that have been retweeted by others
#
- # @see https://dev.twitter.com/docs/api/1.1/get/statuses/retweets_of_me
+ # @see https://dev.twitter.com/docs/api/1.1/get/statuses/user_timeline
+ # @note This method can only return up to 3,200 Tweets.
# @rate_limited Yes
# @authentication_required Requires user context
# @raise [Twitter::Error::Unauthorized] Error raised when supplied user credentials are not valid.
@@ -1838,16 +1601,22 @@ def retweeted_to_me(options={})
# @option options [Integer] :max_id Returns results with an ID less than (that is, older than) or equal to the specified ID.
# @option options [Integer] :count Specifies the number of records to retrieve. Must be less than or equal to 200.
# @option options [Boolean, String, Integer] :trim_user Each tweet returned in a timeline will include a user object with only the author's numerical ID when set to true, 't' or 1.
+ # @option options [Boolean, String, Integer] :exclude_replies This parameter will prevent replies from appearing in the returned timeline. Using exclude_replies with the count parameter will mean you will receive up-to count tweets - this is because the count parameter retrieves that many tweets before filtering out retweets and replies.
+ # @option options [Boolean, String, Integer] :contributor_details Specifies that the contributors element should be enhanced to include the screen_name of the contributor.
# @example Return the 20 most recent tweets of the authenticated user that have been retweeted by others
# Twitter.retweets_of_me
def retweets_of_me(options={})
- collection_from_response(Twitter::Tweet, :get, "/1.1/statuses/retweets_of_me.json", options)
+ options[:include_rts] = false
+ count = options[:count] || DEFAULT_TWEETS_PER_REQUEST
+ collect_with_count(count) do |count_options|
+ user_timeline(options.merge(count_options)).select{|tweet| tweet.retweet_count.to_i > 0}
+ end
end
# Returns the 20 most recent Tweets posted by the specified user
#
# @see https://dev.twitter.com/docs/api/1.1/get/statuses/user_timeline
- # @note This method can only return up to 3200 Tweets.
+ # @note This method can only return up to 3,200 Tweets.
# @rate_limited Yes
# @authentication_required Requires user context
# @raise [Twitter::Error::Unauthorized] Error raised when supplied user credentials are not valid.
@@ -1860,9 +1629,8 @@ def retweets_of_me(options={})
# @option options [Integer] :count Specifies the number of records to retrieve. Must be less than or equal to 200.
# @option options [Boolean, String, Integer] :trim_user Each tweet returned in a timeline will include a user object with only the author's numerical ID when set to true, 't' or 1.
# @option options [Boolean, String, Integer] :exclude_replies This parameter will prevent replies from appearing in the returned timeline. Using exclude_replies with the count parameter will mean you will receive up-to count tweets - this is because the count parameter retrieves that many tweets before filtering out retweets and replies.
+ # @option options [Boolean, String, Integer] :contributor_details Specifies that the contributors element should be enhanced to include the screen_name of the contributor.
# @option options [Boolean, String, Integer] :include_rts Specifies that the timeline should include native retweets in addition to regular tweets. Note: If you're using the trim_user parameter in conjunction with include_rts, the retweets will no longer contain a full user object.
- # @option options [Boolean, String, Integer] :include_entities Specifies that each tweet should include an 'entities' node including metadata about the tweet such as: user_mentions, urls, and hashtags.
- # @option options [Boolean] :contributor_details Specifies that the contributors element should be enhanced to include the screen_name of the contributor.
# @example Return the 20 most recent Tweets posted by @sferik
# Twitter.user_timeline('sferik')
def user_timeline(*args)
@@ -1910,8 +1678,7 @@ def network_timeline(options={})
# Show up to 100 users who retweeted the Tweet
#
- # @see https://dev.twitter.com/docs/api/1.1/get/statuses/:id/retweeted_by
- # @see https://dev.twitter.com/docs/api/1.1/get/statuses/:id/retweeted_by/ids
+ # @see https://dev.twitter.com/docs/api/1.1/get/statuses/retweets/:id
# @rate_limited Yes
# @authentication_required Requires user context
# @raise [Twitter::Error::Unauthorized] Error raised when supplied user credentials are not valid.
@@ -1919,16 +1686,15 @@ def network_timeline(options={})
# @param id [Integer] The numerical ID of the desired Tweet.
# @param options [Hash] A customizable set of options.
# @option options [Integer] :count Specifies the number of records to retrieve. Must be less than or equal to 100.
- # @option options [Integer] :page Specifies the page of results to retrieve.
# @option options [Boolean, String, Integer] :trim_user Each tweet returned in a timeline will include a user object with only the author's numerical ID when set to true, 't' or 1.
# @option options [Boolean] :ids_only ('false') Only return user ids instead of full user objects.
# @example Show up to 100 users who retweeted the Tweet with the ID 28561922516
# Twitter.retweeters_of(28561922516)
def retweeters_of(id, options={})
if ids_only = !!options.delete(:ids_only)
- get("/1.1/statuses/#{id}/retweeted_by/ids.json", options)[:body]
+ retweets(id, options).map(&:user).map(&:id)
else
- collection_from_response(Twitter::User, :get, "/1.1/statuses/#{id}/retweeted_by.json", options)
+ retweets(id, options).map(&:user)
end
end
@@ -2162,7 +1928,7 @@ def update(status, options={})
# Updates the authenticating user's status with media
#
- # @see http://dev.twitter.com/docs/api/1.1/post/statuses/update_with_media
+ # @see https://dev.twitter.com/docs/api/1.1/post/statuses/update_with_media
# @note A status update with text/media identical to the authenticating user's current status will NOT be ignored
# @rate_limited No
# @authentication_required Requires user context
@@ -2180,26 +1946,28 @@ def update(status, options={})
# @example Update the authenticating user's status
# Twitter.update_with_media("I'm tweeting with @gem!", File.new('my_awesome_pic.jpeg'))
def update_with_media(status, media, options={})
- object_from_response(Twitter::Tweet, :post, "/1.1/statuses/update_with_media.json", options.merge('media[]' => media, 'status' => status), :endpoint => @media_endpoint)
+ object_from_response(Twitter::Tweet, :post, "/1.1/statuses/update_with_media.json", options.merge('media[]' => media, 'status' => status))
end
# Returns the top 10 trending topics for a specific WOEID
#
- # @see https://dev.twitter.com/docs/api/1.1/get/trends/:woeid
+ # @see https://dev.twitter.com/docs/api/1.1/get/trends/place
# @rate_limited Yes
# @authentication_required Requires user context
- # @param woeid [Integer] The {https://developer.yahoo.com/geo/geoplanet Yahoo! Where On Earth ID} of the location to return trending information for. WOEIDs can be retrieved by calling {Twitter::API::Trends#trend_locations}. Global information is available by using 1 as the WOEID.
# @raise [Twitter::Error::Unauthorized] Error raised when supplied user credentials are not valid.
+ # @param id [Integer] The {https://developer.yahoo.com/geo/geoplanet Yahoo! Where On Earth ID} of the location to return trending information for. WOEIDs can be retrieved by calling {Twitter::API::Trends#trend_locations}. Global information is available by using 1 as the WOEID.
# @param options [Hash] A customizable set of options.
# @option options [String] :exclude Setting this equal to 'hashtags' will remove all hashtags from the trends list.
# @return [Array<Twitter::Trend>]
# @example Return the top 10 trending topics for San Francisco
- # Twitter.local_trends(2487956)
- def local_trends(woeid=1, options={})
- response = get("/1.1/trends/#{woeid}.json", options)
+ # Twitter.trends(2487956)
+ def trends(id=1, options={})
+ options[:id] = id
+ response = get("/1.1/trends/place.json", options)
collection_from_array(Twitter::Trend, response[:body].first[:trends])
end
- alias trends local_trends
+ alias local_trends trends
+ alias trends_place trends
# Returns the locations that Twitter has trending topic information for
#
@@ -2208,50 +1976,33 @@ def local_trends(woeid=1, options={})
# @authentication_required Requires user context
# @raise [Twitter::Error::Unauthorized] Error raised when supplied user credentials are not valid.
# @param options [Hash] A customizable set of options.
- # @option options [Float] :lat If provided with a :long option the available trend locations will be sorted by distance, nearest to furthest, to the co-ordinate pair. The valid ranges for latitude are -90.0 to +90.0 (North is positive) inclusive.
- # @option options [Float] :long If provided with a :lat option the available trend locations will be sorted by distance, nearest to furthest, to the co-ordinate pair. The valid ranges for longitude are -180.0 to +180.0 (East is positive) inclusive.
# @return [Array<Twitter::Place>]
# @example Return the locations that Twitter has trending topic information for
- # Twitter.trend_locations
- def trend_locations(options={})
+ # Twitter.trends_available
+ def trends_available(options={})
collection_from_response(Twitter::Place, :get, "/1.1/trends/available.json", options)
end
+ alias trend_locations trends_available
- # Returns the top 20 trending topics for each hour in a given day
- #
- # @see https://dev.twitter.com/docs/api/1.1/get/trends/daily
- # @rate_limited Yes
- # @authentication_required Requires user context
- # @raise [Twitter::Error::Unauthorized] Error raised when supplied user credentials are not valid.
- # @param date [Date] The start date for the report. A 404 error will be thrown if the date is older than the available search index (7-10 days). Dates in the future will be forced to the current date.
- # @param options [Hash] A customizable set of options.
- # @option options [String] :exclude Setting this equal to 'hashtags' will remove all hashtags from the trends list.
- # @return [Hash]
- # @example Return the top 20 trending topics for each hour of October 24, 2010
- # Twitter.trends_daily(Date.parse("2010-10-24"))
- def trends_daily(date=Date.today, options={})
- trends_periodically("/1.1/trends/daily.json", date, options)
- end
-
- # Returns the top 30 trending topics for each day in a given week
+ # Returns the locations that Twitter has trending topic information for, closest to a specified location.
#
- # @see https://dev.twitter.com/docs/api/1.1/get/trends/weekly
+ # @see https://dev.twitter.com/docs/api/1.1/get/trends/closest
# @rate_limited Yes
# @authentication_required Requires user context
# @raise [Twitter::Error::Unauthorized] Error raised when supplied user credentials are not valid.
- # @param date [Date] The start date for the report. A 404 error will be thrown if the date is older than the available search index (7-10 days). Dates in the future will be forced to the current date.
# @param options [Hash] A customizable set of options.
- # @option options [String] :exclude Setting this equal to 'hashtags' will remove all hashtags from the trends list.
- # @return [Hash]
- # @example Return the top ten topics that are currently trending on Twitter
- # Twitter.trends_weekly(Date.parse("2010-10-24"))
- def trends_weekly(date=Date.today, options={})
- trends_periodically("/1.1/trends/weekly.json", date, options)
+ # @option options [Float] :lat If provided with a :long option the available trend locations will be sorted by distance, nearest to furthest, to the co-ordinate pair. The valid ranges for latitude are -90.0 to +90.0 (North is positive) inclusive.
+ # @option options [Float] :long If provided with a :lat option the available trend locations will be sorted by distance, nearest to furthest, to the co-ordinate pair. The valid ranges for longitude are -180.0 to +180.0 (East is positive) inclusive.
+ # @return [Array<Twitter::Place>]
+ # @example Return the locations that Twitter has trending topic information for
+ # Twitter.trends_closest
+ def trends_closest(options={})
+ collection_from_response(Twitter::Place, :get, "/1.1/trends/closest.json", options)
end
# Returns an array of user objects that the authenticating user is blocking
#
- # @see https://dev.twitter.com/docs/api/1.1/get/blocks/blocking
+ # @see https://dev.twitter.com/docs/api/1.1/get/blocks/list
# @rate_limited Yes
# @authentication_required Requires user context
# @raise [Twitter::Error::Unauthorized] Error raised when supplied user credentials are not valid.
@@ -2261,12 +2012,13 @@ def trends_weekly(date=Date.today, options={})
# @example Return an array of user objects that the authenticating user is blocking
# Twitter.blocking
def blocking(options={})
- collection_from_response(Twitter::User, :get, "/1.1/blocks/blocking.json", options)
+ merge_default_cursor!(options)
+ cursor_from_response(:users, Twitter::User, :get, "/1.1/blocks/list.json", options)
end
# Returns an array of numeric user ids the authenticating user is blocking
#
- # @see https://dev.twitter.com/docs/api/1.1/get/blocks/blocking/ids
+ # @see https://dev.twitter.com/docs/api/1.1/get/blocks/ids
# @rate_limited Yes
# @authentication_required Requires user context
# @raise [Twitter::Error::Unauthorized] Error raised when supplied user credentials are not valid.
@@ -2274,13 +2026,13 @@ def blocking(options={})
# @param options [Hash] A customizable set of options.
# @example Return an array of numeric user ids the authenticating user is blocking
# Twitter.blocking_ids
- def blocked_ids(options={})
- get("/1.1/blocks/blocking/ids.json", options)[:body]
+ def blocked_ids(*args)
+ ids_from_response(:get, "/1.1/blocks/ids.json", args)
end
# Returns true if the authenticating user is blocking a target user
#
- # @see https://dev.twitter.com/docs/api/1.1/get/blocks/exists
+ # @see https://dev.twitter.com/docs/api/1.1/get/blocks/ids
# @rate_limited Yes
# @authentication_required Requires user context
# @raise [Twitter::Error::Unauthorized] Error raised when supplied user credentials are not valid.
@@ -2291,7 +2043,16 @@ def blocked_ids(options={})
# Twitter.block?('sferik')
# Twitter.block?(7505382) # Same as above
def block?(user, options={})
- exists?(:get, "/1.1/blocks/exists.json", user, options)
+ merge_default_cursor!(options)
+ user_id = case user
+ when Integer
+ user
+ when String
+ user(user).id
+ when Twitter::User
+ user.id
+ end
+ blocked_ids(options).all.map(&:to_i).include?(user_id)
end
# Blocks the users specified by the authenticating user
@@ -2455,12 +2216,16 @@ def user(*args)
# Twitter.user?('sferik')
# Twitter.user?(7505382) # Same as above
def user?(user, options={})
- exists?(:get, "/1.1/users/show.json", user, options)
+ options.merge_user!(user)
+ get("/1.1/users/show.json", options)
+ true
+ rescue Twitter::Error::NotFound
+ false
end
# Returns an array of users that the specified user can contribute to
#
- # @see http://dev.twitter.com/docs/api/1.1/get/users/contributees
+ # @see https://dev.twitter.com/docs/api/1.1/get/users/contributees
# @rate_limited Yes
# @authentication_required Requires user context
# @raise [Twitter::Error::Unauthorized] Error raised when supplied user credentials are not valid.
@@ -2483,7 +2248,7 @@ def contributees(*args)
# Returns an array of users who can contribute to the specified account
#
- # @see http://dev.twitter.com/docs/api/1.1/get/users/contributors
+ # @see https://dev.twitter.com/docs/api/1.1/get/users/contributors
# @rate_limited Yes
# @authentication_required Requires user context
# @raise [Twitter::Error::Unauthorized] Error raised when supplied user credentials are not valid.
@@ -2568,10 +2333,37 @@ def following_followers_of(*args)
private
- def retweets(tweets)
+ # @param tweets [Array]
+ # @return [Array]
+ def select_retweets(tweets)
tweets.select(&:retweet?)
end
+ # @param collection [Array]
+ # @param max_id [Integer, NilClass]
+ # @return [Array]
+ def collect_with_max_id(collection=[], max_id=nil, &block)
+ tweets = yield(max_id)
+ return collection if tweets.nil?
+ collection += tweets
+ tweets.empty? ? collection.flatten : collect_with_max_id(collection, tweets.last.id - 1, &block)
+ end
+
+ # @param count [Integer]
+ # @return [Array]
+ def collect_with_count(count, &block)
+ options = {}
+ options[:count] = MAX_TWEETS_PER_REQUEST
+ collect_with_max_id do |max_id|
+ options[:max_id] = max_id unless max_id.nil?
+ if count > 0
+ tweets = yield(options)
+ count -= tweets.length
+ tweets
+ end
+ end.flatten.compact[0...count]
+ end
+
# @param klass [Class]
# @param array [Array]
# @return [Array]
@@ -2714,31 +2506,6 @@ def list_users(request_method, url, args)
cursor_from_response(:users, Twitter::User, request_method, url, options, {}, calling_method)
end
- # @param klass [Class]
- # @param request_method [Symbol]
- # @param url [String]
- # @param args [Array]
- # @return [Array]
- def destroy(klass, request_method, url, args)
- options = args.extract_options!
- args.flatten.threaded_map do |id|
- object_from_response(klass, request_method, url + "/#{id}.json", options)
- end
- end
-
- # @param request_method [Symbol]
- # @param url [String]
- # @param user [Integer, String, Twitter::User] A Twitter user ID, screen name, or object.
- # @param params [Hash]
- # @return [Boolean]
- def exists?(request_method, url, user, params={}, options={})
- params.merge_user!(user)
- send(request_method.to_sym, url, params, options)
- true
- rescue Twitter::Error::NotFound
- false
- end
-
def list_user?(request_method, url, args)
options = args.extract_options!
options.merge_user!(args.pop)
@@ -2768,20 +2535,8 @@ def list_modify_members(request_method, url, args)
end.last
end
- def trends_periodically(url, date, options)
- response = get(url, options.merge(:date => date.strftime('%Y-%m-%d')))
- trends = {}
- response[:body][:trends].each do |key, value|
- trends[key] = []
- value.each do |trend|
- trends[key] << Twitter::Trend.fetch_or_new(trend)
- end
- end
- trends
- end
-
def merge_default_cursor!(options)
- options.merge!(:cursor => DEFAULT_CURSOR) unless options[:cursor]
+ options[:cursor] = DEFAULT_CURSOR unless options[:cursor]
end
def screen_name
View
3  lib/twitter/base.rb
@@ -25,8 +25,7 @@ def self.attr_reader(*attrs)
# return [Twitter::IdentityMap]
def self.identity_map
return unless Twitter.identity_map
- @identity_map = Twitter.identity_map.new if @identity_map_class != Twitter.identity_map
- @identity_map_class = Twitter.identity_map
+ @identity_map = Twitter.identity_map.new unless defined?(@identity_map) && @identity_map.class == Twitter.identity_map
@identity_map
end
View
4 lib/twitter/client.rb
@@ -4,7 +4,6 @@
require 'twitter/configurable'
require 'twitter/error/client_error'
require 'twitter/error/decode_error'
-require 'twitter/rate_limit'
require 'simple_oauth'
require 'uri'
@@ -16,7 +15,6 @@ module Twitter
class Client
include Twitter::API
include Twitter::Configurable
- attr_reader :rate_limit
# Initializes a new Client object
#
@@ -26,7 +24,6 @@ def initialize(options={})
Twitter::Configurable.keys.each do |key|
instance_variable_set(:"@#{key}", options[key] || Twitter.instance_variable_get(:"@#{key}"))
end
- @rate_limit = Twitter::RateLimit.new
end
# Perform an HTTP DELETE request
@@ -82,7 +79,6 @@ def request(method, path, params={}, options={})
end
yield request if block_given?
end.env
- @rate_limit.update(response[:response_headers])
response
rescue Faraday::Error::ClientError
raise Twitter::Error::ClientError
View
3  lib/twitter/configurable.rb
@@ -3,7 +3,7 @@
module Twitter
module Configurable
attr_writer :consumer_key, :consumer_secret, :oauth_token, :oauth_token_secret
- attr_accessor :endpoint, :media_endpoint, :connection_options, :identity_map, :middleware
+ attr_accessor :endpoint, :connection_options, :identity_map, :middleware
class << self
@@ -14,7 +14,6 @@ def keys
:oauth_token,
:oauth_token_secret,
:endpoint,
- :media_endpoint,
:connection_options,
:identity_map,
:middleware,
View
12 lib/twitter/core_ext/hash.rb
@@ -48,22 +48,22 @@ def merge_owner!(user)
#
# @param user[Integer, String, Twitter::User] A Twitter user ID, screen_name, or object.
# @return [Hash]
- def merge_user(user, prefix=nil, suffix=nil)
- self.dup.merge_user!(user, prefix, suffix)
+ def merge_user(user, prefix=nil)
+ self.dup.merge_user!(user, prefix)
end
# Take a user and merge it into the hash with the correct key
#
# @param user[Integer, String, Twitter::User] A Twitter user ID, screen_name, or object.
# @return [Hash]
- def merge_user!(user, prefix=nil, suffix=nil)
+ def merge_user!(user, prefix=nil)
case user
when Integer
- self[[prefix, "user_id", suffix].compact.join("_").to_sym] = user
+ self[[prefix, "user_id"].compact.join("_").to_sym] = user
when String
- self[[prefix, "screen_name", suffix].compact.join("_").to_sym] = user
+ self[[prefix, "screen_name"].compact.join("_").to_sym] = user
when Twitter::User
- self[[prefix, "user_id", suffix].compact.join("_").to_sym] = user.id
+ self[[prefix, "user_id"].compact.join("_").to_sym] = user.id
end
self
end
View
8 lib/twitter/default.rb
@@ -11,7 +11,6 @@
module Twitter
module Default
ENDPOINT = 'https://api.twitter.com' unless defined? ENDPOINT
- MEDIA_ENDPOINT = 'https://upload.twitter.com' unless defined? MEDIA_ENDPOINT
CONNECTION_OPTIONS = {
:headers => {
:accept => 'application/json',
@@ -22,7 +21,7 @@ module Default
:ssl => {:verify => false},
:timeout => 10,
} unless defined? CONNECTION_OPTIONS
- IDENTITY_MAP = Twitter::IdentityMap unless defined? IDENTITY_MAP
+ IDENTITY_MAP = false unless defined? IDENTITY_MAP
MIDDLEWARE = Faraday::Builder.new(
&Proc.new do |builder|
# Convert file uploads to Faraday::UploadIO objects
@@ -79,11 +78,6 @@ def endpoint
ENDPOINT
end
- # @return [String]
- def media_endpoint
- MEDIA_ENDPOINT
- end
-
# @return [Hash]
def connection_options
CONNECTION_OPTIONS
View
2  lib/twitter/error.rb
@@ -1,3 +1,5 @@
+require 'twitter/rate_limit'
+
module Twitter
# Custom error class for rescuing from all Twitter errors
class Error < StandardError
View
8 lib/twitter/rate_limit.rb
@@ -3,12 +3,6 @@ class RateLimit
attr_reader :attrs
alias to_hash attrs
- # @deprecated This method exists to provide backwards compatibility to when
- # Twitter::RateLimit was a singleton. Safe to remove in version 4.
- def self.instance
- Twitter.rate_limit
- end
-
# @return [Twitter::RateLimit]
def initialize(attrs={})
@attrs = attrs
@@ -38,7 +32,7 @@ def reset_in
end
alias retry_after reset_in
- # Update the attributes of a Relationship
+ # Update the attributes of a RateLimit
#
# @param attrs [Hash]
# @return [Twitter::RateLimit]
View
21 lib/twitter/rate_limit_status.rb
@@ -1,21 +0,0 @@
-require 'twitter/base'
-
-module Twitter
- class RateLimitStatus < Twitter::Base
- attr_reader :hourly_limit, :remaining_hits, :reset_time_in_seconds
-
- # Time when the authenticating user's rate limit will be reset
- #
- # @return [Time]
- def reset_time
- @reset_time ||= Time.parse(@attrs[:reset_time]) if reset_time?
- end
-
- private
-
- def reset_time?
- !@attrs[:reset_time].nil?
- end
-
- end
-end
View
6 lib/twitter/response/parse_json.rb
@@ -9,10 +9,6 @@ def parse(body)
case body
when /\A^\s*$\z/, nil
nil
- when 'true'
- true
- when 'false'
- false
else
MultiJson.load(body, :symbolize_keys => true)
end
@@ -20,7 +16,7 @@ def parse(body)
def on_complete(env)
if respond_to?(:parse)
- env[:body] = parse(env[:body]) unless [204, 304].include?(env[:status])
+ env[:body] = parse(env[:body]) unless [204, 301, 302, 304].include?(env[:status])
end
end
View
11 lib/twitter/tweet.rb
@@ -67,12 +67,6 @@ def metadata
@metadata ||= Twitter::Metadata.fetch_or_new(@attrs[:metadata])
end
- # @deprecated This method will be removed in version 4.
- # @return [Twitter::OEmbed]
- def oembed(options={})
- @oembed ||= Twitter.oembed(@attrs[:id], options)
- end
-
# @return [Twitter::Place]
def place
@place ||= Twitter::Place.fetch_or_new(@attrs[:place])
@@ -85,6 +79,10 @@ def repliers_count
end
alias reply_count repliers_count
+ def retweet?
+ !!retweeted_status
+ end
+
# If this Tweet is a retweet, the original Tweet is available here.
#
# @return [Twitter::Tweet]
@@ -92,6 +90,7 @@ def retweeted_status
@retweeted_status ||= self.class.fetch_or_new(@attrs[:retweeted_status])
end
alias retweeted_tweet retweeted_status
+ alias retweet retweeted_status
# @return [String]
def retweeters_count
View
1  spec/fixtures/false.json
@@ -1 +0,0 @@
-false
View
1  spec/fixtures/following.json
@@ -0,0 +1 @@
+{"relationship":{"target":{"followed_by":true,"id_str":"14100886","following":false,"screen_name":"pengwynn","id":14100886},"source":{"marked_spam":false,"notifications_enabled":false,"followed_by":false,"want_retweets":true,"id_str":"7505382","blocking":false,"all_replies":false,"following":true,"screen_name":"sferik","id":7505382}}}
View
0  spec/fixtures/id_list.json → spec/fixtures/ids_list.json
File renamed without changes
View
0  spec/fixtures/id_list2.json → spec/fixtures/ids_list2.json
File renamed without changes
View
1  spec/fixtures/not_following.json
@@ -0,0 +1 @@
+{"relationship":{"target":{"followed_by":false,"id_str":"14100886","following":true,"screen_name":"sferik","id":7505382},"source":{"marked_spam":false,"notifications_enabled":false,"followed_by":true,"want_retweets":true,"id_str":"7505382","blocking":false,"all_replies":false,"following":false,"screen_name":"pengwynn","id":14100886}}}
View
1  spec/fixtures/relationship.json
@@ -1 +0,0 @@
-{"relationship":{"target":{"followed_by":true,"id_str":"14100886","following":true,"screen_name":"pengwynn","id":14100886},"source":{"marked_spam":false,"notifications_enabled":false,"followed_by":true,"want_retweets":true,"id_str":"7505382","blocking":false,"all_replies":false,"following":true,"screen_name":"sferik","id":7505382}}}
View
2  spec/fixtures/statuses.json
@@ -1 +1 @@
-[{"in_reply_to_status_id_str":null,"place":null,"geo":null,"favorited":false,"in_reply_to_user_id_str":null,"contributors":null,"in_reply_to_screen_name":null,"source":"\u003Ca href=\"http:\/\/www.echofon.com\/\" rel=\"nofollow\"\u003EEchofon\u003C\/a\u003E","retweet_count":null,"in_reply_to_user_id":null,"in_reply_to_status_id":null,"created_at":"Sat Oct 16 17:07:46 +0000 2010","retweeted":false,"id_str":"27558893223","user":{"follow_request_sent":false,"profile_background_color":"000000","description":"Adventures in hunger and foolishness.","verified":false,"favourites_count":729,"notifications":false,"profile_use_background_image":true,"profile_text_color":"333333","listed_count":28,"profile_background_image_url":"http:\/\/a3.twimg.com\/profile_background_images\/162641967\/we_concept_bg2.png","profile_link_color":"0084B4","url":null,"statuses_count":2968,"show_all_inline_media":true,"lang":"en","profile_background_tile":false,"created_at":"Mon Jul 16 12:59:01 +0000 2007","profile_sidebar_fill_color":"DDEEF6","location":"San Francisco","contributors_enabled":false,"protected":false,"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/323331048\/me_normal.jpg","id_str":"7505382","friends_count":88,"profile_sidebar_border_color":"C0DEED","name":"Erik Michaels-Ober","following":false,"screen_name":"sferik","id":7505382,"geo_enabled":true,"time_zone":"Pacific Time (US & Canada)","utc_offset":-28800,"followers_count":898},"coordinates":null,"id":27558893223,"truncated":false,"text":"Ruby is the best programming language for hiding the ugly bits."},{"place":null,"coordinates":null,"retweet_count":null,"geo":null,"favorited":false,"source":"<a href=\"http://www.echofon.com/\" rel=\"nofollow\">Echofon</a>","in_reply_to_status_id":null,"created_at":"Fri Oct 15 18:26:47 +0000 2010","contributors":null,"in_reply_to_user_id":null,"user":{"friends_count":112,"description":"degradable","follow_request_sent":false,"profile_use_background_image":true,"profile_sidebar_border_color":"C0DEED","verified":false,"profile_background_image_url":"http://a1.twimg.com/profile_background_images/133569392/nature02922-f1.2.jpg","profile_background_color":"C0DEED","url":null,"show_all_inline_media":true,"notifications":false,"profile_background_tile":true,"lang":"en","statuses_count":2915,"geo_enabled":true,"favourites_count":707,"created_at":"Mon Jul 16 12:59:01 +0000 2007","profile_text_color":"333333","profile_image_url":"http://a0.twimg.com/profile_images/323331048/me_normal.jpg","location":"San Francisco","protected":false,"contributors_enabled":false,"profile_link_color":"0084B4","screen_name":"sferik","name":"Erik Michaels-Ober","listed_count":28,"following":true,"time_zone":"Pacific Time (US & Canada)","followers_count":894,"id":7505382,"utc_offset":-28800,"profile_sidebar_fill_color":"DDEEF6"},"truncated":false,"in_reply_to_screen_name":null,"id":27467028175,"retweeted":false,"text":"There are 1.3 billion people in China; when people say there are 1 billion they are rounding off the entire population of the United States."},{"in_reply_to_status_id_str":null,"place":null,"geo":null,"favorited":false,"in_reply_to_user_id_str":null,"in_reply_to_status_id":null,"contributors":null,"in_reply_to_screen_name":null,"in_reply_to_user_id":null,"source":"\u003Ca href=\"http:\/\/twitter.com\/tweetbutton\" rel=\"nofollow\"\u003ETweet Button\u003C\/a\u003E","retweet_count":null,"created_at":"Mon Oct 11 20:57:56 +0000 2010","id_str":"27068258331","retweeted":false,"user":{"statuses_count":2972,"description":"Adventures in hunger and foolishness.","show_all_inline_media":true,"favourites_count":729,"profile_sidebar_border_color":"C0DEED","contributors_enabled":false,"notifications":false,"geo_enabled":true,"time_zone":"Pacific Time (US & Canada)","profile_background_color":"000000","url":null,"verified":false,"follow_request_sent":false,"lang":"en","profile_use_background_image":true,"created_at":"Mon Jul 16 12:59:01 +0000 2007","profile_text_color":"333333","location":"San Francisco","id_str":"7505382","protected":false,"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/323331048\/me_normal.jpg","profile_background_image_url":"http:\/\/a3.twimg.com\/profile_background_images\/162641967\/we_concept_bg2.png","profile_link_color":"0084B4","name":"Erik Michaels-Ober","following":false,"followers_count":897,"screen_name":"sferik","id":7505382,"listed_count":28,"profile_background_tile":false,"utc_offset":-28800,"friends_count":89,"profile_sidebar_fill_color":"DDEEF6"},"coordinates":null,"id":27068258331,"truncated":false,"text":"The new Windows Phone campaign is the best advertising from Microsoft since \"Start Me Up\" (1995). Great work by CP+B. http:\/\/t.co\/tIzxopI"},{"in_reply_to_status_id_str":null,"place":{"country_code":"US","place_type":"city","url":"http:\/\/api.twitter.com\/1\/geo\/id\/4552eed9a8b61ff9.json","country":"The United States of America","bounding_box":{"type":"Polygon","coordinates":[[[-123.632497,38.29571],[-122.833844,38.29571],[-122.833844,38.808369],[-123.632497,38.808369]]]},"attributes":{},"full_name":"Russian River-Coastal, CA","name":"Russian River-Coastal","id":"4552eed9a8b61ff9"},"geo":{"type":"Point","coordinates":[38.524535,-123.088368]},"favorited":false,"in_reply_to_user_id_str":null,"in_reply_to_status_id":null,"contributors":null,"in_reply_to_screen_name":null,"in_reply_to_user_id":null,"source":"\u003Ca href=\"http:\/\/www.echofon.com\/\" rel=\"nofollow\"\u003EEchofon\u003C\/a\u003E","retweet_count":null,"created_at":"Sun Oct 10 18:26:22 +0000 2010","id_str":"26959930192","retweeted":false,"user":{"statuses_count":2972,"description":"Adventures in hunger and foolishness.","show_all_inline_media":true,"favourites_count":729,"profile_sidebar_border_color":"C0DEED","contributors_enabled":false,"notifications":false,"geo_enabled":true,"time_zone":"Pacific Time (US & Canada)","profile_background_color":"000000","url":null,"verified":false,"follow_request_sent":false,"lang":"en","profile_use_background_image":true,"created_at":"Mon Jul 16 12:59:01 +0000 2007","profile_text_color":"333333","location":"San Francisco","id_str":"7505382","protected":false,"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/323331048\/me_normal.jpg","profile_background_image_url":"http:\/\/a3.twimg.com\/profile_background_images\/162641967\/we_concept_bg2.png","profile_link_color":"0084B4","name":"Erik Michaels-Ober","following":false,"followers_count":897,"screen_name":"sferik","id":7505382,"listed_count":28,"profile_background_tile":false,"utc_offset":-28800,"friends_count":89,"profile_sidebar_fill_color":"DDEEF6"},"coordinates":{"type":"Point","coordinates":[-123.088368,38.524535]},"id":26959930192,"truncated":false,"text":"Fear not to sow seeds because of the birds. http:\/\/twitpic.com\/2wg621"},{"in_reply_to_status_id_str":null,"place":null,"geo":null,"favorited":false,"in_reply_to_user_id_str":null,"in_reply_to_status_id":null,"contributors":null,"in_reply_to_screen_name":null,"in_reply_to_user_id":null,"source":"\u003Ca href=\"http:\/\/www.echofon.com\/\" rel=\"nofollow\"\u003EEchofon\u003C\/a\u003E","retweet_count":null,"created_at":"Wed Oct 06 00:03:47 +0000 2010","id_str":"26503221778","retweeted":false,"user":{"statuses_count":2972,"description":"Adventures in hunger and foolishness.","show_all_inline_media":true,"favourites_count":729,"profile_sidebar_border_color":"C0DEED","contributors_enabled":false,"notifications":false,"geo_enabled":true,"time_zone":"Pacific Time (US & Canada)","profile_background_color":"000000","url":null,"verified":false,"follow_request_sent":false,"lang":"en","profile_use_background_image":true,"created_at":"Mon Jul 16 12:59:01 +0000 2007","profile_text_color":"333333","location":"San Francisco","id_str":"7505382","protected":false,"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/323331048\/me_normal.jpg","profile_background_image_url":"http:\/\/a3.twimg.com\/profile_background_images\/162641967\/we_concept_bg2.png","profile_link_color":"0084B4","name":"Erik Michaels-Ober","following":false,"followers_count":897,"screen_name":"sferik","id":7505382,"listed_count":28,"profile_background_tile":false,"utc_offset":-28800,"friends_count":89,"profile_sidebar_fill_color":"DDEEF6"},"coordinates":null,"id":26503221778,"truncated":false,"text":"Speaking of things that are maddening: the interview with the Wall Street guys on the most recent This American Life http:\/\/bit.ly\/af9pSD"},{"in_reply_to_status_id_str":null,"place":null,"geo":null,"favorited":false,"in_reply_to_user_id_str":null,"contributors":null,"in_reply_to_screen_name":null,"source":"\u003Ca href=\"http:\/\/www.echofon.com\/\" rel=\"nofollow\"\u003EEchofon\u003C\/a\u003E","retweet_count":null,"in_reply_to_user_id":null,"in_reply_to_status_id":null,"created_at":"Wed Sep 29 00:49:44 +0000 2010","retweeted":false,"id_str":"25836892941","user":{"follow_request_sent":false,"profile_background_color":"000000","description":"Adventures in hunger and foolishness.","verified":false,"favourites_count":729,"notifications":false,"profile_use_background_image":true,"profile_text_color":"333333","listed_count":28,"profile_background_image_url":"http:\/\/a3.twimg.com\/profile_background_images\/162641967\/we_concept_bg2.png","profile_link_color":"0084B4","url":null,"statuses_count":2968,"show_all_inline_media":true,"lang":"en","profile_background_tile":false,"created_at":"Mon Jul 16 12:59:01 +0000 2007","profile_sidebar_fill_color":"DDEEF6","location":"San Francisco","contributors_enabled":false,"protected":false,"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/323331048\/me_normal.jpg","id_str":"7505382","friends_count":88,"profile_sidebar_border_color":"C0DEED","name":"Erik Michaels-Ober","following":false,"screen_name":"sferik","id":7505382,"geo_enabled":true,"time_zone":"Pacific Time (US & Canada)","utc_offset":-28800,"followers_count":898},"coordinates":null,"id":25836892941,"truncated":false,"text":"Holy cow! RailsAdmin is up to 200 watchers (from 100 yesterday). http:\/\/github.com\/sferik\/rails_admin"},{"place":null,"retweet_count":null,"geo":null,"retweeted":false,"in_reply_to_status_id":null,"source":"\u003Ca href=\"http:\/\/www.echofon.com\/\" rel=\"nofollow\"\u003EEchofon\u003C\/a\u003E","truncated":false,"in_reply_to_status_id_str":null,"created_at":"Mon Sep 27 23:35:56 +0000 2010","in_reply_to_user_id":null,"favorited":false,"in_reply_to_user_id_str":null,"user":{"time_zone":"Pacific Time (US & Canada)","description":"Adventures in hunger and foolishness.","profile_sidebar_fill_color":"DDEEF6","followers_count":898,"listed_count":29,"notifications":false,"friends_count":88,"statuses_count":2962,"profile_use_background_image":true,"profile_sidebar_border_color":"C0DEED","show_all_inline_media":true,"favourites_count":727,"url":null,"contributors_enabled":false,"profile_background_image_url":"http:\/\/a3.twimg.com\/profile_background_images\/162641967\/we_concept_bg2.png","lang":"en","geo_enabled":true,"created_at":"Mon Jul 16 12:59:01 +0000 2007","profile_background_color":"000000","location":"San Francisco","profile_background_tile":false,"protected":false,"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/323331048\/me_normal.jpg","verified":false,"profile_text_color":"333333","name":"Erik Michaels-Ober","follow_request_sent":false,"following":false,"screen_name":"sferik","id":7505382,"id_str":"7505382","utc_offset":-28800,"profile_link_color":"0084B4"},"contributors":null,"coordinates":null,"in_reply_to_screen_name":null,"id":25732982065,"id_str":"25732982065","text":"Kind of cool that Facebook acts as a mirror for open-source projects that they use or like http:\/\/mirror.facebook.net\/"},{"in_reply_to_status_id_str":null,"place":null,"geo":null,"favorited":false,"in_reply_to_user_id_str":null,"in_reply_to_status_id":null,"contributors":null,"in_reply_to_screen_name":null,"in_reply_to_user_id":null,"source":"\u003Ca href=\"http:\/\/www.echofon.com\/\" rel=\"nofollow\"\u003EEchofon\u003C\/a\u003E","retweet_count":null,"created_at":"Mon Sep 27 14:55:28 +0000 2010","id_str":"25693598875","retweeted":false,"user":{"statuses_count":2972,"description":"Adventures in hunger and foolishness.","show_all_inline_media":true,"favourites_count":729,"profile_sidebar_border_color":"C0DEED","contributors_enabled":false,"notifications":false,"geo_enabled":true,"time_zone":"Pacific Time (US & Canada)","profile_background_color":"000000","url":null,"verified":false,"follow_request_sent":false,"lang":"en","profile_use_background_image":true,"created_at":"Mon Jul 16 12:59:01 +0000 2007","profile_text_color":"333333","location":"San Francisco","id_str":"7505382","protected":false,"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/323331048\/me_normal.jpg","profile_background_image_url":"http:\/\/a3.twimg.com\/profile_background_images\/162641967\/we_concept_bg2.png","profile_link_color":"0084B4","name":"Erik Michaels-Ober","following":false,"followers_count":897,"screen_name":"sferik","id":7505382,"listed_count":28,"profile_background_tile":false,"utc_offset":-28800,"friends_count":89,"profile_sidebar_fill_color":"DDEEF6"},"coordinates":null,"id":25693598875,"truncated":false,"text":"RailsAdmin already has 100 watchers, 12 forks, and 6 contributors in less than 2 months. Let's keep the momentum going! http:\/\/bit.ly\/cCMMqD"},{"in_reply_to_status_id_str":null,"place":null,"geo":null,"favorited":false,"in_reply_to_user_id_str":null,"contributors":null,"in_reply_to_screen_name":null,"source":"\u003Ca href=\"http:\/\/www.echofon.com\/\" rel=\"nofollow\"\u003EEchofon\u003C\/a\u003E","retweet_count":null,"in_reply_to_user_id":null,"in_reply_to_status_id":null,"created_at":"Tue Sep 14 03:25:46 +0000 2010","retweeted":false,"id_str":"24443017910","user":{"profile_background_color":"000000","description":"Adventures in hunger and foolishness.","verified":false,"follow_request_sent":false,"notifications":false,"profile_use_background_image":true,"profile_text_color":"333333","profile_background_image_url":"http:\/\/a3.twimg.com\/profile_background_images\/162641967\/we_concept_bg2.png","profile_link_color":"0084B4","url":null,"listed_count":28,"lang":"en","profile_background_tile":false,"created_at":"Mon Jul 16 12:59:01 +0000 2007","friends_count":88,"profile_sidebar_fill_color":"DDEEF6","location":"San Francisco","statuses_count":2968,"protected":false,"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/323331048\/me_normal.jpg","id_str":"7505382","show_all_inline_media":true,"favourites_count":729,"profile_sidebar_border_color":"C0DEED","name":"Erik Michaels-Ober","contributors_enabled":false,"following":false,"screen_name":"sferik","id":7505382,"geo_enabled":true,"time_zone":"Pacific Time (US & Canada)","utc_offset":-28800,"followers_count":898},"coordinates":null,"id":24443017910,"truncated":false,"text":"This week's This American Life is amazing. @JoeLipari is an American hero. http:\/\/bit.ly\/d9RbnB"},{"in_reply_to_status_id_str":null,"place":null,"geo":null,"favorited":false,"in_reply_to_user_id_str":null,"contributors":null,"in_reply_to_screen_name":null,"source":"\u003Ca href=\"http:\/\/www.echofon.com\/\" rel=\"nofollow\"\u003EEchofon\u003C\/a\u003E","retweet_count":null,"in_reply_to_user_id":null,"in_reply_to_status_id":null,"created_at":"Sat Sep 11 02:17:29 +0000 2010","retweeted":false,"id_str":"24158227743","user":{"profile_background_color":"000000","description":"Adventures in hunger and foolishness.","verified":false,"follow_request_sent":false,"notifications":false,"profile_use_background_image":true,"profile_text_color":"333333","profile_background_image_url":"http:\/\/a3.twimg.com\/profile_background_images\/162641967\/we_concept_bg2.png","profile_link_color":"0084B4","url":null,"listed_count":28,"lang":"en","profile_background_tile":false,"created_at":"Mon Jul 16 12:59:01 +0000 2007","friends_count":88,"profile_sidebar_fill_color":"DDEEF6","location":"San Francisco","statuses_count":2968,"protected":false,"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/323331048\/me_normal.jpg","id_str":"7505382","show_all_inline_media":true,"favourites_count":729,"profile_sidebar_border_color":"C0DEED","name":"Erik Michaels-Ober","contributors_enabled":false,"following":false,"screen_name":"sferik","id":7505382,"geo_enabled":true,"time_zone":"Pacific Time (US & Canada)","utc_offset":-28800,"followers_count":898},"coordinates":null,"id":24158227743,"truncated":false,"text":"RT @polyseme: OH: shofars should be called jewvuzelas."},{"in_reply_to_status_id_str":null,"place":null,"geo":null,"favorited":false,"in_reply_to_user_id_str":null,"in_reply_to_status_id":null,"contributors":null,"in_reply_to_screen_name":null,"in_reply_to_user_id":null,"source":"\u003Ca href=\"http:\/\/www.echofon.com\/\" rel=\"nofollow\"\u003EEchofon\u003C\/a\u003E","retweet_count":null,"created_at":"Fri Sep 10 18:07:47 +0000 2010","id_str":"24126395365","retweeted":false,"user":{"statuses_count":2972,"description":"Adventures in hunger and foolishness.","show_all_inline_media":true,"favourites_count":729,"profile_sidebar_border_color":"C0DEED","contributors_enabled":false,"notifications":false,"geo_enabled":true,"time_zone":"Pacific Time (US & Canada)","profile_background_color":"000000","url":null,"verified":false,"follow_request_sent":false,"lang":"en","profile_use_background_image":true,"created_at":"Mon Jul 16 12:59:01 +0000 2007","profile_text_color":"333333","location":"San Francisco","id_str":"7505382","protected":false,"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/323331048\/me_normal.jpg","profile_background_image_url":"http:\/\/a3.twimg.com\/profile_background_images\/162641967\/we_concept_bg2.png","profile_link_color":"0084B4","name":"Erik Michaels-Ober","following":false,"followers_count":897,"screen_name":"sferik","id":7505382,"listed_count":28,"profile_background_tile":false,"utc_offset":-28800,"friends_count":89,"profile_sidebar_fill_color":"DDEEF6"},"coordinates":null,"id":24126395365,"truncated":false,"text":"Spent this morning fixing broken windows in RailsAdmin http:\/\/github.com\/sferik\/rails_admin\/compare\/ab6c598...0e3770f"},{"in_reply_to_status_id_str":null,"place":null,"geo":null,"favorited":false,"in_reply_to_user_id_str":null,"in_reply_to_status_id":null,"contributors":null,"in_reply_to_screen_name":null,"in_reply_to_user_id":null,"source":"\u003Ca href=\"http:\/\/www.echofon.com\/\" rel=\"nofollow\"\u003EEchofon\u003C\/a\u003E","retweet_count":null,"created_at":"Fri Sep 10 18:02:34 +0000 2010","id_str":"24126047148","retweeted":false,"user":{"statuses_count":2972,"description":"Adventures in hunger and foolishness.","show_all_inline_media":true,"favourites_count":729,"profile_sidebar_border_color":"C0DEED","contributors_enabled":false,"notifications":false,"geo_enabled":true,"time_zone":"Pacific Time (US & Canada)","profile_background_color":"000000","url":null,"verified":false,"follow_request_sent":false,"lang":"en","profile_use_background_image":true,"created_at":"Mon Jul 16 12:59:01 +0000 2007","profile_text_color":"333333","location":"San Francisco","id_str":"7505382","protected":false,"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/323331048\/me_normal.jpg","profile_background_image_url":"http:\/\/a3.twimg.com\/profile_background_images\/162641967\/we_concept_bg2.png","profile_link_color":"0084B4","name":"Erik Michaels-Ober","following":false,"followers_count":897,"screen_name":"sferik","id":7505382,"listed_count":28,"profile_background_tile":false,"utc_offset":-28800,"friends_count":89,"profile_sidebar_fill_color":"DDEEF6"},"coordinates":null,"id":24126047148,"truncated":false,"text":"I'm a big believer that the broken windows theory applies to software development http:\/\/en.wikipedia.org\/wiki\/Broken_windows_theory"},{"in_reply_to_status_id_str":null,"place":null,"geo":null,"favorited":false,"in_reply_to_user_id_str":null,"in_reply_to_status_id":null,"contributors":null,"in_reply_to_screen_name":null,"in_reply_to_user_id":null,"source":"\u003Ca href=\"http:\/\/www.echofon.com\/\" rel=\"nofollow\"\u003EEchofon\u003C\/a\u003E","retweet_count":null,"created_at":"Thu Sep 09 17:12:21 +0000 2010","id_str":"24028079777","retweeted":false,"user":{"statuses_count":2972,"description":"Adventures in hunger and foolishness.","show_all_inline_media":true,"favourites_count":729,"profile_sidebar_border_color":"C0DEED","contributors_enabled":false,"notifications":false,"geo_enabled":true,"time_zone":"Pacific Time (US & Canada)","profile_background_color":"000000","url":null,"verified":false,"follow_request_sent":false,"lang":"en","profile_use_background_image":true,"created_at":"Mon Jul 16 12:59:01 +0000 2007","profile_text_color":"333333","location":"San Francisco","id_str":"7505382","protected":false,"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/323331048\/me_normal.jpg","profile_background_image_url":"http:\/\/a3.twimg.com\/profile_background_images\/162641967\/we_concept_bg2.png","profile_link_color":"0084B4","name":"Erik Michaels-Ober","following":false,"followers_count":897,"screen_name":"sferik","id":7505382,"listed_count":28,"profile_background_tile":false,"utc_offset":-28800,"friends_count":89,"profile_sidebar_fill_color":"DDEEF6"},"coordinates":null,"id":24028079777,"truncated":false,"text":"I hope you idiots are happy with your piece of shit Android phones. http:\/\/www.apple.com\/pr\/library\/2010\/09\/09statement.html"},{"in_reply_to_status_id_str":null,"place":null,"geo":null,"favorited":false,"in_reply_to_user_id_str":null,"in_reply_to_status_id":null,"contributors":null,"in_reply_to_screen_name":null,"in_reply_to_user_id":null,"source":"\u003Ca href=\"http:\/\/www.echofon.com\/\" rel=\"nofollow\"\u003EEchofon\u003C\/a\u003E","retweet_count":null,"created_at":"Wed Sep 01 17:55:15 +0000 2010","id_str":"22728299854","retweeted":false,"user":{"statuses_count":2972,"description":"Adventures in hunger and foolishness.","show_all_inline_media":true,"favourites_count":729,"profile_sidebar_border_color":"C0DEED","contributors_enabled":false,"notifications":false,"geo_enabled":true,"time_zone":"Pacific Time (US & Canada)","profile_background_color":"000000","url":null,"verified":false,"follow_request_sent":false,"lang":"en","profile_use_background_image":true,"created_at":"Mon Jul 16 12:59:01 +0000 2007","profile_text_color":"333333","location":"San Francisco","id_str":"7505382","protected":false,"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/323331048\/me_normal.jpg","profile_background_image_url":"http:\/\/a3.twimg.com\/profile_background_images\/162641967\/we_concept_bg2.png","profile_link_color":"0084B4","name":"Erik Michaels-Ober","following":false,"followers_count":897,"screen_name":"sferik","id":7505382,"listed_count":28,"profile_background_tile":false,"utc_offset":-28800,"friends_count":89,"profile_sidebar_fill_color":"DDEEF6"},"coordinates":null,"id":22728299854,"truncated":false,"text":"Ping: kills MySpace dead."},{"in_reply_to_status_id_str":null,"place":null,"geo":null,"favorited":false,"in_reply_to_user_id_str":null,"in_reply_to_status_id":null,"contributors":null,"in_reply_to_screen_name":null,"in_reply_to_user_id":null,"source":"\u003Ca href=\"http:\/\/www.echofon.com\/\" rel=\"nofollow\"\u003EEchofon\u003C\/a\u003E","retweet_count":null,"created_at":"Wed Sep 01 17:43:30 +0000 2010","id_str":"22727444431","retweeted":false,"user":{"statuses_count":2972,"description":"Adventures in hunger and foolishness.","show_all_inline_media":true,"favourites_count":729,"profile_sidebar_border_color":"C0DEED","contributors_enabled":false,"notifications":false,"geo_enabled":true,"time_zone":"Pacific Time (US & Canada)","profile_background_color":"000000","url":null,"verified":false,"follow_request_sent":false,"lang":"en","profile_use_background_image":true,"created_at":"Mon Jul 16 12:59:01 +0000 2007","profile_text_color":"333333","location":"San Francisco","id_str":"7505382","protected":false,"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/323331048\/me_normal.jpg","profile_background_image_url":"http:\/\/a3.twimg.com\/profile_background_images\/162641967\/we_concept_bg2.png","profile_link_color":"0084B4","name":"Erik Michaels-Ober","following":false,"followers_count":897,"screen_name":"sferik","id":7505382,"listed_count":28,"profile_background_tile":false,"utc_offset":-28800,"friends_count":89,"profile_sidebar_fill_color":"DDEEF6"},"coordinates":null,"id":22727444431,"truncated":false,"text":"Crazy that iTunes Ping didn't leak a drop."},{"in_reply_to_status_id_str":null,"place":{"country_code":"US","place_type":"neighborhood","url":"http:\/\/api.twitter.com\/1\/geo\/id\/5c92ab5379de3839.json","country":"The United States of America","bounding_box":{"type":"Polygon","coordinates":[[[-122.40348192,37.77752898],[-122.387436,37.77752898],[-122.387436,37.79448597],[-122.40348192,37.79448597]]]},"attributes":{},"full_name":"South Beach, San Francisco","name":"South Beach","id":"5c92ab5379de3839"},"geo":{"type":"Point","coordinates":[37.782365,-122.392431]},"favorited":false,"in_reply_to_user_id_str":null,"in_reply_to_status_id":null,"contributors":null,"in_reply_to_screen_name":null,"in_reply_to_user_id":null,"source":"\u003Ca href=\"http:\/\/www.echofon.com\/\" rel=\"nofollow\"\u003EEchofon\u003C\/a\u003E","retweet_count":null,"created_at":"Wed Sep 01 05:53:01 +0000 2010","id_str":"22683247815","retweeted":false,"user":{"statuses_count":2972,"description":"Adventures in hunger and foolishness.","show_all_inline_media":true,"favourites_count":729,"profile_sidebar_border_color":"C0DEED","contributors_enabled":false,"notifications":false,"geo_enabled":true,"time_zone":"Pacific Time (US & Canada)","profile_background_color":"000000","url":null,"verified":false,"follow_request_sent":false,"lang":"en","profile_use_background_image":true,"created_at":"Mon Jul 16 12:59:01 +0000 2007","profile_text_color":"333333","location":"San Francisco","id_str":"7505382","protected":false,"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/323331048\/me_normal.jpg","profile_background_image_url":"http:\/\/a3.twimg.com\/profile_background_images\/162641967\/we_concept_bg2.png","profile_link_color":"0084B4","name":"Erik Michaels-Ober","following":false,"followers_count":897,"screen_name":"sferik","id":7505382,"listed_count":28,"profile_background_tile":false,"utc_offset":-28800,"friends_count":89,"profile_sidebar_fill_color":"DDEEF6"},"coordinates":{"type":"Point","coordinates":[-122.392431,37.782365]},"id":22683247815,"truncated":false,"text":"The plot thickens http:\/\/twitpic.com\/2k5lt2"},{"in_reply_to_status_id_str":null,"place":null,"geo":null,"favorited":false,"in_reply_to_user_id_str":null,"in_reply_to_status_id":null,"contributors":null,"in_reply_to_screen_name":null,"in_reply_to_user_id":null,"source":"\u003Ca href=\"http:\/\/twitter.com\/tweetbutton\" rel=\"nofollow\"\u003ETweet Button\u003C\/a\u003E","retweet_count":null,"created_at":"Fri Aug 27 23:01:19 +0000 2010","id_str":"22305399947","retweeted":false,"user":{"statuses_count":2972,"description":"Adventures in hunger and foolishness.","show_all_inline_media":true,"favourites_count":729,"profile_sidebar_border_color":"C0DEED","contributors_enabled":false,"notifications":false,"geo_enabled":true,"time_zone":"Pacific Time (US & Canada)","profile_background_color":"000000","url":null,"verified":false,"follow_request_sent":false,"lang":"en","profile_use_background_image":true,"created_at":"Mon Jul 16 12:59:01 +0000 2007","profile_text_color":"333333","location":"San Francisco","id_str":"7505382","protected":false,"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/323331048\/me_normal.jpg","profile_background_image_url":"http:\/\/a3.twimg.com\/profile_background_images\/162641967\/we_concept_bg2.png","profile_link_color":"0084B4","name":"Erik Michaels-Ober","following":false,"followers_count":897,"screen_name":"sferik","id":7505382,"listed_count":28,"profile_background_tile":false,"utc_offset":-28800,"friends_count":89,"profile_sidebar_fill_color":"DDEEF6"},"coordinates":null,"id":22305399947,"truncated":false,"text":"140 Proof Provides A Piece Of The Twitter Advertising\u00a0Puzzle http:\/\/t.co\/R2cUSDe via @techcrunch"},{"in_reply_to_status_id_str":null,"place":null,"geo":null,"favorited":false,"in_reply_to_user_id_str":null,"in_reply_to_status_id":null,"contributors":null,"in_reply_to_screen_name":null,"in_reply_to_user_id":null,"source":"\u003Ca href=\"http:\/\/www.echofon.com\/\" rel=\"nofollow\"\u003EEchofon\u003C\/a\u003E","retweet_count":null,"created_at":"Fri Aug 27 22:33:42 +0000 2010","id_str":"22303907694","retweeted":false,"user":{"statuses_count":2972,"description":"Adventures in hunger and foolishness.","show_all_inline_media":true,"favourites_count":729,"profile_sidebar_border_color":"C0DEED","contributors_enabled":false,"notifications":false,"geo_enabled":true,"time_zone":"Pacific Time (US & Canada)","profile_background_color":"000000","url":null,"verified":false,"follow_request_sent":false,"lang":"en","profile_use_background_image":true,"created_at":"Mon Jul 16 12:59:01 +0000 2007","profile_text_color":"333333","location":"San Francisco","id_str":"7505382","protected":false,"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/323331048\/me_normal.jpg","profile_background_image_url":"http:\/\/a3.twimg.com\/profile_background_images\/162641967\/we_concept_bg2.png","profile_link_color":"0084B4","name":"Erik Michaels-Ober","following":false,"followers_count":897,"screen_name":"sferik","id":7505382,"listed_count":28,"profile_background_tile":false,"utc_offset":-28800,"friends_count":89,"profile_sidebar_fill_color":"DDEEF6"},"coordinates":null,"id":22303907694,"truncated":false,"text":"Try as you may http:\/\/www.thedoghousediaries.com\/?p=1940"},{"in_reply_to_status_id_str":null,"place":null,"geo":null,"favorited":false,"in_reply_to_user_id_str":null,"in_reply_to_status_id":null,"contributors":null,"in_reply_to_screen_name":null,"in_reply_to_user_id":null,"source":"\u003Ca href=\"http:\/\/www.echofon.com\/\" rel=\"nofollow\"\u003EEchofon\u003C\/a\u003E","retweet_count":null,"created_at":"Thu Aug 19 01:38:01 +0000 2010","id_str":"21538122473","retweeted":false,"user":{"statuses_count":2972,"description":"Adventures in hunger and foolishness.","show_all_inline_media":true,"favourites_count":729,"profile_sidebar_border_color":"C0DEED","contributors_enabled":false,"notifications":false,"geo_enabled":true,"time_zone":"Pacific Time (US & Canada)","profile_background_color":"000000","url":null,"verified":false,"follow_request_sent":false,"lang":"en","profile_use_background_image":true,"created_at":"Mon Jul 16 12:59:01 +0000 2007","profile_text_color":"333333","location":"San Francisco","id_str":"7505382","protected":false,"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/323331048\/me_normal.jpg","profile_background_image_url":"http:\/\/a3.twimg.com\/profile_background_images\/162641967\/we_concept_bg2.png","profile_link_color":"0084B4","name":"Erik Michaels-Ober","following":false,"followers_count":897,"screen_name":"sferik","id":7505382,"listed_count":28,"profile_background_tile":false,"utc_offset":-28800,"friends_count":89,"profile_sidebar_fill_color":"DDEEF6"},"coordinates":null,"id":21538122473,"truncated":false,"text":"I know @SarahPalinUSA has a right to use Twitter, but should she?"}]
+[{"created_at":"Fri Sep 07 16:35:24 +0000 2012","id":244111636544225280,"id_str":"244111636544225280","text":"Happy Birthday @imdane. Watch out for those @rally pranksters!","source":"\u003ca href=\"http:\/\/twitter.com\/download\/iphone\" rel=\"nofollow\"\u003eTwitter for iPhone\u003c\/a\u003e","truncated":false,"in_reply_to_status_id":null,"in_reply_to_status_id_str":null,"in_reply_to_user_id":null,"in_reply_to_user_id_str":null,"in_reply_to_screen_name":null,"user":{"id":5819322,"id_str":"5819322","name":"Maggie Utgoff","screen_name":"mutgoff","location":"san francisco","description":"I live every week like it's Shark Week. ","url":"http:\/\/www.mutgoff.com","entities":{"url":{"urls":[{"url":"http:\/\/www.mutgoff.com","expanded_url":null,"indices":[0,22]}]},"description":{"urls":[]}},"protected":false,"followers_count":263063,"friends_count":708,"listed_count":534,"created_at":"Mon May 07 01:02:52 +0000 2007","favourites_count":444,"utc_offset":-28800,"time_zone":"Pacific Time (US & Canada)","geo_enabled":true,"verified":false,"statuses_count":4604,"lang":"en","contributors_enabled":false,"is_translator":false,"profile_background_color":"FFFFFF","profile_background_image_url":"http:\/\/a0.twimg.com\/profile_background_images\/344662358\/x88fe902ff835983434794eb1f9d7370.jpg","profile_background_image_url_https":"https:\/\/si0.twimg.com\/profile_background_images\/344662358\/x88fe902ff835983434794eb1f9d7370.jpg","profile_background_tile":false,"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/1199277090\/Screen_shot_2010-12-26_at_11.31.51_AM_normal.png","profile_image_url_https":"https:\/\/si0.twimg.com\/profile_images\/1199277090\/Screen_shot_2010-12-26_at_11.31.51_AM_normal.png","profile_link_color":"9DDD95","profile_sidebar_border_color":"A0EEF5","profile_sidebar_fill_color":"1A3F57","profile_text_color":"72B9BF","profile_use_background_image":true,"show_all_inline_media":true,"default_profile":false,"default_profile_image":false,"following":true,"follow_request_sent":null,"notifications":null},"geo":{"type":"Point","coordinates":[43.46481998,-73.64247884]},"coordinates":{"type":"Point","coordinates":[-73.64247884,43.46481998]},"place":{"id":"003cd76c24b9fa3b","url":"https:\/\/api.twitter.com\/1.1\/geo\/id\/003cd76c24b9fa3b.json","place_type":"city","name":"Bolton","full_name":"Bolton, NY","country_code":"US","country":"United States","bounding_box":{"type":"Polygon","coordinates":[[[-73.750813,43.442073],[-73.525347,43.442073],[-73.525347,43.678377],[-73.750813,43.678377]]]},"attributes":{}},"contributors":null,"retweet_count":0,"entities":{"hashtags":[],"urls":[],"user_mentions":[{"screen_name":"imdane","name":"Dane Hurtubise","id":14076314,"id_str":"14076314","indices":[15,22]},{"screen_name":"rally","name":"Rally","id":16364838,"id_str":"16364838","indices":[44,50]}]},"favorited":false,"retweeted":false},{"created_at":"Fri Sep 07 16:33:36 +0000 2012","id":244111183165157376,"id_str":"244111183165157376","text":"If you like good real-life stories, check out @NarrativelyNY\u2019s just-launched site http:\/\/t.co\/wiUL07jE (and also visit http:\/\/t.co\/ZoyQxqWA)","source":"\u003ca href=\"http:\/\/tapbots.com\" rel=\"nofollow\"\u003eTweetbot for Mac\u003c\/a\u003e","truncated":false,"in_reply_to_status_id":null,"in_reply_to_status_id_str":null,"in_reply_to_user_id":null,"in_reply_to_user_id_str":null,"in_reply_to_screen_name":null,"user":{"id":14163141,"id_str":"14163141","name":"David Friedman","screen_name":"ironicsans","location":"New York","description":"Photographer. Idea blogger. Occasional historian.","url":"http:\/\/www.davidfriedman.info","entities":{"url":{"urls":[{"url":"http:\/\/www.davidfriedman.info","expanded_url":null,"indices":[0,29]}]},"description":{"urls":[]}},"protected":false,"followers_count":4131,"friends_count":1270,"listed_count":220,"created_at":"Mon Mar 17 13:47:33 +0000 2008","favourites_count":1377,"utc_offset":-18000,"time_zone":"Eastern Time (US & Canada)","geo_enabled":true,"verified":false,"statuses_count":4753,"lang":"en","contributors_enabled":false,"is_translator":false,"profile_background_color":"AAB4B5","profile_background_image_url":"http:\/\/a0.twimg.com\/profile_background_images\/66248418\/Untitled-1.gif","profile_background_image_url_https":"https:\/\/si0.twimg.com\/profile_background_images\/66248418\/Untitled-1.gif","profile_background_tile":true,"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/427291735\/n645611374_892426_9102_normal.jpg","profile_image_url_https":"https:\/\/si0.twimg.com\/profile_images\/427291735\/n645611374_892426_9102_normal.jpg","profile_link_color":"0084B4","profile_sidebar_border_color":"BDDCAD","profile_sidebar_fill_color":"DDFFCC","profile_text_color":"333333","profile_use_background_image":true,"show_all_inline_media":true,"default_profile":false,"default_profile_image":false,"following":true,"follow_request_sent":null,"notifications":null},"geo":null,"coordinates":null,"place":null,"contributors":null,"retweet_count":0,"entities":{"hashtags":[],"urls":[{"url":"http:\/\/t.co\/wiUL07jE","expanded_url":"http:\/\/narrative.ly","display_url":"narrative.ly","indices":[82,102]},{"url":"http:\/\/t.co\/ZoyQxqWA","expanded_url":"http:\/\/www.kickstarter.com\/projects\/narratively\/narratively","display_url":"kickstarter.com\/projects\/narra\u2026","indices":[119,139]}],"user_mentions":[{"screen_name":"NarrativelyNY","name":"Narratively","id":576457087,"id_str":"576457087","indices":[46,60]}]},"favorited":false,"retweeted":false,"possibly_sensitive":false},{"created_at":"Fri Sep 07 16:30:14 +0000 2012","id":244110336414859264,"id_str":"244110336414859264","text":"Something else to vote for: \"New Rails workshops to bring more women into the Boston software scene\" http:\/\/t.co\/eNBuckHc \/cc @bostonrb","source":"\u003ca href=\"http:\/\/itunes.apple.com\/us\/app\/twitter\/id409789998?mt=12\" rel=\"nofollow\"\u003eTwitter for Mac\u003c\/a\u003e","truncated":false,"in_reply_to_status_id":null,"in_reply_to_status_id_str":null,"in_reply_to_user_id":null,"in_reply_to_user_id_str":null,"in_reply_to_screen_name":null,"user":{"id":43234200,"id_str":"43234200","name":"Pat Shaughnessy","screen_name":"pat_shaughnessy","location":"Boston","description":"Blogger, Rubyist, Writing a new eBook: http:\/\/patshaughnessy.net\/ruby-under-a-microscope","url":"http:\/\/patshaughnessy.net","entities":{"url":{"urls":[{"url":"http:\/\/patshaughnessy.net","expanded_url":null,"indices":[0,25]}]},"description":{"urls":[]}},"protected":false,"followers_count":734,"friends_count":362,"listed_count":38,"created_at":"Fri May 29 00:55:48 +0000 2009","favourites_count":35,"utc_offset":-18000,"time_zone":"Eastern Time (US & Canada)","geo_enabled":false,"verified":false,"statuses_count":1620,"lang":"en","contributors_enabled":false,"is_translator":false,"profile_background_color":"C0DEED","profile_background_image_url":"http:\/\/a0.twimg.com\/images\/themes\/theme1\/bg.png","profile_background_image_url_https":"https:\/\/si0.twimg.com\/images\/themes\/theme1\/bg.png","profile_background_tile":false,"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/1950093297\/pat2_normal.jpg","profile_image_url_https":"https:\/\/si0.twimg.com\/profile_images\/1950093297\/pat2_normal.jpg","profile_link_color":"0084B4","profile_sidebar_border_color":"C0DEED","profile_sidebar_fill_color":"DDEEF6","profile_text_color":"333333","profile_use_background_image":true,"show_all_inline_media":false,"default_profile":true,"default_profile_image":false,"following":true,"follow_request_sent":null,"notifications":null},"geo":null,"coordinates":null,"place":null,"contributors":null,"retweet_count":0,"entities":{"hashtags":[],"urls":[{"url":"http:\/\/t.co\/eNBuckHc","expanded_url":"http:\/\/news.ycombinator.com\/item?id=4489199","display_url":"news.ycombinator.com\/item?id=4489199","indices":[101,121]}],"user_mentions":[{"screen_name":"bostonrb","name":"Boston Ruby Group","id":21431343,"id_str":"21431343","indices":[126,135]}]},"favorited":false,"retweeted":false,"possibly_sensitive":false},{"created_at":"Fri Sep 07 16:28:05 +0000 2012","id":244109797308379136,"id_str":"244109797308379136","text":"Pushing the button to launch the site. http:\/\/t.co\/qLoEn5jG","source":"\u003ca href=\"http:\/\/instagr.am\" rel=\"nofollow\"\u003eInstagram\u003c\/a\u003e","truncated":false,"in_reply_to_status_id":null,"in_reply_to_status_id_str":null,"in_reply_to_user_id":null,"in_reply_to_user_id_str":null,"in_reply_to_screen_name":null,"user":{"id":1882641,"id_str":"1882641","name":"Caleb Elston","screen_name":"calebelston","location":"San Francisco","description":"Co-founder & CEO of Yobongo. Dubious of people who claim to be experts. Formerly VP Products at Justin.tv. Advisor to Simpler.","url":"http:\/\/www.calebelston.com","entities":{"url":{"urls":[{"url":"http:\/\/www.calebelston.com","expanded_url":null,"indices":[0,26]}]},"description":{"urls":[]}},"protected":false,"followers_count":1960,"friends_count":151,"listed_count":136,"created_at":"Thu Mar 22 14:34:22 +0000 2007","favourites_count":815,"utc_offset":-28800,"time_zone":"Pacific Time (US & Canada)","geo_enabled":true,"verified":false,"statuses_count":7068,"lang":"en","contributors_enabled":false,"is_translator":false,"profile_background_color":"666666","profile_background_image_url":"http:\/\/a0.twimg.com\/profile_background_images\/322151965\/ngb.gif","profile_background_image_url_https":"https:\/\/si0.twimg.com\/profile_background_images\/322151965\/ngb.gif","profile_background_tile":false,"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/2584558450\/elyaf9epw0kcnh9gxglp_normal.jpeg","profile_image_url_https":"https:\/\/si0.twimg.com\/profile_images\/2584558450\/elyaf9epw0kcnh9gxglp_normal.jpeg","profile_link_color":"0099CC","profile_sidebar_border_color":"E3E3E3","profile_sidebar_fill_color":"FFFFFF","profile_text_color":"292E38","profile_use_background_image":false,"show_all_inline_media":true,"default_profile":false,"default_profile_image":false,"following":true,"follow_request_sent":null,"notifications":null},"geo":null,"coordinates":null,"place":null,"contributors":null,"retweet_count":0,"entities":{"hashtags":[],"urls":[{"url":"http:\/\/t.co\/qLoEn5jG","expanded_url":"http:\/\/instagr.am\/p\/PR7YFvRhiO\/","display_url":"instagr.am\/p\/PR7YFvRhiO\/","indices":[39,59]}],"user_mentions":[]},"favorited":false,"retweeted":false,"possibly_sensitive":false},{"created_at":"Fri Sep 07 16:23:50 +0000 2012","id":244108728834592770,"id_str":"244108728834592770","text":"RT @olivercameron: Mosaic looks cool: http:\/\/t.co\/A8013C9k","source":"web","truncated":false,"in_reply_to_status_id":null,"in_reply_to_status_id_str":null,"in_reply_to_user_id":null,"in_reply_to_user_id_str":null,"in_reply_to_screen_name":null,"user":{"id":1882641,"id_str":"1882641","name":"Caleb Elston","screen_name":"calebelston","location":"San Francisco","description":"Co-founder & CEO of Yobongo. Dubious of people who claim to be experts. Formerly VP Products at Justin.tv. Advisor to Simpler.","url":"http:\/\/www.calebelston.com","entities":{"url":{"urls":[{"url":"http:\/\/www.calebelston.com","expanded_url":null,"indices":[0,26]}]},"description":{"urls":[]}},"protected":false,"followers_count":1960,"friends_count":151,"listed_count":136,"created_at":"Thu Mar 22 14:34:22 +0000 2007","favourites_count":815,"utc_offset":-28800,"time_zone":"Pacific Time (US & Canada)","geo_enabled":true,"verified":false,"statuses_count":7068,"lang":"en","contributors_enabled":false,"is_translator":false,"profile_background_color":"666666","profile_background_image_url":"http:\/\/a0.twimg.com\/profile_background_images\/322151965\/ngb.gif","profile_background_image_url_https":"https:\/\/si0.twimg.com\/profile_background_images\/322151965\/ngb.gif","profile_background_tile":false,"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/2584558450\/elyaf9epw0kcnh9gxglp_normal.jpeg","profile_image_url_https":"https:\/\/si0.twimg.com\/profile_images\/2584558450\/elyaf9epw0kcnh9gxglp_normal.jpeg","profile_link_color":"0099CC","profile_sidebar_border_color":"E3E3E3","profile_sidebar_fill_color":"FFFFFF","profile_text_color":"292E38","profile_use_background_image":false,"show_all_inline_media":true,"default_profile":false,"default_profile_image":false,"following":true,"follow_request_sent":null,"notifications":null},"geo":null,"coordinates":null,"place":null,"contributors":null,"retweeted_status":{"created_at":"Fri Sep 07 16:12:47 +0000 2012","id":244105944508796931,"id_str":"244105944508796931","text":"Mosaic looks cool: http:\/\/t.co\/A8013C9k","source":"\u003ca href=\"http:\/\/itunes.apple.com\/us\/app\/twitter\/id409789998?mt=12\" rel=\"nofollow\"\u003eTwitter for Mac\u003c\/a\u003e","truncated":false,"in_reply_to_status_id":null,"in_reply_to_status_id_str":null,"in_reply_to_user_id":null,"in_reply_to_user_id_str":null,"in_reply_to_screen_name":null,"user":{"id":13634322,"id_str":"13634322","name":"Oliver Cameron","screen_name":"olivercameron","location":"Palo Alto, CA","description":"Co-founder of @everyme.","url":"http:\/\/everyme.com","entities":{"url":{"urls":[{"url":"http:\/\/everyme.com","expanded_url":null,"indices":[0,18]}]},"description":{"urls":[]}},"protected":false,"followers_count":1365,"friends_count":218,"listed_count":57,"created_at":"Mon Feb 18 18:08:32 +0000 2008","favourites_count":8,"utc_offset":0,"time_zone":"London","geo_enabled":false,"verified":false,"statuses_count":3346,"lang":"en","contributors_enabled":false,"is_translator":false,"profile_background_color":"FFFFFF","profile_background_image_url":"http:\/\/a0.twimg.com\/profile_background_images\/5435833\/pat_20060420022220.gif","profile_background_image_url_https":"https:\/\/si0.twimg.com\/profile_background_images\/5435833\/pat_20060420022220.gif","profile_background_tile":true,"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/1237999642\/Oliver_normal.png","profile_image_url_https":"https:\/\/si0.twimg.com\/profile_images\/1237999642\/Oliver_normal.png","profile_link_color":"454545","profile_sidebar_border_color":"FFFFFF","profile_sidebar_fill_color":"FFFFFF","profile_text_color":"000000","profile_use_background_image":false,"show_all_inline_media":true,"default_profile":false,"default_profile_image":false,"following":null,"follow_request_sent":null,"notifications":null},"geo":null,"coordinates":null,"place":null,"contributors":null,"retweet_count":1,"entities":{"hashtags":[],"urls":[{"url":"http:\/\/t.co\/A8013C9k","expanded_url":"http:\/\/heymosaic.com\/i\/1Z8ssK","display_url":"heymosaic.com\/i\/1Z8ssK","indices":[19,39]}],"user_mentions":[]},"favorited":false,"retweeted":false,"possibly_sensitive":false},"retweet_count":1,"entities":{"hashtags":[],"urls":[{"url":"http:\/\/t.co\/A8013C9k","expanded_url":"http:\/\/heymosaic.com\/i\/1Z8ssK","display_url":"heymosaic.com\/i\/1Z8ssK","indices":[38,58]}],"user_mentions":[{"screen_name":"olivercameron","name":"Oliver Cameron","id":13634322,"id_str":"13634322","indices":[3,17]}]},"favorited":false,"retweeted":false,"possibly_sensitive":false},{"created_at":"Fri Sep 07 16:20:31 +0000 2012","id":244107890632294400,"id_str":"244107890632294400","text":"The Weatherman is Not a Moron: http:\/\/t.co\/ZwL5Gnq5. An excerpt from my book, THE SIGNAL AND THE NOISE (http:\/\/t.co\/fNXj8vCE)","source":"\u003ca href=\"http:\/\/www.tweetdeck.com\" rel=\"nofollow\"\u003eTweetDeck\u003c\/a\u003e","truncated":false,"in_reply_to_status_id":null,"in_reply_to_status_id_str":null,"in_reply_to_user_id":null,"in_reply_to_user_id_str":null,"in_reply_to_screen_name":null,"user":{"id":16017475,"id_str":"16017475","name":"Nate Silver","screen_name":"fivethirtyeight","location":"New York","description":"FiveThirtyEight blogger (http:\/\/nyti.ms\/Qp8cqb). Author, The Signal and the Noise (http:\/\/amzn.to\/QdyFYV). Sports\/politics\/food geek.","url":"http:\/\/amzn.to\/QdyFYV","entities":{"url":{"urls":[{"url":"http:\/\/amzn.to\/QdyFYV","expanded_url":null,"indices":[0,21]}]},"description":{"urls":[]}},"protected":false,"followers_count":183238,"friends_count":475,"listed_count":8160,"created_at":"Wed Aug 27 20:56:45 +0000 2008","favourites_count":6,"utc_offset":-18000,"time_zone":"Eastern Time (US & Canada)","geo_enabled":false,"verified":true,"statuses_count":6786,"lang":"en","contributors_enabled":false,"is_translator":false,"profile_background_color":"C0DEED","profile_background_image_url":"http:\/\/a0.twimg.com\/images\/themes\/theme1\/bg.png","profile_background_image_url_https":"https:\/\/si0.twimg.com\/images\/themes\/theme1\/bg.png","profile_background_tile":false,"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/1110592135\/fivethirtyeight73_twitter_normal.png","profile_image_url_https":"https:\/\/si0.twimg.com\/profile_images\/1110592135\/fivethirtyeight73_twitter_normal.png","profile_link_color":"0084B4","profile_sidebar_border_color":"C0DEED","profile_sidebar_fill_color":"DDEEF6","profile_text_color":"333333","profile_use_background_image":true,"show_all_inline_media":false,"default_profile":true,"default_profile_image":false,"following":true,"follow_request_sent":null,"notifications":null},"geo":null,"coordinates":null,"place":null,"contributors":null,"retweet_count":19,"entities":{"hashtags":[],"urls":[{"url":"http:\/\/t.co\/ZwL5Gnq5","expanded_url":"http:\/\/nyti.ms\/OW7n5p","display_url":"nyti.ms\/OW7n5p","indices":[31,51]},{"url":"http:\/\/t.co\/fNXj8vCE","expanded_url":"http:\/\/amzn.to\/Qg2SEu","display_url":"amzn.to\/Qg2SEu","indices":[104,124]}],"user_mentions":[]},"favorited":false,"retweeted":false,"possibly_sensitive":false},{"created_at":"Fri Sep 07 16:20:15 +0000 2012","id":244107823733174272,"id_str":"244107823733174272","text":"RT @randomhacks: Going to Code Across Austin II: Y'all Come Hack Now, Sat, Sep 8 http:\/\/t.co\/Sk5BM7U3 We'll see y'all there! #rhok @cod ...","source":"web","truncated":false,"in_reply_to_status_id":null,"in_reply_to_status_id_str":null,"in_reply_to_user_id":null,"in_reply_to_user_id_str":null,"in_reply_to_screen_name":null,"user":{"id":64482503,"id_str":"64482503","name":"Code for America","screen_name":"codeforamerica","location":"San Francisco, California","description":"Code for America helps governments work better for everyone with the people and the power of the web.","url":"http:\/\/www.codeforamerica.org","entities":{"url":{"urls":[{"url":"http:\/\/www.codeforamerica.org","expanded_url":null,"indices":[0,29]}]},"description":{"urls":[]}},"protected":false,"followers_count":11824,"friends_count":783,"listed_count":981,"created_at":"Mon Aug 10 18:59:29 +0000 2009","favourites_count":20,"utc_offset":-28800,"time_zone":"Pacific Time (US & Canada)","geo_enabled":false,"verified":false,"statuses_count":3611,"lang":"en","contributors_enabled":false,"is_translator":false,"profile_background_color":"EBEBEB","profile_background_image_url":"http:\/\/a0.twimg.com\/images\/themes\/theme7\/bg.gif","profile_background_image_url_https":"https:\/\/si0.twimg.com\/images\/themes\/theme7\/bg.gif","profile_background_tile":false,"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/1118630094\/logosquare_bigger_normal.jpg","profile_image_url_https":"https:\/\/si0.twimg.com\/profile_images\/1118630094\/logosquare_bigger_normal.jpg","profile_link_color":"990000","profile_sidebar_border_color":"DFDFDF","profile_sidebar_fill_color":"F3F3F3","profile_text_color":"333333","profile_use_background_image":false,"show_all_inline_media":false,"default_profile":false,"default_profile_image":false,"following":true,"follow_request_sent":null,"notifications":null},"geo":null,"coordinates":null,"place":null,"contributors":null,"retweeted_status":{"created_at":"Fri Sep 07 16:11:02 +0000 2012","id":244105505390350336,"id_str":"244105505390350336","text":"Going to Code Across Austin II: Y'all Come Hack Now, Sat, Sep 8 http:\/\/t.co\/Sk5BM7U3 We'll see y'all there! #rhok @codeforamerica @TheaClay","source":"\u003ca href=\"http:\/\/twitter.com\/tweetbutton\" rel=\"nofollow\"\u003eTweet Button\u003c\/a\u003e","truncated":false,"in_reply_to_status_id":null,"in_reply_to_status_id_str":null,"in_reply_to_user_id":null,"in_reply_to_user_id_str":null,"in_reply_to_screen_name":null,"user":{"id":75361247,"id_str":"75361247","name":"Random Hacks","screen_name":"randomhacks","location":"USA","description":"Official Twitter account for Random Hacks of Kindness.","url":"http:\/\/www.rhok.org","entities":{"url":{"urls":[{"url":"http:\/\/www.rhok.org","expanded_url":null,"indices":[0,19]}]},"description":{"urls":[]}},"protected":false,"followers_count":3917,"friends_count":202,"listed_count":209,"created_at":"Fri Sep 18 19:22:26 +0000 2009","favourites_count":1,"utc_offset":-28800,"time_zone":"Pacific Time (US & Canada)","geo_enabled":true,"verified":false,"statuses_count":1173,"lang":"en","contributors_enabled":false,"is_translator":false,"profile_background_color":"C0DEED","profile_background_image_url":"http:\/\/a0.twimg.com\/profile_background_images\/102109549\/rhok_social_media_wallpaper.png","profile_background_image_url_https":"https:\/\/si0.twimg.com\/profile_background_images\/102109549\/rhok_social_media_wallpaper.png","profile_background_tile":false,"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/905274924\/rhok_social_media_logo_normal.png","profile_image_url_https":"https:\/\/si0.twimg.com\/profile_images\/905274924\/rhok_social_media_logo_normal.png","profile_link_color":"2087E7","profile_sidebar_border_color":"2087E7","profile_sidebar_fill_color":"E8E7E7","profile_text_color":"030303","profile_use_background_image":true,"show_all_inline_media":false,"default_profile":false,"default_profile_image":false,"following":null,"follow_request_sent":null,"notifications":null},"geo":null,"coordinates":null,"place":null,"contributors":null,"retweet_count":2,"entities":{"hashtags":[{"text":"rhok","indices":[109,114]}],"urls":[{"url":"http:\/\/t.co\/Sk5BM7U3","expanded_url":"http:\/\/zvents.com\/e\/IhP3T\/7o","display_url":"zvents.com\/e\/IhP3T\/7o","indices":[64,84]}],"user_mentions":[{"screen_name":"codeforamerica","name":"Code for America","id":64482503,"id_str":"64482503","indices":[115,130]},{"screen_name":"TheaClay","name":"Thea Clay","id":34324747,"id_str":"34324747","indices":[131,140]}]},"favorited":false,"retweeted":false,"possibly_sensitive":false},"retweet_count":2,"entities":{"hashtags":[{"text":"rhok","indices":[126,131]}],"urls":[{"url":"http:\/\/t.co\/Sk5BM7U3","expanded_url":"http:\/\/zvents.com\/e\/IhP3T\/7o","display_url":"zvents.com\/e\/IhP3T\/7o","indices":[81,101]}],"user_mentions":[{"screen_name":"randomhacks","name":"Random Hacks","id":75361247,"id_str":"75361247","indices":[3,15]},{"screen_name":"cod","name":"Chris OBrien","id":13791662,"id_str":"13791662","indices":[132,136]}]},"favorited":false,"retweeted":false,"possibly_sensitive":false},{"created_at":"Fri Sep 07 16:17:55 +0000 2012","id":244107236262170624,"id_str":"244107236262170624","text":"RT @jondot: Just published: \"Pragmatic Concurrency With #Ruby\" http:\/\/t.co\/kGEykswZ \/cc @JRuby @headius","source":"\u003ca href=\"http:\/\/twitter.com\/download\/iphone\" rel=\"nofollow\"\u003eTwitter for iPhone\u003c\/a\u003e","truncated":false,"in_reply_to_status_id":null,"in_reply_to_status_id_str":null,"in_reply_to_user_id":null,"in_reply_to_user_id_str":null,"in_reply_to_screen_name":null,"user":{"id":10248172,"id_str":"10248172","name":"Fredrik Bj\u00f6rk","screen_name":"fbjork","location":"San Francisco, CA","description":"Director of Engineering at @banjo","url":"http:\/\/ban.jo","entities":{"url":{"urls":[{"url":"http:\/\/ban.jo","expanded_url":null,"indices":[0,13]}]},"description":{"urls":[]}},"protected":false,"followers_count":266,"friends_count":343,"listed_count":18,"created_at":"Wed Nov 14 14:58:28 +0000 2007","favourites_count":7,"utc_offset":-28800,"time_zone":"Pacific Time (US & Canada)","geo_enabled":true,"verified":false,"statuses_count":944,"lang":"en","contributors_enabled":false,"is_translator":false,"profile_background_color":"131516","profile_background_image_url":"http:\/\/a0.twimg.com\/images\/themes\/theme14\/bg.gif","profile_background_image_url_https":"https:\/\/si0.twimg.com\/images\/themes\/theme14\/bg.gif","profile_background_tile":true,"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/2167836514\/252562_10150648192185221_786305220_19068177_4887761_n_normal.jpg","profile_image_url_https":"https:\/\/si0.twimg.com\/profile_images\/2167836514\/252562_10150648192185221_786305220_19068177_4887761_n_normal.jpg","profile_link_color":"009999","profile_sidebar_border_color":"EEEEEE","profile_sidebar_fill_color":"EFEFEF","profile_text_color":"333333","profile_use_background_image":true,"show_all_inline_media":true,"default_profile":false,"default_profile_image":false,"following":true,"follow_request_sent":null,"notifications":null},"geo":null,"coordinates":null,"place":null,"contributors":null,"retweeted_status":{"created_at":"Fri Sep 07 15:53:34 +0000 2012","id":244101108983803904,"id_str":"244101108983803904","text":"Just published: \"Pragmatic Concurrency With #Ruby\" http:\/\/t.co\/kGEykswZ \/cc @JRuby @headius","source":"web","truncated":false,"in_reply_to_status_id":null,"in_reply_to_status_id_str":null,"in_reply_to_user_id":null,"in_reply_to_user_id_str":null,"in_reply_to_screen_name":null,"user":{"id":25607541,"id_str":"25607541","name":"dotan nahum","screen_name":"jondot","location":"","description":"I'm just a mean code machine. Constantly scanning, hunting and building the next big thing.","url":"http:\/\/blog.paracode.com","entities":{"url":{"urls":[{"url":"http:\/\/blog.paracode.com","expanded_url":null,"indices":[0,24]}]},"description":{"urls":[]}},"protected":false,"followers_count":410,"friends_count":85,"listed_count":13,"created_at":"Sat Mar 21 00:26:10 +0000 2009","favourites_count":0,"utc_offset":-10800,"time_zone":"Greenland","geo_enabled":false,"verified":false,"statuses_count":784,"lang":"en","contributors_enabled":false,"is_translator":false,"profile_background_color":"2B1F44","profile_background_image_url":"http:\/\/a0.twimg.com\/profile_background_images\/437973354\/nwgrand_516_142243.jpg","profile_background_image_url_https":"https:\/\/si0.twimg.com\/profile_background_images\/437973354\/nwgrand_516_142243.jpg","profile_background_tile":false,"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/1181955409\/nd_normal.png","profile_image_url_https":"https:\/\/si0.twimg.com\/profile_images\/1181955409\/nd_normal.png","profile_link_color":"1C62B9","profile_sidebar_border_color":"F1A253","profile_sidebar_fill_color":"221309","profile_text_color":"755C8A","profile_use_background_image":true,"show_all_inline_media":false,"default_profile":false,"default_profile_image":false,"following":null,"follow_request_sent":null,"notifications":null},"geo":null,"coordinates":null,"place":null,"contributors":null,"retweet_count":8,"entities":{"hashtags":[{"text":"Ruby","indices":[44,49]}],"urls":[{"url":"http:\/\/t.co\/kGEykswZ","expanded_url":"http:\/\/blog.paracode.com\/2012\/09\/07\/pragmatic-concurrency-with-ruby\/","display_url":"blog.paracode.com\/2012\/09\/07\/pra\u2026","indices":[51,71]}],"user_mentions":[{"screen_name":"jruby","name":"JRuby Dev Team","id":16132186,"id_str":"16132186","indices":[78,84]},{"screen_name":"headius","name":"Charles Nutter","id":9989362,"id_str":"9989362","indices":[85,93]}]},"favorited":false,"retweeted":false,"possibly_sensitive":false},"retweet_count":8,"entities":{"hashtags":[{"text":"Ruby","indices":[56,61]}],"urls":[{"url":"http:\/\/t.co\/kGEykswZ","expanded_url":"http:\/\/blog.paracode.com\/2012\/09\/07\/pragmatic-concurrency-with-ruby\/","display_url":"blog.paracode.com\/2012\/09\/07\/pra\u2026","indices":[63,83]}],"user_mentions":[{"screen_name":"jondot","name":"dotan nahum","id":25607541,"id_str":"25607541","indices":[3,10]},{"screen_name":"jruby","name":"JRuby Dev Team","id":16132186,"id_str":"16132186","indices":[90,96]},{"screen_name":"headius","name":"Charles Nutter","id":9989362,"id_str":"9989362","indices":[97,105]}]},"favorited":false,"retweeted":false,"possibly_sensitive":false},{"created_at":"Fri Sep 07 16:14:53 +0000 2012","id":244106476048764928,"id_str":"244106476048764928","text":"If you are wondering how we computed the split bubbles: http:\/\/t.co\/BcaqSs5u","source":"\u003ca href=\"http:\/\/itunes.apple.com\/us\/app\/twitter\/id409789998?mt=12\" rel=\"nofollow\"\u003eTwitter for Mac\u003c\/a\u003e","truncated":false,"in_reply_to_status_id":null,"in_reply_to_status_id_str":null,"in_reply_to_user_id":null,"in_reply_to_user_id_str":null,"in_reply_to_screen_name":null,"user":{"id":43593,"id_str":"43593","name":"Mike Bostock","screen_name":"mbostock","location":"San Francisco, CA","description":"Purveyor of fine misinformations.","url":"http:\/\/bost.ocks.org","entities":{"url":{"urls":[{"url":"http:\/\/bost.ocks.org","expanded_url":null,"indices":[0,20]}]},"description":{"urls":[]}},"protected":false,"followers_count":4090,"friends_count":181,"listed_count":227,"created_at":"Tue Dec 05 21:57:30 +0000 2006","favourites_count":124,"utc_offset":-28800,"time_zone":"Pacific Time (US & Canada)","geo_enabled":true,"verified":false,"statuses_count":2237,"lang":"en","contributors_enabled":false,"is_translator":false,"profile_background_color":"131516","profile_background_image_url":"http:\/\/a0.twimg.com\/images\/themes\/theme14\/bg.gif","profile_background_image_url_https":"https:\/\/si0.twimg.com\/images\/themes\/theme14\/bg.gif","profile_background_tile":true,"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/1434042628\/mbostock-sf_normal.png","profile_image_url_https":"https:\/\/si0.twimg.com\/profile_images\/1434042628\/mbostock-sf_normal.png","profile_link_color":"9F0606","profile_sidebar_border_color":"EEEEEE","profile_sidebar_fill_color":"EFEFEF","profile_text_color":"333333","profile_use_background_image":true,"show_all_inline_media":true,"default_profile":false,"default_profile_image":false,"following":true,"follow_request_sent":null,"notifications":null},"geo":null,"coordinates":null,"place":null,"contributors":null,"retweet_count":1,"entities":{"hashtags":[],"urls":[{"url":"http:\/\/t.co\/BcaqSs5u","expanded_url":"http:\/\/bl.ocks.org\/3422480","display_url":"bl.ocks.org\/3422480","indices":[56,76]}],"user_mentions":[]},"favorited":false,"retweeted":false,"possibly_sensitive":false},{"created_at":"Fri Sep 07 16:11:24 +0000 2012","id":244105599351148544,"id_str":"244105599351148544","text":"\u201cWrite drunk. Edit sober.\u201d\u2014Ernest Hemingway","source":"\u003ca href=\"http:\/\/stone.com\/neue\" rel=\"nofollow\"\u003eTwittelator Neue\u003c\/a\u003e","truncated":false,"in_reply_to_status_id":null,"in_reply_to_status_id_str":null,"in_reply_to_user_id":null,"in_reply_to_user_id_str":null,"in_reply_to_screen_name":null,"user":{"id":485409945,"id_str":"485409945","name":"Fake Jack Dorsey","screen_name":"FakeDorsey","location":"San Francisco","description":"Simplify, bitches.","url":"http:\/\/square.twitter.com","entities":{"url":{"urls":[{"url":"http:\/\/square.twitter.com","expanded_url":null,"indices":[0,25]}]},"description":{"urls":[]}},"protected":false,"followers_count":3275,"friends_count":1,"listed_count":61,"created_at":"Tue Feb 07 05:16:26 +0000 2012","favourites_count":4,"utc_offset":null,"time_zone":null,"geo_enabled":false,"verified":false,"statuses_count":86,"lang":"en","contributors_enabled":false,"is_translator":false,"profile_background_color":"C0DEED","profile_background_image_url":"http:\/\/a0.twimg.com\/images\/themes\/theme1\/bg.png","profile_background_image_url_https":"https:\/\/si0.twimg.com\/images\/themes\/theme1\/bg.png","profile_background_tile":false,"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/1810072255\/Untitled_normal.png","profile_image_url_https":"https:\/\/si0.twimg.com\/profile_images\/1810072255\/Untitled_normal.png","profile_link_color":"0084B4","profile_sidebar_border_color":"C0DEED","profile_sidebar_fill_color":"DDEEF6","profile_text_color":"333333","profile_use_background_image":true,"show_all_inline_media":false,"default_profile":true,"default_profile_image":false,"following":true,"follow_request_sent":null,"notifications":null},"geo":null,"coordinates":null,"place":null,"contributors":null,"retweet_count":14,"entities":{"hashtags":[],"urls":[],"user_mentions":[]},"favorited":false,"retweeted":false},{"created_at":"Fri Sep 07 16:07:16 +0000 2012","id":244104558433951744,"id_str":"244104558433951744","text":"RT @wcmaier: Better banking through better ops: build something new with us @Simplify (remote, PDX) http:\/\/t.co\/8WgzKZH3","source":"\u003ca href=\"http:\/\/tapbots.com\/tweetbot\" rel=\"nofollow\"\u003eTweetbot for iOS\u003c\/a\u003e","truncated":false,"in_reply_to_status_id":null,"in_reply_to_status_id_str":null,"in_reply_to_user_id":null,"in_reply_to_user_id_str":null,"in_reply_to_screen_name":null,"user":{"id":18713,"id_str":"18713","name":"Alex Payne","screen_name":"al3x","location":"Berlin (Aug 31 - Sept 21)","description":"Programmer. Writer. Secular Humanist.","url":"http:\/\/al3x.net","entities":{"url":{"urls":[{"url":"http:\/\/al3x.net","expanded_url":null,"indices":[0,15]}]},"description":{"urls":[]}},"protected":false,"followers_count":36487,"friends_count":323,"listed_count":2272,"created_at":"Thu Nov 23 19:29:11 +0000 2006","favourites_count":4615,"utc_offset":3600,"time_zone":"Berlin","geo_enabled":true,"verified":false,"statuses_count":23134,"lang":"en","contributors_enabled":false,"is_translator":false,"profile_background_color":"E5E9EB","profile_background_image_url":"http:\/\/a0.twimg.com\/images\/themes\/theme1\/bg.png","profile_background_image_url_https":"https:\/\/si0.twimg.com\/images\/themes\/theme1\/bg.png","profile_background_tile":false,"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/357750272\/small_3_normal.png","profile_image_url_https":"https:\/\/si0.twimg.com\/profile_images\/357750272\/small_3_normal.png","profile_link_color":"336699","profile_sidebar_border_color":"333333","profile_sidebar_fill_color":"C3CBD0","profile_text_color":"232323","profile_use_background_image":false,"show_all_inline_media":true,"default_profile":false,"default_profile_image":false,"following":true,"follow_request_sent":null,"notifications":null},"geo":null,"coordinates":null,"place":null,"contributors":null,"retweeted_status":{"created_at":"Fri Sep 07 15:27:38 +0000 2012","id":244094582411890689,"id_str":"244094582411890689","text":"Better banking through better ops: build something new with us @Simplify (remote, PDX) http:\/\/t.co\/8WgzKZH3","source":"\u003ca href=\"http:\/\/tapbots.com\/tweetbot\" rel=\"nofollow\"\u003eTweetbot for iOS\u003c\/a\u003e","truncated":false,"in_reply_to_status_id":null,"in_reply_to_status_id_str":null,"in_reply_to_user_id":null,"in_reply_to_user_id_str":null,"in_reply_to_screen_name":null,"user":{"id":11125102,"id_str":"11125102","name":"Will Maier","screen_name":"wcmaier","location":"Madison, WI, USA","description":"I help @Simplify ship beautiful things. Previously @lt_kije.","url":"http:\/\/wcm.aier.us\/","entities":{"url":{"urls":[{"url":"http:\/\/wcm.aier.us\/","expanded_url":null,"indices":[0,19]}]},"description":{"urls":[]}},"protected":false,"followers_count":240,"friends_count":193,"listed_count":16,"created_at":"Thu Dec 13 12:35:31 +0000 2007","favourites_count":2,"utc_offset":-21600,"time_zone":"Central Time (US & Canada)","geo_enabled":false,"verified":false,"statuses_count":3898,"lang":"en","contributors_enabled":false,"is_translator":false,"profile_background_color":"C0DEED","profile_background_image_url":"http:\/\/a0.twimg.com\/images\/themes\/theme1\/bg.png","profile_background_image_url_https":"https:\/\/si0.twimg.com\/images\/themes\/theme1\/bg.png","profile_background_tile":false,"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/39909052\/kije-final_normal.jpg","profile_image_url_https":"https:\/\/si0.twimg.com\/profile_images\/39909052\/kije-final_normal.jpg","profile_link_color":"0084B4","profile_sidebar_border_color":"C0DEED","profile_sidebar_fill_color":"DDEEF6","profile_text_color":"333333","profile_use_background_image":true,"show_all_inline_media":true,"default_profile":true,"default_profile_image":false,"following":null,"follow_request_sent":null,"notifications":null},"geo":null,"coordinates":null,"place":null,"contributors":null,"retweet_count":3,"entities":{"hashtags":[],"urls":[{"url":"http:\/\/t.co\/8WgzKZH3","expanded_url":"http:\/\/careers.simple.com\/apply\/LKW4tQ\/Operations-Engineer.html","display_url":"careers.simple.com\/apply\/LKW4tQ\/O\u2026","indices":[87,107]}],"user_mentions":[{"screen_name":"Simplify","name":"Simple","id":71165241,"id_str":"71165241","indices":[63,72]}]},"favorited":false,"retweeted":false,"possibly_sensitive":false},"retweet_count":3,"entities":{"hashtags":[],"urls":[{"url":"http:\/\/t.co\/8WgzKZH3","expanded_url":"http:\/\/careers.simple.com\/apply\/LKW4tQ\/Operations-Engineer.html","display_url":"careers.simple.com\/apply\/LKW4tQ\/O\u2026","indices":[100,120]}],"user_mentions":[{"screen_name":"wcmaier","name":"Will Maier","id":11125102,"id_str":"11125102","indices":[3,11]},{"screen_name":"Simplify","name":"Simple","id":71165241,"id_str":"71165241","indices":[76,85]}]},"favorited":false,"retweeted":false,"possibly_sensitive":false},{"created_at":"Fri Sep 07 16:05:38 +0000 2012","id":244104146997870594,"id_str":"244104146997870594","text":"We just announced Mosaic, what we've been working on since the Yobongo acquisition. My personal post, http:\/\/t.co\/ELOyIRZU @heymosaic","source":"web","truncated":false,"in_reply_to_status_id":null,"in_reply_to_status_id_str":null,"in_reply_to_user_id":null,"in_reply_to_user_id_str":null,"in_reply_to_screen_name":null,"user":{"id":1882641,"id_str":"1882641","name":"Caleb Elston","screen_name":"calebelston","location":"San Francisco","description":"Co-founder & CEO of Yobongo. Dubious of people who claim to be experts. Formerly VP Products at Justin.tv. Advisor to Simpler.","url":"http:\/\/www.calebelston.com","entities":{"url":{"urls":[{"url":"http:\/\/www.calebelston.com","expanded_url":null,"indices":[0,26]}]},"description":{"urls":[]}},"protected":false,"followers_count":1960,"friends_count":151,"listed_count":136,"created_at":"Thu Mar 22 14:34:22 +0000 2007","favourites_count":815,"utc_offset":-28800,"time_zone":"Pacific Time (US & Canada)","geo_enabled":true,"verified":false,"statuses_count":7068,"lang":"en","contributors_enabled":false,"is_translator":false,"profile_background_color":"666666","profile_background_image_url":"http:\/\/a0.twimg.com\/profile_background_images\/322151965\/ngb.gif","profile_background_image_url_https":"https:\/\/si0.twimg.com\/profile_background_images\/322151965\/ngb.gif","profile_background_tile":false,"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/2584558450\/elyaf9epw0kcnh9gxglp_normal.jpeg","profile_image_url_https":"https:\/\/si0.twimg.com\/profile_images\/2584558450\/elyaf9epw0kcnh9gxglp_normal.jpeg","profile_link_color":"0099CC","profile_sidebar_border_color":"E3E3E3","profile_sidebar_fill_color":"FFFFFF","profile_text_color":"292E38","profile_use_background_image":false,"show_all_inline_media":true,"default_profile":false,"default_profile_image":false,"following":true,"follow_request_sent":null,"notifications":null},"geo":null,"coordinates":null,"place":null,"contributors":null,"retweet_count":4,"entities":{"hashtags":[],"urls":[{"url":"http:\/\/t.co\/ELOyIRZU","expanded_url":"http:\/\/calebelston.com\/2012\/09\/07\/meet-mosaic\/","display_url":"calebelston.com\/2012\/09\/07\/mee\u2026","indices":[102,122]}],"user_mentions":[{"screen_name":"heymosaic","name":"Mosaic","id":772256556,"id_str":"772256556","indices":[123,133]}]},"favorited":false,"retweeted":false,"possibly_sensitive":false},{"created_at":"Fri Sep 07 16:01:18 +0000 2012","id":244103057175113729,"id_str":"244103057175113729","text":"Donate $10 or more --&gt; get your favorite car magnet: http:\/\/t.co\/NfRhl2s2 #Obama2012","source":"web","truncated":false,"in_reply_to_status_id":null,"in_reply_to_status_id_str":null,"in_reply_to_user_id":null,"in_reply_to_user_id_str":null,"in_reply_to_screen_name":null,"user":{"id":813286,"id_str":"813286","name":"Barack Obama","screen_name":"BarackObama","location":"Washington, DC","description":"This account is run by #Obama2012 campaign staff. Tweets from the President are signed -bo.","url":"http:\/\/www.barackobama.com","entities":{"url":{"urls":[{"url":"http:\/\/www.barackobama.com","expanded_url":null,"indices":[0,26]}]},"description":{"urls":[]}},"protected":false,"followers_count":19449227,"friends_count":673288,"listed_count":175179,"created_at":"Mon Mar 05 22:08:25 +0000 2007","favourites_count":0,"utc_offset":-18000,"time_zone":"Eastern Time (US & Canada)","geo_enabled":false,"verified":true,"statuses_count":5968,"lang":"en","contributors_enabled":true,"is_translator":false,"profile_background_color":"77B0DC","profile_background_image_url":"http:\/\/a0.twimg.com\/profile_background_images\/584034019\/tkwyaf768hs9bylnus1k.jpeg","profile_background_image_url_https":"https:\/\/si0.twimg.com\/profile_background_images\/584034019\/tkwyaf768hs9bylnus1k.jpeg","profile_background_tile":false,"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/2325704772\/wrrmef61i6jl91kwkmzq_normal.png","profile_image_url_https":"https:\/\/si0.twimg.com\/profile_images\/2325704772\/wrrmef61i6jl91kwkmzq_normal.png","profile_link_color":"2574AD","profile_sidebar_border_color":"C2E0F6","profile_sidebar_fill_color":"C2E0F6","profile_text_color":"333333","profile_use_background_image":true,"show_all_inline_media":false,"default_profile":false,"default_profile_image":false,"following":true,"follow_request_sent":null,"notifications":null},"geo":null,"coordinates":null,"place":null,"contributors":null,"retweet_count":147,"entities":{"hashtags":[{"text":"Obama2012","indices":[77,87]}],"urls":[{"url":"http:\/\/t.co\/NfRhl2s2","expanded_url":"http:\/\/OFA.BO\/eWNq2T","display_url":"OFA.BO\/eWNq2T","indices":[56,76]}],"user_mentions":[]},"favorited":false,"retweeted":false,"possibly_sensitive":false},{"created_at":"Fri Sep 07 16:00:25 +0000 2012","id":244102834398851073,"id_str":"244102834398851073","text":"RT @tenderlove: If corporations are people, can we use them to drive in the carpool lane?","source":"\u003ca href=\"http:\/\/sites.google.com\/site\/yorufukurou\/\" rel=\"nofollow\"\u003eYoruFukurou\u003c\/a\u003e","truncated":false,"in_reply_to_status_id":null,"in_reply_to_status_id_str":null,"in_reply_to_user_id":null,"in_reply_to_user_id_str":null,"in_reply_to_screen_name":null,"user":{"id":20941662,"id_str":"20941662","name":"James Edward Gray II","screen_name":"JEG2","location":"Edmond, OK","description":"Rubyist, Husband, Father, Atheist, Oklahoman, and all around weird guy.","url":"http:\/\/blog.grayproductions.net","entities":{"url":{"urls":[{"url":"http:\/\/blog.grayproductions.net","expanded_url":null,"indices":[0,31]}]},"description":{"urls":[]}},"protected":false,"followers_count":4206,"friends_count":174,"listed_count":389,"created_at":"Sun Feb 15 22:05:54 +0000 2009","favourites_count":0,"utc_offset":-21600,"time_zone":"Central Time (US & Canada)","geo_enabled":true,"verified":false,"statuses_count":11780,"lang":"en","contributors_enabled":false,"is_translator":false,"profile_background_color":"EBEBEB","profile_background_image_url":"http:\/\/a0.twimg.com\/images\/themes\/theme7\/bg.gif","profile_background_image_url_https":"https:\/\/si0.twimg.com\/images\/themes\/theme7\/bg.gif","profile_background_tile":false,"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/2311650093\/fkgorpzafxmsafxpf6wi_normal.png","profile_image_url_https":"https:\/\/si0.twimg.com\/profile_images\/2311650093\/fkgorpzafxmsafxpf6wi_normal.png","profile_link_color":"990000","profile_sidebar_border_color":"DFDFDF","profile_sidebar_fill_color":"F3F3F3","profile_text_color":"333333","profile_use_background_image":true,"show_all_inline_media":true,"default_profile":false,"default_profile_image":false,"following":true,"follow_request_sent":null,"notifications":null},"geo":null,"coordinates":null,"place":null,"contributors":null,"retweeted_status":{"created_at":"Fri Sep 07 15:57:28 +0000 2012","id":244102091730210816,"id_str":"244102091730210816","text":"If corporations are people, can we use them to drive in the carpool lane?","source":"\u003ca href=\"http:\/\/www.echofon.com\/\" rel=\"nofollow\"\u003eEchofon\u003c\/a\u003e","truncated":false,"in_reply_to_status_id":null,"in_reply_to_status_id_str":null,"in_reply_to_user_id":null,"in_reply_to_user_id_str":null,"in_reply_to_screen_name":null,"user":{"id":14761655,"id_str":"14761655","name":"Aaron Patterson","screen_name":"tenderlove","location":"Seattle, WA","description":"\u3072\u3052\u306e\u5c71\u7537\u3002 When I'm not trimming my beard, I'm hanging out with my lady, @ebiltwin.","url":"http:\/\/tenderlovemaking.com","entities":{"url":{"urls":[{"url":"http:\/\/tenderlovemaking.com","expanded_url":null,"indices":[0,27]}]},"description":{"urls":[]}},"protected":false,"followers_count":10869,"friends_count":365,"listed_count":862,"created_at":"Tue May 13 17:25:31 +0000 2008","favourites_count":275,"utc_offset":-28800,"time_zone":"Pacific Time (US & Canada)","geo_enabled":true,"verified":false,"statuses_count":14623,"lang":"en","contributors_enabled":false,"is_translator":false,"profile_background_color":"C0DEED","profile_background_image_url":"http:\/\/a0.twimg.com\/images\/themes\/theme1\/bg.png","profile_background_image_url_https":"https:\/\/si0.twimg.com\/images\/themes\/theme1\/bg.png","profile_background_tile":false,"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/1261953917\/headshot_normal.png","profile_image_url_https":"https:\/\/si0.twimg.com\/profile_images\/1261953917\/headshot_normal.png","profile_link_color":"0084B4","profile_sidebar_border_color":"C0DEED","profile_sidebar_fill_color":"DDEEF6","profile_text_color":"333333","profile_use_background_image":true,"show_all_inline_media":false,"default_profile":true,"default_profile_image":false,"following":null,"follow_request_sent":null,"notifications":null},"geo":null,"coordinates":null,"place":null,"contributors":null,"retweet_count":10,"entities":{"hashtags":[],"urls":[],"user_mentions":[]},"favorited":false,"retweeted":false},"retweet_count":10,"entities":{"hashtags":[],"urls":[],"user_mentions":[{"screen_name":"tenderlove","name":"Aaron Patterson","id":14761655,"id_str":"14761655","indices":[3,14]}]},"favorited":false,"retweeted":false},{"created_at":"Fri Sep 07 16:00:03 +0000 2012","id":244102741125890048,"id_str":"244102741125890048","text":"LDN\u2014Obama's nomination; Putin woos APEC; Bombs hit Damascus; Quakes shake China; Canada cuts Iran ties; weekend read: http:\/\/t.co\/OFs6dVW4","source":"web","truncated":false,"in_reply_to_status_id":null,"in_reply_to_status_id_str":null,"in_reply_to_user_id":null,"in_reply_to_user_id_str":null,"in_reply_to_screen_name":null,"user":{"id":632391565,"id_str":"632391565","name":"Evening Edition","screen_name":"eveningedition","location":"","description":"The perfect commute-sized way to catch up on the day\u2019s news after a long day at work. Brought to you by @MuleDesign.","url":"http:\/\/evening-edition.com","entities":{"url":{"urls":[{"url":"http:\/\/evening-edition.com","expanded_url":null,"indices":[0,26]}]},"description&qu