Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
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.
  • 4 commits
  • 15 files changed
  • 0 commit comments
  • 1 contributor
Commits on Mar 30, 2012
@semifor Support for new lists API endpoinds and semantics with backwards compat
New lists API endpoints and semantics are available with the (legacy_lists_api
=> 0) passed to new.  By default, the orginal Lists API endpoints and
semantics are used.
c71ce86
@semifor Replaced JSON::Any with JSON 90d02c6
Commits on Apr 24, 2012
@semifor Rebuilt from Net::Twitter 3.18002 1e81ca3
@semifor Dev release 0.11000_01 e699b42
View
1  .gitignore
@@ -11,3 +11,4 @@ lib/Net/Twitter/Lite.pm
*.gz
.prove
inc/
+MYMETA.*
View
6 Changes
@@ -1,3 +1,9 @@
+0.11000_01 2012-04-24
+ - functional parity with Net::Twitter 3.18002
+ - Replaced JSON::Any with JSON
+ - new lists methods, legacy_lists_api option for back compat
+ - update_with_media and other new API methods ported from Net::Twitter
+
0.10004 2011-03-28
- ported from Net::Twitter 3.16000
- fixed: methods requiring HTTP DELETE failed with OAuth
View
19 Makefile.PL
@@ -1,6 +1,6 @@
use inc::Module::Install;
-version '0.10004';
+version '0.11000_00';
if ( $Module::Install::AUTHOR ) {
eval "use Net::Twitter::Core";
@@ -22,9 +22,10 @@ all_from 'lib/Net/Twitter/Lite.pm';
# core
requires 'Carp';
requires 'Encode';
+requires 'Memoize';
# CPAN
-requires 'JSON::Any' => '1.21';
+requires 'JSON' => 2.02;
requires 'URI' => 1.40;
requires 'URI::Escape';
requires 'LWP::UserAgent' => 2.032;
@@ -40,20 +41,6 @@ feature '.netrc support',
'Net::Netrc' => 0,
;
-# Don't rely on the JSON::Any requirement to pull in a suitable JSON backend.
-# The user may already have JSON::Any installed, but since removed all valid
-# providers. (Yes, this seems to have happened in the wild.)
-sub has_json_handler () {
- my @order = qw/JSON::XS JSON/;
- for my $provider ( @order ) {
- eval "require $provider";
- return 1 unless $@;
- }
- return;
-}
-
-has_json_handler || requires JSON => '2.02';
-
no_index directory => 'src';
no_index directory => 'examples';
View
737 README
@@ -2,7 +2,7 @@ NAME
Net::Twitter::Lite - A perl interface to the Twitter API
VERSION
- This document describes Net::Twitter::Lite version 0.10004
+ This document describes Net::Twitter::Lite version 0.11000_00
SYNOPSIS
use Net::Twitter::Lite;
@@ -10,6 +10,7 @@ SYNOPSIS
my $nt = Net::Twitter::Lite->new(
username => $user,
password => $password
+ legacy_lists_api => 0,
);
my $result = eval { $nt->update('Hello, world!') };
@@ -39,6 +40,25 @@ DESCRIPTION
error handling options.
CLIENT CODE CHANGES REQUIRED
+ Legacy Lists API
+ Twitter re-implemented the Lists API using new endpoints and semantics.
+ For backwards compatibility, this version of "Net::Twitter::Lite"
+ defaults to the deprecated, legacy endpoints and semantics. It issues a
+ warning if the "legacy_lists_api" option to new is not provided.
+
+ To enable the new Lists endpoints and semantics, pass "(legacy_lists_api
+ =" 0)> to "new". To disable the warning, and keep the backwards
+ compatible endpoints and semantics, pass "(legacy_lists_api =" 1)> to
+ "new".
+
+ The "legacy_lists_api" option to "new" sets the default for all lists
+ API method calls. You can override the default an each API call by
+ passing a "-legacy_lists_api" option set to 1 or 0.
+
+ Support for "legacy_lists_api" option will be removed in a future
+ version and the option to "new" will be silently ignored.
+
+ netrc option
The default "apiurl" changed in version 0.08006. The change should be
transparent to client code, unless you're using the "netrc" option. If
so, you'll need to either update the ".netrc" entry and change the
@@ -49,7 +69,7 @@ CLIENT CODE CHANGES REQUIRED
# -or-
$nt = Net::Twitter::Lite->new(netrc => 'twitter.com');
-IMPORTANT
+ OAuth requires callback parameter
Beginning with version 0.03, it is necessary for web applications using
OAuth authentication to pass the "callback" parameter to
"get_authorization_url". In the absence of a callback parameter, when
@@ -254,7 +274,7 @@ METHODS AND ARGUMENTS
useragent
The value for "User-Agent" HTTP header. It defaults to
- "Net::Twitter::Lite/0.10004 (Perl)".
+ "Net::Twitter::Lite/0.11000_00 (Perl)".
source
The value used in the "source" parameter of API method calls. It
@@ -299,6 +319,16 @@ METHODS AND ARGUMENTS
(Optional) Sets the "machine" entry to look up in ".netrc" when
"<netrc =" 1>> is used. Defaults to "api.twitter.com".
+ legacy_lists_api
+ If set to 1, this option enables backwards compatibility by
+ using the now deprecated endpoints and semantics for lists API
+ methods. If set to 0, the new endpoints and semantics will be
+ used. Only the new lists API methods are documented here.
+
+ If you do not provide this option to "new" a warning is issued.
+ Support for this option and the legacy lists API methods will be
+ removed in a future version.
+
BASIC AUTHENTICATION METHODS
credentials($username, $password)
Set the credentials for Basic Authentication. This is helpful for
@@ -472,17 +502,47 @@ REST API Methods
Returns: HashRef
- all_lists
- all_lists(id)
+ add_list_member
- Parameters: id, user_id, screen_name
- Required: id
+ Parameters: list_id, slug, user_id, screen_name, owner_screen_name,
+ owner_id
+ Required: *none*
+
+ Add a member to a list. The authenticated user must own the list to
+ be able to add members to it. Note that lists can't have more than
+ 500 members.
+
+ Returns: User
+
+ add_place
+ add_place(name, contained_within, token, lat, long)
+
+ Parameters: name, contained_within, token, lat, long,
+ attribute:street_address, callback
+ Required: name, contained_within, token, lat, long
+
+ Creates a new place object at the given latitude and longitude.
+
+ Before creating a place you need to query "similar_places" with the
+ latitude, longitude and name of the place you wish to create. The
+ query will return an array of places which are similar to the one
+ you wish to create, and a token. If the place you wish to create
+ isn't in the returned array you can use the token with this method
+ to create a new one.
+
+ Returns: Place
+
+ all_subscriptions
+ alias: all_lists
+ alias: list_subscriptions
+
+ Parameters: user_id, screen_name, count, cursor
+ Required: *none*
Returns all lists the authenticating or specified user subscribes
- to, including their own. The user is specified using the "user_id"
- or "screen_name parameters". If no user is given, the authenticating
- user is used. Requires authentication unless requesting for another
- user.
+ to, including their own. The user is specified using the user_id or
+ screen_name parameters. If no user is given, the authenticating user
+ is used.
Returns: ArrayRef[List]
@@ -518,6 +578,25 @@ REST API Methods
Returns: ArrayRef[Int]
+ contributees
+
+ Parameters: user_id, screen_name, include_entities, skip_satus
+ Required: *none*
+
+ Returns an array of users that the specified user can contribute to.
+
+ Returns: ArrayRef[User]
+
+ contributors
+
+ Parameters: user_id, screen_name, include_entities, skip_satus
+ Required: *none*
+
+ Returns an array of users who can contribute to the specified
+ account.
+
+ Returns: ArrayRef[User]
+
create_block
create_block(id)
@@ -554,6 +633,17 @@ REST API Methods
Returns: BasicUser
+ create_list
+
+ Parameters: list_id, slug, name, mode, description,
+ owner_screen_name, owner_id
+ Required: *none*
+
+ Creates a new list for the authenticated user. Note that you can't
+ create more than 20 lists per account.
+
+ Returns: List
+
create_saved_search
create_saved_search(query)
@@ -564,10 +654,32 @@ REST API Methods
Returns: SavedSearch
+ delete_list
+
+ Parameters: owner_screen_name, owner_id, list_id, slug
+ Required: *none*
+
+ Deletes the specified list. The authenticated user must own the list
+ to be able to destroy it.
+
+ Returns: List
+
+ delete_list_member
+ alias: remove_list_member
+
+ Parameters: list_id, slug, user_id, screen_name, owner_screen_name,
+ owner_id
+ Required: *none*
+
+ Removes the specified member from the list. The authenticated user
+ must be the list's owner to remove members from the list.
+
+ Returns: User
+
destroy_block
destroy_block(id)
- Parameters: id, user_idscreen_name
+ Parameters: id, user_id, screen_name
Required: id
Un-blocks the user specified in the ID parameter as the
@@ -689,30 +801,6 @@ REST API Methods
Returns: ArrayRef[Status]
- followers
-
- Parameters: id, user_id, screen_name, cursor, include_entities
- Required: *none*
-
- Returns a reference to an array of the user's followers. If "id",
- "user_id", or "screen_name" is not specified, the followers of the
- authenticating user are returned. The returned users are ordered
- from most recently followed to least recently followed.
-
- Use the optional "cursor" parameter to retrieve users in pages of
- 100. When the "cursor" parameter is used, the return value is a
- reference to a hash with keys "previous_cursor", "next_cursor", and
- "users". The value of "users" is a reference to an array of the
- user's friends. The result set isn't guaranteed to be 100 every time
- as suspended users will be filtered out. Set the optional "cursor"
- parameter to -1 to get the first page of users. Set it to the prior
- return's value of "previous_cursor" or "next_cursor" to page forward
- or backwards. When there are no prior pages, the value of
- "previous_cursor" will be 0. When there are no subsequent pages, the
- value of "next_cursor" will be 0.
-
- Returns: HashRef|ArrayRef[User]
-
followers_ids
followers_ids(id)
@@ -720,7 +808,9 @@ REST API Methods
Required: id
Returns a reference to an array of numeric IDs for every user
- following the specified user.
+ following the specified user. The order of the IDs may change from
+ call to call. To obtain the screen names, pass the arrayref to
+ "lookup_users".
Use the optional "cursor" parameter to retrieve IDs in pages of
5000. When the "cursor" parameter is used, the return value is a
@@ -735,31 +825,6 @@ REST API Methods
Returns: HashRef|ArrayRef[Int]
- friends
- alias: following
-
- Parameters: id, user_id, screen_name, cursor, include_entities
- Required: *none*
-
- Returns a reference to an array of the user's friends. If "id",
- "user_id", or "screen_name" is not specified, the friends of the
- authenticating user are returned. The returned users are ordered
- from most recently followed to least recently followed.
-
- Use the optional "cursor" parameter to retrieve users in pages of
- 100. When the "cursor" parameter is used, the return value is a
- reference to a hash with keys "previous_cursor", "next_cursor", and
- "users". The value of "users" is a reference to an array of the
- user's friends. The result set isn't guaranteed to be 100 every time
- as suspended users will be filtered out. Set the optional "cursor"
- parameter to -1 to get the first page of users. Set it to the prior
- return's value of "previous_cursor" or "next_cursor" to page forward
- or backwards. When there are no prior pages, the value of
- "previous_cursor" will be 0. When there are no subsequent pages, the
- value of "next_cursor" will be 0.
-
- Returns: Hashref|ArrayRef[User]
-
friends_ids
friends_ids(id)
alias: following_ids
@@ -768,7 +833,8 @@ REST API Methods
Required: id
Returns a reference to an array of numeric IDs for every user
- followed the specified user.
+ followed by the specified user. The order of the IDs is reverse
+ chronological.
Use the optional "cursor" parameter to retrieve IDs in pages of
5000. When the "cursor" parameter is used, the return value is a
@@ -783,30 +849,31 @@ REST API Methods
Returns: HashRef|ArrayRef[Int]
- friends_timeline
- alias: following_timeline
-
- Parameters: since_id, max_id, count, page, skip_user, trim_user,
- include_entities, include_rts
- Required: *none*
-
- Returns the 20 most recent statuses posted by the authenticating
- user and that user's friends. This is the equivalent of /home on the
- Web.
-
- Returns: ArrayRef[Status]
-
friendship_exists
friendship_exists(user_a, user_b)
alias: relationship_exists
alias: follows
- Parameters: user_a, user_b
+ Parameters: user_id_a, user_id_b, screen_name_a, screen_name_b,
+ user_a, user_b
Required: user_a, user_b
Tests for the existence of friendship between two users. Will return
true if user_a follows user_b, otherwise will return false.
+ Use of "user_a" and "user_b" is deprecated. It has been preserved
+ for backwards compatibility, and is used for the two-argument
+ positional form:
+
+ $nt->friendship_exists($user_a, $user_b);
+
+ Instead, you should use one of the named argument forms:
+
+ $nt->friendship_exists({ user_id_a => $id1, user_id_b => $id2 });
+ $nt->friendship_exists({ screen_name_a => $name1, screen_name_b => $name2 });
+
+ Consider using "show_friendship" instead.
+
Returns: Bool
friendships_incoming
@@ -844,6 +911,96 @@ REST API Methods
Returns: HashRef
+ geo_search
+
+ Parameters: lat, long, query, ip, granularity, accuracy,
+ max_results, contained_within, attribute:street_address, callback
+ Required: *none*
+
+ Search for places that can be attached to a statuses/update. Given a
+ latitude and a longitude pair, an IP address, or a name, this
+ request will return a list of all the valid places that can be used
+ as the place_id when updating a status.
+
+ Conceptually, a query can be made from the user's location, retrieve
+ a list of places, have the user validate the location he or she is
+ at, and then send the ID of this location with a call to
+ statuses/update.
+
+ This is the recommended method to use find places that can be
+ attached to statuses/update. Unlike geo/reverse_geocode which
+ provides raw data access, this endpoint can potentially re-order
+ places with regards to the user who is authenticated. This approach
+ is also preferred for interactive place matching with the user.
+
+ Returns: HashRef
+
+ get_configuration
+
+ Parameters: *none*
+ Required: *none*
+
+ Returns the current configuration used by Twitter including
+ twitter.com slugs which are not usernames, maximum photo
+ resolutions, and t.co URL lengths.
+
+ It is recommended applications request this endpoint when they are
+ loaded, but no more than once a day.
+
+ Returns: HashRef
+
+ get_languages
+
+ Parameters: *none*
+ Required: *none*
+
+ Returns the list of languages supported by Twitter along with their
+ ISO 639-1 code. The ISO 639-1 code is the two letter value to use if
+ you include lang with any of your requests.
+
+ Returns: ArrayRef[Lanugage]
+
+ get_list
+
+ Parameters: list_id, slug, owner_screen_name, owner_id
+ Required: *none*
+
+ Returns the specified list. Private lists will only be shown if the
+ authenticated user owns the specified list.
+
+ Returns: List
+
+ get_lists
+ alias: list_lists
+
+ Parameters: user_id, screen_name, cursor
+ Required: *none*
+
+ Returns the lists of the specified (or authenticated) user. Private
+ lists will be included if the authenticated user is the same as the
+ user whose lists are being returned.
+
+ Returns: Hashref
+
+ get_privacy_policy
+
+ Parameters: *none*
+ Required: *none*
+
+ Returns Twitter's privacy policy.
+
+ Returns: HashRef
+
+ get_tos
+
+ Parameters: *none*
+ Required: *none*
+
+ Returns the Twitter Terms of Service. These are not the same as the
+ Developer Rules of the Road.
+
+ Returns: HashRef
+
home_timeline
Parameters: since_id, max_id, count, page, skip_user,
@@ -857,6 +1014,76 @@ REST API Methods
Returns: ArrayRef[Status]
+ is_list_member
+
+ Parameters: owner_screen_name, owner_id, list_id, slug, user_id,
+ screen_name, include_entities, skip_status
+ Required: *none*
+
+ Check if the specified user is a member of the specified list.
+ Returns the user or undef.
+
+ Returns: Maybe[User]
+
+ is_list_subscriber
+ alias: is_subscribed_list
+
+ Parameters: owner_screen_name, owner_id, list_id, slug, user_id,
+ screen_name, include_entities, skip_status
+ Required: *none*
+
+ Check if the specified user is a subscriber of the specified list.
+ Returns the user or undef.
+
+ Returns: Maybe[User]
+
+ list_members
+
+ Parameters: list_id, slug, owner_screen_name, owner_id, cursor,
+ include_entities, skip_status
+ Required: *none*
+
+ Returns the members of the specified list. Private list members will
+ only be shown if the authenticated user owns the specified list.
+
+ Returns: Hashref
+
+ list_memberships
+
+ Parameters: user_id, screen_name, cursor, filter_to_owned_lists
+ Required: *none*
+
+ Returns the lists the specified user has been added to. If user_id
+ or screen_name are not provided the memberships for the
+ authenticating user are returned.
+
+ Returns: Hashref
+
+ list_statuses
+
+ Parameters: list_id, slug, owner_screen_name, owner_id, since_id,
+ max_id, per_page, page, include_entities, include_rts
+ Required: *none*
+
+ Returns tweet timeline for members of the specified list.
+ Historically, retweets were not available in list timeline responses
+ but you can now use the include_rts=true parameter to additionally
+ receive retweet objects.
+
+ Returns: ArrayRef[Status]
+
+ list_subscribers
+
+ Parameters: list_id, slug, owner_screen_name, owner_id, cursor,
+ include_entities, skip_status
+ Required: *none*
+
+ Returns the subscribers of the specified list. Private list
+ subscribers will only be shown if the authenticated user owns the
+ specified list.
+
+ Returns: Hashref
+
lookup_friendships
Parameters: user_id, screen_name
@@ -874,7 +1101,7 @@ REST API Methods
Parameters: user_id, screen_name, include_entities
Required: *none*
- Return up to 20 users worth of extended information, specified by
+ Return up to 100 users worth of extended information, specified by
either ID, screen name, or combination of the two. The author's most
recent status (if the authenticating user has permission) will be
returned inline. This method is rate limited to 1000 calls per hour.
@@ -897,6 +1124,42 @@ REST API Methods
Returns: ArrayRef[User]
+ members_create_all
+ alias: add_list_members
+
+ Parameters: list_id, slug, owner_screen_name, owner_id
+ Required: *none*
+
+ Adds multiple members to a list, by specifying a reference to an
+ array or a comma-separated list of member ids or screen names. The
+ authenticated user must own the list to be able to add members to
+ it. Note that lists can't have more than 500 members, and you are
+ limited to adding up to 100 members to a list at a time with this
+ method.
+
+ Returns: List
+
+ members_destroy_all
+ alias: remove_list_members
+
+ Parameters: list_id, slug, user_id, screen_name, owner_screen_name,
+ owner_id
+ Required: *none*
+
+ Removes multiple members from a list, by specifying a reference to
+ an array of member ids or screen names, or a string of comma
+ separated user ids or screen names. The authenticated user must own
+ the list to be able to remove members from it. Note that lists can't
+ have more than 500 members, and you are limited to removing up to
+ 100 members to a list at a time with this method.
+
+ Please note that there can be issues with lists that rapidly remove
+ and add memberships. Take care when using these methods such that
+ you are not too rapidly switching between removals and adds on the
+ same list.
+
+ Returns: List
+
mentions
alias: replies
@@ -1193,7 +1456,7 @@ REST API Methods
Parameters: id
Required: id
- Retrieve the data for a saved search, by ID, owned by the
+ Retrieve the data for a saved search, by "id", owned by the
authenticating user.
Returns: SavedSearch
@@ -1223,6 +1486,44 @@ REST API Methods
Returns: ExtendedUser
+ similar_places
+ similar_places(lat, long, name)
+
+ Parameters: lat, long, name, contained_within,
+ attribute:street_address, callback
+ Required: lat, long, name
+
+ Locates places near the given coordinates which are similar in name.
+
+ Conceptually you would use this method to get a list of known places
+ to choose from first. Then, if the desired place doesn't exist, make
+ a request to "add_place" to create a new one.
+
+ The token contained in the response is the token needed to be able
+ to create a new place.
+
+ Returns: HashRef
+
+ subscribe_list
+
+ Parameters: owner_screen_name, owner_id, list_id, slug
+ Required: *none*
+
+ Subscribes the authenticated user to the specified list.
+
+ Returns: List
+
+ subscriptions
+
+ Parameters: user_id, screen_name, count, cursor
+ Required: *none*
+
+ Obtain a collection of the lists the specified user is subscribed
+ to, 20 lists per page by default. Does not include the user's own
+ lists.
+
+ Returns: ArrayRef[List]
+
suggestion_categories
Parameters: *none*
@@ -1243,18 +1544,6 @@ REST API Methods
Returns: Str
- trends
-
- Parameters: *none*
- Required: *none*
-
- Returns the top ten queries that are currently trending on Twitter.
- The response includes the time of the request, the name of each
- trending topic, and the url to the Twitter Search results page for
- that topic.
-
- Returns: ArrayRef[Query]
-
trends_available
Parameters: lat, long
@@ -1323,6 +1612,15 @@ REST API Methods
Returns: HashRef
+ unsubscribe_list
+
+ Parameters: list_id, slug, owner_screen_name, owner_id
+ Required: *none*
+
+ Unsubscribes the authenticated user from the specified list.
+
+ Returns: List
+
update
update(status)
@@ -1398,6 +1696,17 @@ REST API Methods
Returns: HashRef
+ update_list
+
+ Parameters: list_id, slug, name, mode, description,
+ owner_screen_name, owner_id
+ Required: *none*
+
+ Updates the specified list. The authenticated user must own the list
+ to be able to update it.
+
+ Returns: List
+
update_profile
Parameters: name, email, url, location, description,
@@ -1464,6 +1773,40 @@ REST API Methods
Returns: ExtendedUser
+ update_with_media
+ update_with_media(status, media)
+
+ Parameters: status, media[], possibly_sensitive,
+ in_reply_to_status_id, lat, long, place_id, display_coordinates
+ Required: status, media
+
+ Updates the authenticating user's status and attaches media for
+ upload.
+
+ The "media[]" parameter is an arrayref with the following
+ interpretation:
+
+ [ $file ]
+ [ $file, $filename ]
+ [ $file, $filename, Content_Type => $mime_type ]
+ [ undef, $filename, Content_Type => $mime_type, Content => $raw_image_data ]
+
+ The first value of the array ($file) is the name of a file to open.
+ The second value ($filename) is the name given to Twitter for the
+ file. If $filename is not provided, the basename portion of $file is
+ used. If $mime_type is not provided, it will be provided
+ automatically using LWP::MediaTypes::guess_media_type().
+
+ $raw_image_data can be provided, rather than opening a file, by
+ passing "undef" as the first array value.
+
+ The Tweet text will be rewritten to include the media URL(s), which
+ will reduce the number of characters allowed in the Tweet text. If
+ the URL(s) cannot be appended without text truncation, the tweet
+ will be rejected and this method will return an HTTP 403 error.
+
+ Returns: Status
+
user_suggestions
user_suggestions(category)
alias: follow_suggestions
@@ -1540,218 +1883,6 @@ Search API Methods
Returns: HashRef
-Lists API Methods
- add_list_member
- add_list_member(user, list_id, id)
-
- Parameters: user, list_id, id
- Required: user, list_id, id
-
- Adds the user identified by "id" to the list.
-
- Returns a reference the added user as a hash reference.
-
- Returns: User
-
- create_list
- create_list(user, name)
-
- Parameters: user, name, mode, description
- Required: user, name
-
- Creates a new list for the authenticated user. The "mode" parameter
- may be either "public" or "private". If not specified, it defaults
- to "public".
-
- Returns: HashRef
-
- delete_list
- delete_list(user, list_id)
-
- Parameters: user, list_id
- Required: user, list_id
-
- Deletes a list owned by the authenticating user. Returns the list as
- a hash reference.
-
- Returns:
-
- delete_list_member
- delete_list_member(user, list_id, id)
- alias: remove_list_member
-
- Parameters: user, list_id, id
- Required: user, list_id, id
-
- Deletes the user identified by "id" from the specified list.
-
- Returns the deleted user as a hash reference.
-
- Returns:
-
- get_list
- get_list(user, list_id)
-
- Parameters: user, list_id
- Required: user, list_id
-
- Returns the specified list as a hash reference.
-
- Returns: HashRef
-
- get_lists
- get_lists(user)
- alias: list_lists
-
- Parameters: user, cursor
- Required: user
-
- Returns a reference to an array of lists owned by the specified
- user. If the user is the authenticated user, it returns both public
- and private lists. Otherwise, it only returns public lists.
-
- When the "cursor" parameter is used, a hash reference is returned;
- the lists are returned in the "lists" element of the hash.
-
- Returns: ArrayRef[List]
-
- is_list_member
- is_list_member(user, list_id, id)
-
- Parameters: user, list_id, id
- Required: user, list_id, id
-
- Returns the list member as a HASH reference if "id" is a member of
- the list. Otherwise, returns undef.
-
- Returns: ArrayRef[User]
-
- is_list_subscriber
- is_list_subscriber(user, list_id, id)
- alias: is_subscribed_list
-
- Parameters: user, list_id, id
- Required: user, list_id, id
-
- Returns the subscriber as a HASH reference if "id" is a subscriber
- to the list. Otherwise, returns undef.
-
- Returns: ArrayRef[User]
-
- list_members
- list_members(user, list_id)
-
- Parameters: user, list_id, id, cursor
- Required: user, list_id
-
- Returns the list members as an array reference.
-
- The optional "id" parameter can be used to determine if the user
- specified by "id" is a member of the list. If so, the user is
- returned as a hash reference; if not, "undef" is returned.
-
- When the "cursor" parameter is used, a hash reference is returned;
- the members are returned in the "users" element of the hash.
-
- Returns: ArrayRef[User]
-
- list_memberships
- list_memberships(user)
-
- Parameters: user, cursor
- Required: user
-
- Returns the lists the specified user is a member of as an array
- reference.
-
- When the "cursor" parameter is used, a hash reference is returned;
- the lists are returned in the "lists" element of the hash.
-
- Returns:
-
- list_statuses
- list_statuses(user, list_id)
-
- Parameters: user, list_id, since_id, max_id, per_page, page
- Required: user, list_id
-
- Returns a timeline of list member statuses as an array reference.
-
- Returns: ArrayRef[Status]
-
- list_subscribers
- list_subscribers(user, list_id)
-
- Parameters: user, list_id, id, cursor
- Required: user, list_id
-
- Returns the subscribers to a list as an array reference.
-
- When the "cursor" parameter is used, a hash reference is returned;
- the subscribers are returned in the "users" element of the hash.
-
- Returns: ArrayRef[User]
-
- list_subscriptions
- list_subscriptions(user)
-
- Parameters: user, cursor
- Required: user
-
- Returns a lists to which the specified user is subscribed as an
- array reference.
-
- When the "cursor" parameter is used, a hash reference is returned;
- the lists are returned in the "lists" element of the hash.
-
- Returns:
-
- members_create_all
- members_create_all(user, list_id)
- alias: add_list_members
-
- Parameters: user, list_id, screen_name, user_id
- Required: user, list_id
-
- Adds multiple users "id" to the list. Users are specified with the
- "screen_name" or "user_id" parameter with a reference to an ARRAY of
- values.
-
- Returns a reference the added user as a hash reference.
-
- Returns: ArrayRef[User]
-
- subscribe_list
- subscribe_list(user, list_id)
-
- Parameters: user, list_id
- Required: user, list_id
-
- Subscribes the authenticated user to the specified list.
-
- Returns: List
-
- unsubscribe_list
- unsubscribe_list(user, list_id)
-
- Parameters: user, list_id
- Required: user, list_id
-
- Unsubscribes the authenticated user from the specified list.
-
- Returns: List
-
- update_list
- update_list(user, list_id)
-
- Parameters: user, list_id, name, mode, description
- Required: user, list_id
-
- Updates a list to change the name, mode, description, or any
- combination thereof.
-
- Returns: HashRef
-
ERROR HANDLING
When "Net::Twitter::Lite" encounters a Twitter API error or a network
error, it throws a "Net::Twitter::Lite::Error" object. You can catch and
View
12 src/build.pl
@@ -1,12 +1,15 @@
#!/usr/bin/perl
use warnings;
use strict;
+use Memoize;
use Net::Twitter;
use Template;
my ($version, $input, $output) = @ARGV;
+memoize('get_methods_for');
+
my $tt = Template->new;
$tt->process($input, {
VERSION => $version,
@@ -16,20 +19,25 @@
$output,
) || die $tt->error;
+my %seen;
sub get_methods_for {
- my $api = shift;
+ my ( $api, $filter ) = @_;
+ $filter ||= '.';
+
+ my $filter_re = qr/$filter/;
my $nt = Net::Twitter->new(traits => [ "API::$api" ]);
return
sort { $a->{name} cmp $b->{name} }
+ grep { $_->{name} =~ $filter_re }
grep {
$_->isa('Net::Twitter::Meta::Method')
}
map {
$_->isa('Class::MOP::Method::Wrapped') ? $_->get_original_method : $_
} $nt->meta->get_all_methods;
-}
+}
sub get_base_url_for {
my $api = shift;
View
125 src/net-twitter-lite.tt2
@@ -8,12 +8,12 @@ $VERSION = eval { $VERSION };
use Carp;
use URI::Escape;
-use JSON::Any qw/XS JSON/;
+use JSON;
use HTTP::Request::Common;
use Net::Twitter::Lite::Error;
use Encode qw/encode_utf8/;
-my $json_handler = JSON::Any->new(utf8 => 1);
+my $json_handler = JSON->new->utf8;
sub new {
my ($class, %args) = @_;
@@ -44,6 +44,20 @@ sub new {
%args
}, $class;
+ unless ( exists $new->{legacy_lists_api} ) {
+ $new->{legacy_lists_api} = 1;
+ carp
+"For backwards compatibility @{[ __PACKAGE__ ]} uses the deprecated Lists API
+endpoints and semantics. This default will be changed in a future version.
+Please update your code to use the new lists semantics and pass
+(legacy_lists_api => 0) to new.
+
+You can disable this warning, and keep backwards compatibility by passing
+(legacy_lists_api => 1) to new. Be warned, however, that support for the
+legacy endpoints will be removed in a future version and the default will
+change to (legacy_lists_api => 0).";
+
+ }
if ( delete $args{ssl} ) {
$new->{$_} =~ s/^http:/https:/
@@ -390,20 +404,20 @@ sub _mk_post_msg {
{ ### scope $api_def
my $api_def = [
-[% FOREACH api IN [ 'REST', 'Search', 'Lists' ] -%]
- [ [% api %] => [
-[% FOREACH method IN get_methods_for(api) -%]
+[% FOREACH api IN [ [ 'Lists', '^legacy_' ], [ 'REST' ], [ 'Search' ] ] -%]
+ [ [% api.0 %] => [
+[% FOREACH method IN get_methods_for(api.0, api.1) -%]
[ '[% method.name %]', {
- aliases => [ qw/[% method.aliases.join(' ') %]/ ],
- path => '[% method.path %]',
- method => '[% method.method %]',
- params => [ qw/[% method.params.join(' ') %]/ ],
- required => [ qw/[% method.required.join(' ') %]/ ],
- add_source => [% method.add_source %],
- deprecated => [% method.deprecated %],
- authenticate => [% method.authenticate %],
- booleans => [ qw/[% method.booleans.join(' ') %]/ ],
- base_url_method => '[% method.base_url_method %]',
+ aliases => [ qw/[% method.aliases.join(' ') %]/ ],
+ path => '[% method.path %]',
+ method => '[% method.method %]',
+ params => [ qw/[% method.params.join(' ') %]/ ],
+ required => [ qw/[% method.required.join(' ') %]/ ],
+ add_source => [% method.add_source %],
+ deprecated => [% method.deprecated %],
+ authenticate => [% method.authenticate %],
+ booleans => [ qw/[% method.booleans.join(' ') %]/ ],
+ base_url_method => '[% method.base_url_method %]',
} ],
[% END -%]
] ],
@@ -442,6 +456,15 @@ while ( @$api_def ) {
# copy callers args since we may add ->{source}
my $args = ref $_[-1] eq 'HASH' ? { %{pop @_} } : {};
+ if ( (my $legacy_method = $self->can("legacy_$name")) && (
+ exists $$args{-legacy_lists_api} ? delete $$args{-legacy_lists_api}
+ : $self->{legacy_lists_api} ) ) {
+ return $self->$legacy_method(@_, $args);
+ }
+
+ # just in case it's included where it shouldn't be:
+ delete $args->{-legacy_lists_api};
+
croak sprintf "$name expected %d args", scalar @$arg_names if @_ > @$arg_names;
# promote positional args to named args
@@ -475,6 +498,11 @@ while ( @$api_def ) {
$local_path =~ s,/:id$,, unless exists $args->{id}; # remove optional trailing id
$local_path =~ s/:(\w+)/delete $args->{$1} or croak "required arg '$1' missing"/eg;
+ # stringify lists
+ for ( qw/screen_name user_id/ ) {
+ $args->{$_} = join(',' => @{ $args->{$_} }) if ref $args->{$_} eq 'ARRAY';
+ }
+
my $uri = URI->new($self->{$options{base_url_method}} . "/$local_path.json");
return $self->_parse_result(
@@ -483,12 +511,13 @@ while ( @$api_def ) {
};
no strict 'refs';
- *{__PACKAGE__ . "::$_"} = $code for $name, @{$options{aliases}};
+ $name = $_, *{__PACKAGE__ . "::$_"} = $code for $name, @{$options{aliases}};
}
}
# catch expected error and promote it to an undef
-for ( qw/list_members is_list_member list_subscribers is_list_subscriber/ ) {
+for ( qw/list_members is_list_member list_subscribers is_list_subscriber
+ legacy_list_members legacy_is_list_member legacy_list_subscribers legacy_is_list_subscriber/ ) {
my $orig = __PACKAGE__->can($_) or die;
my $code = sub {
@@ -507,36 +536,12 @@ for ( qw/list_members is_list_member list_subscribers is_list_subscriber/ ) {
*{__PACKAGE__ . "::$_"} = $code;
}
-# special case parameter handling for lookup_users
-for ( qw/lookup_users/ ) {
- my $orig = __PACKAGE__->can($_) or die;
-
- my $code = sub {
- my $self = shift;
-
- my $args = ref $_[-1] eq 'HASH' ? pop @_ : {};
- $args = { %$args, @_ };
-
- for ( qw/screen_name user_id/ ) {
- $args->{$_} = join(',' => @{ $args->{$_} }) if ref $args->{$_} eq 'ARRAY';
- }
-
- return $orig->($self, $args);
- };
-
- no strict 'refs';
- no warnings 'redefine';
- *{__PACKAGE__ . "::$_"} = $code;
-}
-
-
-
} ### end scope for $api_def
sub _from_json {
my ($self, $json) = @_;
- return eval { $json_handler->from_json($json) };
+ return eval { $json_handler->decode($json) };
}
sub _parse_result {
@@ -581,6 +586,7 @@ This document describes Net::Twitter::Lite version [% VERSION %]
my $nt = Net::Twitter::Lite->new(
username => $user,
password => $password
+ legacy_lists_api => 0,
);
my $result = eval { $nt->update('Hello, world!') };
@@ -612,6 +618,26 @@ versions of C<Net::Twitter>, and additional error handling options.
=head1 CLIENT CODE CHANGES REQUIRED
+=head2 Legacy Lists API
+
+Twitter re-implemented the Lists API using new endpoints and semantics. For backwards
+compatibility, this version of C<Net::Twitter::Lite> defaults to the deprecated, legacy
+endpoints and semantics. It issues a warning if the C<legacy_lists_api> option to new
+is not provided.
+
+To enable the new Lists endpoints and semantics, pass C<(legacy_lists_api => 0)> to
+C<new>. To disable the warning, and keep the backwards compatible endpoints and
+semantics, pass C<(legacy_lists_api => 1)> to C<new>.
+
+The C<legacy_lists_api> option to C<new> sets the default for all lists API method
+calls. You can override the default an each API call by passing a C<-legacy_lists_api>
+option set to 1 or 0.
+
+Support for C<legacy_lists_api> option will be removed in a future version and the
+option to C<new> will be silently ignored.
+
+=head2 netrc option
+
The default C<apiurl> changed in version 0.08006. The change should be
transparent to client code, unless you're using the C<netrc> option. If so,
you'll need to either update the C<.netrc> entry and change the C<machine>
@@ -622,7 +648,7 @@ or C<netrc_machine> options to C<twitter.com>.
# -or-
$nt = Net::Twitter::Lite->new(netrc => 'twitter.com');
-=head1 IMPORTANT
+=head2 OAuth requires callback parameter
Beginning with version 0.03, it is necessary for web applications using OAuth
authentication to pass the C<callback> parameter to C<get_authorization_url>.
@@ -905,6 +931,15 @@ option (below).
(Optional) Sets the C<machine> entry to look up in C<.netrc> when C<<netrc => 1>>
is used. Defaults to C<api.twitter.com>.
+=item legacy_lists_api
+
+If set to 1, this option enables backwards compatibility by using the now deprecated
+endpoints and semantics for lists API methods. If set to 0, the new endpoints and
+semantics will be used. Only the new lists API methods are documented here.
+
+If you do not provide this option to C<new> a warning is issued. Support for
+this option and the legacy lists API methods will be removed in a future version.
+
=back
=back
@@ -1089,10 +1124,6 @@ also parameters, using any one of them satisfies the requirement.
[% INCLUDE APIDOC class='Search' %]
-=head1 Lists API Methods
-
-[% INCLUDE APIDOC class='Lists' %]
-
=head1 ERROR HANDLING
When C<Net::Twitter::Lite> encounters a Twitter API error or a network error, it
View
2  t/00_load.t
@@ -1,4 +1,4 @@
-#!perl -T
+#!perl
use Test::More tests => 1;
View
2  t/01_basic.t
@@ -61,7 +61,7 @@ plan tests => @tests * 4 + 2;
use_ok 'Net::Twitter::Lite';
-my $nt = Net::Twitter::Lite->new;
+my $nt = Net::Twitter::Lite->new(legacy_lists_api => 0);
isa_ok $nt, 'Net::Twitter::Lite';
my $ua = $nt->{ua};
View
5 t/02_regression.t
@@ -11,7 +11,7 @@ plan tests => 4;
use Net::Twitter::Lite;
-my $nt = Net::Twitter::Lite->new;
+my $nt = Net::Twitter::Lite->new(legacy_lists_api => 0);
my $request;
my %args;
@@ -49,7 +49,8 @@ like $request->header('Authorization'), qr/^Basic /, 'Basic Auth header';
consumer_secret => 'secret',
access_token => 'token',
access_token_secret => 'token_secret',
+ legacy_lists_api => 0,
);
mock_response($nt);
- ok eval { $nt->delete_list(fred => 'pets') }, 'HTTP DELETE';
+ ok eval { $nt->delete_list(fred => 'pets', { -legacy_lists_api => 1}) }, 'HTTP DELETE';
}
View
12 t/99-pod_coverage.t
@@ -13,4 +13,14 @@ plan skip_all => 'set TEST_POD to enable this test'
unless ($ENV{TEST_POD} || -e 'MANIFEST.SKIP');
# skip deprecated methods
-all_pod_coverage_ok({ trustme => [qw/^(?:update_location|downtime_schedule)$/]});
+all_pod_coverage_ok({ trustme => [qr/^(?:
+ update_location
+ | downtime_schedule
+ | friends
+ | following
+ | followers
+ | following_timeline
+ | friends_timeline
+ | legacy_\w+
+ | trends
+)$/x]});
View
4 t/99-pod_spelling.t
@@ -23,6 +23,7 @@ BasicUser
clientname
clienturl
clientver
+contributees
DirectMessage
ExtendedUser
favorited
@@ -36,6 +37,7 @@ identica
IM
inline
IP
+ip
IRC
lang
Mims
@@ -61,6 +63,7 @@ ssl
Str
stringifies
timeline
+Twitter's
twitterpm
twittervision
Un
@@ -70,6 +73,7 @@ Unsubscribes
url
useragent
username
+usernames
WiFi
WOEID
woeid
View
2  t/60-api_lists.t → t/legacy_lists_api.t
@@ -7,7 +7,7 @@ use Net::Twitter::Lite;
eval 'use LWP::UserAgent 5.819';
plan skip_all => 'LWP::UserAgent 5.819 required' if $@;
-my $nt = Net::Twitter::Lite->new(username => 'fred', password => 'secret');
+my $nt = Net::Twitter::Lite->new(username => 'fred', password => 'secret', legacy_lists_api => 1);
my $req;
my $res = HTTP::Response->new(200);
View
194 t/new-lists.t
@@ -0,0 +1,194 @@
+#!perl
+use warnings;
+use strict;
+use Test::More;
+use Net::Twitter::Lite;
+
+eval 'use LWP::UserAgent 5.819';
+plan skip_all => 'LWP::UserAgent 5.819 required' if $@;
+
+my $nt = Net::Twitter::Lite->new(username => 'fred', password => 'secret', legacy_lists_api => 0);
+
+my $req;
+my $res = HTTP::Response->new(200);
+$res->content('{"response":"done"}');
+$nt->{ua}->add_handler(request_send => sub { $req = shift; return $res });
+
+my @tests = (
+ create_list => {
+ args => [ { name => 'Test list', description => 'Just a test', mode => 'private' } ],
+ path => '/lists/create',
+ params => { name => 'Test list', description => 'Just a test', mode => 'private' },
+ method => 'POST',
+ },
+ update_list => {
+ args => [ { owner_screen_name => 'owner', slug => 'test-list', mode => 'public' } ],
+ path => '/lists/update',
+ params => { owner_screen_name => 'owner', slug => 'test-list', mode => 'public' },
+ method => 'POST',
+ },
+ list_lists => {
+ args =>[ { owner_screen_name => 'owner' } ],
+ path => '/lists',
+ params => { owner_screen_name => 'owner' },
+ method => 'GET',
+ },
+ list_memberships => {
+ args => [],
+ path => '/lists/memberships',
+ params => {},
+ method => 'GET',
+ },
+ delete_list => {
+ args => [ { owner_screen_name => 'owner', slug => 'test-list' } ],
+ path => '/lists/destroy',
+ params => { owner_screen_name => 'owner', slug => 'test-list' },
+ method => 'POST',
+ },
+ list_statuses => {
+ args => [ { owner_screen_name => 'owner', slug => 'test-list' } ],
+ path => '/lists/statuses',
+ params => { owner_screen_name => 'owner', slug => 'test-list' },
+ method => 'GET',
+ },
+ get_list => {
+ args => [ { owner_srceen_name => 'owner', slug => 'test-list' } ],
+ path => '/lists/show',
+ params => { owner_srceen_name => 'owner', slug => 'test-list' },
+ method => 'GET',
+ },
+ add_list_member => {
+ args => [ { owner_screen_name => 'owner', slug => 'test-list', user_id => 1234 } ],
+ path => '/lists/members/create',
+ params => { owner_screen_name => 'owner', slug => 'test-list', user_id => 1234 },
+ method => 'POST',
+ },
+ delete_list_member => {
+ args => [ { owner_screen_name => 'owner', slug => 'test-list', user_id => 1234 } ],
+ path => '/lists/members/destroy',
+ params => { owner_screen_name => 'owner', slug => 'test-list', user_id => 1234 },
+ method => 'POST',
+ },
+ remove_list_member => {
+ args => [ { owner_screen_name => 'owner', slug => 'test-list', user_id => 1234 } ],
+ path => '/lists/members/destroy',
+ params => { owner_screen_name => 'owner', slug => 'test-list', user_id => 1234 },
+ method => 'POST',
+ },
+ list_members => {
+ args => [ { owner_screen_name => 'owner', slug => 'test-list' } ],
+ path => '/lists/members',
+ params => { owner_screen_name => 'owner', slug => 'test-list' },
+ method => 'GET',
+ },
+ is_list_member => {
+ args => [ { owner_screen_name => 'owner', slug => 'test-list', user_id => 1234 } ],
+ path => '/lists/members/show',
+ params => { owner_screen_name => 'owner', slug => 'test-list', user_id => 1234 },
+ method => 'GET',
+ },
+ subscribe_list => {
+ args => [ { owner_screen_name => 'owner', slug => 'some-list' } ],
+ path => '/lists/subscribers/create',
+ params => { owner_screen_name => 'owner', slug => 'some-list' },
+ method => 'POST',
+ },
+ list_subscribers => {
+ args => [ { owner_screen_name => 'owner', slug => 'some-list' } ],
+ path => '/lists/subscribers',
+ params => { owner_screen_name => 'owner', slug => 'some-list' },
+ method => 'GET',
+ },
+ list_subscriptions => {
+ args => [],
+ path => '/lists/all',
+ params => {},
+ method => 'GET',
+ },
+ unsubscribe_list => {
+ args => [ { owner_screen_name => 'owner', slug => 'test-list' } ],
+ path => '/lists/subscribers/destroy',
+ params => { owner_screen_name => 'owner', slug => 'test-list' },
+ method => 'POST',
+ },
+ is_list_subscriber => {
+ args => [ { owner_screen_name => 'owner', slug => 'test-list', user_id => 1234 } ],
+ path => '/lists/subscribers/show',
+ params => { owner_screen_name => 'owner', slug => 'test-list', user_id => 1234 },
+ method => 'GET',
+ },
+ is_subscribed_list => {
+ args => [ { owner_screen_name => 'owner', slug => 'test-list', user_id => 1234 } ],
+ path => '/lists/subscribers/show',
+ params => { owner_screen_name => 'owner', slug => 'test-list', user_id => 1234 },
+ method => 'GET',
+ },
+ members_create_all => {
+ args => [ { list_id => 9876, screen_name => [qw/bert barney fred/] }],
+ path => '/lists/members/create_all',
+ params => { list_id => 9876, screen_name => 'bert,barney,fred' },
+ method => 'POST',
+ },
+ add_list_members => {
+ args => [ { list_id => 9876, screen_name => [qw/bert barney fred/] }],
+ path => '/lists/members/create_all',
+ params => { list_id => 9876, screen_name => 'bert,barney,fred' },
+ method => 'POST',
+ },
+ remove_list_members => {
+ args => [ { list_id => 9876, screen_name => [qw/bert barney fred/] }],
+ path => '/lists/members/destroy_all',
+ params => { list_id => 9876, screen_name => 'bert,barney,fred' },
+ method => 'POST',
+ },
+ get_lists => {
+ args => [ { screen_name => 'owner' } ],
+ path => '/lists',
+ params => { screen_name => 'owner' },
+ method => 'GET',
+ },
+ subscriptions => {
+ args => [],
+ path => '/lists/subscriptions',
+ params => {},
+ method => 'GET',
+ },
+);
+
+plan tests => scalar @tests / 2 * 3 + 2;
+
+while ( @tests ) {
+ my $api_method = shift @tests;
+ my $t = shift @tests;
+
+ my $r = $nt->$api_method(@{ $t->{args} });
+ is $req->uri->path, "/1$t->{path}.json", "$api_method: path";
+ is $req->method, $t->{method}, "$api_method: HTTP method";
+ is_deeply extract_args($req), $t->{params},
+ "$api_method: parameters";
+}
+
+{
+ # unauthenticated call
+ my $r = $nt->list_statuses({ owner_screen_name => 'twitter' => slug => 'team', authenticate => 0 });
+ ok !$req->header('authorization'), 'unauthenticated call';
+
+ # authenticated call (default)
+ $r = $nt->list_statuses({ owner_screen_name => 'twitter' => slug => 'team' });
+ like $req->header('authorization'), qr/^Basic/, 'authenticated request (default)';
+}
+
+sub extract_args {
+ my $req = shift;
+
+ my $uri;
+ if ( $req->method eq 'POST' ) {
+ $uri = URI->new;
+ $uri->query($req->content);
+ }
+ else {
+ $uri = $req->uri;
+ }
+
+ return { $uri->query_form };
+}
View
2  t/ssl.t
@@ -10,7 +10,7 @@ eval "require Crypt::SSLeay; Crypt::SSLeay->VERSION >= 0.50"
plan tests => 1;
-my $nt = Net::Twitter::Lite->new(ssl => 1);
+my $nt = Net::Twitter::Lite->new(ssl => 1, legacy_lists_api => 0);
my $request;
my $response = HTTP::Response->new(200, 'OK');
View
2  t/unicode.t
@@ -30,6 +30,7 @@ my $nt = Net::Twitter::Lite->new(
consumer_key => 'key',
consumer_secret => 'secret',
ua => $ua,
+ legacy_lists_api => 0,
);
$nt->access_token('token');
$nt->access_token_secret('secret');
@@ -75,6 +76,7 @@ $nt = Net::Twitter::Lite->new(
username => 'fred',
password => 'pebbles',
ua => $ua,
+ legacy_lists_api => 0,
);
eval { $nt->update($status) };

No commit comments for this range

Something went wrong with that request. Please try again.