File Coverage

blib/lib/Twitter/API/Trait/Migration.pm
Criterion Covered Total %
statement 35 36 97.2
branch 4 6 66.6
condition 2 5 40.0
subroutine 10 10 100.0
pod 0 4 0.0
total 51 61 83.6


line stmt bran cond sub pod time code
1             package Twitter::API::Trait::Migration;
2             # ABSTRACT: Migration support Net::Twitter/::Lite users
3             $Twitter::API::Trait::Migration::VERSION = '1.0006';
4 1     1   629 use 5.14.1;
  1         4  
5 1     1   5 use Carp;
  1         3  
  1         62  
6 1     1   5 use Moo::Role;
  1         3  
  1         8  
7 1     1   372 use Ref::Util qw/is_ref/;
  1         3  
  1         38  
8 1     1   4 use namespace::clean;
  1         2  
  1         8  
9              
10             has [ qw/request_token request_token_secret/ ] => (
11             is => 'rw',
12             predicate => 1,
13             clearer => 1,
14             );
15              
16             has wrap_result => (
17             is => 'ro',
18             default => sub { 0 },
19             );
20              
21             around request => sub {
22             my ( $next, $self ) = splice @_, 0, 2;
23              
24             my ( $r, $c ) = $self->$next(@_);
25              
26             # Early exit? Actually just a context object; return it.
27             return $r unless defined $c;
28              
29             # Net::Twitter/::Lite migraton support
30             if ( $self->wrap_result ) {
31             unless ( $ENV{TWITTER_API_NO_MIGRATION_WARNINGS} ) {
32             carp 'wrap_result is enabled. It will be removed in a future '
33             .'version. See Twitter::API::Trait::Migration';
34             }
35             return $c;
36             }
37              
38             return wantarray ? ( $c->result, $c ) : $c->result;
39             };
40              
41 2     2 0 35 sub ua { shift->user_agent(@_) }
42              
43             sub _get_auth_url {
44 18     18   34 my ( $self, $endpoint ) = splice @_, 0, 2;
45 18 50 33     68 my %args = @_ == 1 && is_ref($_[0]) ? %{ $_[0] } : @_;
  0         0  
46              
47 18   50     53 my $callback = delete $args{callback} // 'oob';
48 18         50 my ( $r, $c ) = $self->oauth_request_token(callback => $callback);
49 18         679 $self->request_token($$r{oauth_token});
50 18         38 $self->request_token_secret($$r{oauth_token_secret});
51              
52             my $uri = $self->_auth_url($endpoint,
53             oauth_token => $$r{oauth_token},
54 18         49 %args
55             );
56 18 50       156 return wantarray ? ( $uri, $c ) : $uri;
57             }
58              
59 9     9 0 23 sub get_authentication_url { shift->_get_auth_url(authenticate => @_) }
60 9     9 0 18 sub get_authorization_url { shift->_get_auth_url(authorize => @_) }
61              
62             sub request_access_token {
63 7     7 0 25 my ( $self, %params ) = @_;
64              
65             # request_access_token is defined in both Net::Twitter's OAuth and AppAuth
66             # traits. We need to know which one to call, here.
67 7 100       26 if ( $self->does('Twitter::API::Trait::AppAuth') ) {
68 1         24 return $self->access_token($self->oauth2_token(@_));
69             }
70              
71 6         191 my ( $r, $c ) = $self->oauth_access_token({
72             token => $self->request_token,
73             token_secret => $self->request_token_secret,
74             %params, # verifier => $verifier
75             });
76              
77             # Net::Twitter stores access tokens in the client instance
78 6         75 $self->access_token($$r{oauth_token});
79 6         17 $self->access_token_secret($$r{oauth_token_secret});
80 6         116 $self->clear_request_token;
81 6         105 $self->clear_request_token_secret;
82              
83             return (
84 6         24 @{$r}{qw/oauth_token oauth_token_secret user_id screen_name/},
  6         81  
85             $c,
86             );
87             }
88              
89             for my $method ( qw/
90             get_authentication_url
91             get_authorization_url
92             request_access_token
93             ua
94             /) {
95             around $method => sub {
96             my ( $next, $self ) = splice @_, 0, 2;
97              
98             unless ( $ENV{TWITTER_API_NO_MIGRATION_WARNINGS} ) {
99             carp $method.' will be removed in a future release. '
100             .'Please see Twitter::API::Trait::Migration';
101             }
102             $self->$next(@_);
103             };
104             }
105              
106             1;
107              
108             __END__
109              
110             =pod
111              
112             =encoding UTF-8
113              
114             =head1 NAME
115              
116             Twitter::API::Trait::Migration - Migration support Net::Twitter/::Lite users
117              
118             =head1 VERSION
119              
120             version 1.0006
121              
122             =head1 DESCRIPTION
123              
124             Twitter::API is a rewrite of L<Net::Twitter>. It's leaner, lighter, and
125             has faster—fewer dependencies, and less baggage. This trait helps Net::Twitter and
126             Net::Twitter::Lite users migrate to Twitter::API by providing Net::Twitter
127             compatible behavior where possible and warning politely where code should be
128             changed.
129              
130             =head1 Migrating from Net::Twitter
131              
132             Twitter::API requires a minimum perl version of 5.14.1. Make sure you have that.
133              
134             Just change your constructor call:
135              
136             my $client = Net::Twitter->new(
137             traits => [ qw/API::RESTv1_1 OAuth RetryOnError/ ],
138             consumer_key => $key,
139             consumer_secret => $secret,
140             access_token => $token,
141             access_token_secret => $token_secret,
142             );
143              
144             Becomes:
145              
146             my $client = Twitter::API->new_with_traits(
147             traits => [ qw/Migration ApiMethods RetryOnError/ ],
148             consumer_key => $key,
149             consumer_secret => $secret,
150             access_token => $token,
151             access_token_secret => $token_secret,
152             );
153              
154             Differences:
155              
156             =over 4
157              
158             =item *
159              
160             replace C<new> with C<new_with_traits>
161              
162             =item *
163              
164             replace trait C<API::RESTv1_1> with C<ApiMethods>
165              
166             =item *
167              
168             drop trait C<OAuth>, Twitter::API's core includes it
169              
170             =item *
171              
172             add the Migration trait so Twitter::API will handle oauth key management in a Net::Twitter compatible way and warn
173              
174             =back
175              
176             =head2 Traits
177              
178             Twitter::API supports the following traits:
179              
180             =over 4
181              
182             =item *
183              
184             L<ApiMethods|Twitter::API::Trait::ApiMethods>
185              
186             =item *
187              
188             L<AppAuth|Twitter::API::Trait::AppAuth>
189              
190             =item *
191              
192             L<DecodeHtmlEntities|Twitter::API::Trait::DecodeHtmlEntities>
193              
194             =item *
195              
196             L<NormalizeBooleans|Twitter::API::Trait::NormalizeBooleans>
197              
198             =item *
199              
200             L<RetryOnError|Twitter::API::Trait::RetryOnError>
201              
202             =item *
203              
204             L<Enchilada|Twitter::API::Trait::Enchilada>
205              
206             =back
207              
208             B<ApiMethods >is a direct replacement for Net::Twitter's API::RESTv1_1 trait.
209              
210             Net::Twitter's B<InflateObjects> trait will be released as a separate distribution
211             to minimize Twitter::API's dependencies.
212              
213             If you are using the Net::Twitter's B<WrapResults> trait, Twitter::API provides
214             a better way to access the what it provides. In list context, API calls return
215             both the API call results and a L<Twitter::API::Context> object that provides
216             the same accessors and attributes B<WrapResult> provided, including the
217             B<result> accessor.
218              
219             So, if you had:
220              
221             my $r = $client->home_timeline;
222             $r->result;
223             $r->rate_limit_remaining;
224              
225             You can change that to:
226              
227             my ( $result, $context ) = $client->home_timeline;
228             $result;
229             $context->rate_limit_remaining;
230              
231             Or for the smallest change to your code:
232              
233             my ( undef, $r ) = $client->home_timeline;
234             $r->result; i # same as before
235             $r->rate_limit_remaning; # same as before
236              
237             However, there is migration support for B<WrapResult>. Call the constructor
238             with option C<< wrap_result => 1 >> and Twitter::API will return the context
239             object, only, for API calls. This should give you the same behavior you had
240             with B<WrapResult> while you modify your code. Twitter::API will warn when this
241             option is used. You may disale warnings with
242             C<$ENV{TWITTER_API_NO_MIGRATION_WARNINGS} = 1>.
243              
244             If you are using any other Net::Twitter traits, please contact the author of
245             Twitter::API. Additional traits may be added to Twitter::API or released as
246             separate distributions.
247              
248             If you are using C<< decode_html_entities => 1 >> in Net::Twitter, drop that
249             option and add trait B<DecodeHtmlEntities>. Traits B<AppAuth> and
250             B<RetryOnError> provide the same functionality in Twitter::API as their
251             Net::Twitter counterparts. So, no changes required, there, if you're using
252             them. (Although there is a change to one of B<AppAuth>'s methods. See the
253             L</"OAuth changes"> discussion.)
254              
255             NormalizeBooleans is something you'll probably want. See the
256             L<NormalizeBooleans|Twitter::API::Trait::NormalizeBooleans> documentation.
257              
258             Enchilda just bundles ApiMethods, NormalizeBooleans, RetryOnError, and
259             DecodeHtmlEntities.
260              
261             =head2 Other constructor options
262              
263             Drop option C<< ssl => 1 >>. It is no longer necessary. By default, all
264             connections use SSL.
265              
266             If you are setting B<useragent_lass> and/or B<useragent_args> to customize the
267             user agent, just construct your own pass it to new with C<< user_agent =>
268             $custom_user_agent >>.
269              
270             If you are using B<ua> to set a custom user agent, the attribute name has
271             changed to B<usre_agent>. So, pass it to new with C<< user_agent =>
272             $custom_user_agent >>.
273              
274             By default, Twitter::API uses L<HTTP::Thin> as its user agent. You should be
275             able to use any user agent you like, as long as it has a B<request> method that
276             takes an L<HTTP::Request> and returns an L<HTTP::Response>.
277              
278             If you used B<clientname>, B<clientver>, B<clienturl>, or B<useragent>, see
279             L<Twitter::API/agent> and L<Twitter::API/default_headers>. If all you're after
280             is a custom User-Agent header, just pass C<< agent => $user_agent_string >>.
281             It will be used for both User-Agent header and the X-Twitter-Client header on
282             requests. If you want to include your own application version and url, pass
283             C<< default_headers => \%my_request_headers >>.
284              
285             =head2 OAuth changes
286              
287             Net::Twitter saved request and access tokens in the client instance as part of
288             the 3-legged OAuth handshake. That was a poor design decision. Twitter::API
289             returns request and access tokens to the caller. It is the caller's
290             responsibility to store and cache them appropriately. Hovever, transitional
291             support is provided, with client instance storage, so your code can run
292             unmodified while you make the transition.
293              
294             The following methods exist only for migration from Net::Twitter and will be
295             removed in a future release. A warning is issued on each call to these methods.
296             To disable the warnings, set C<$ENV{TWITTER_API_NO_MIGRATION_WARNINGS} = 1>.
297              
298             =over 4
299              
300             =item *
301              
302             B<get_authentication_url>
303              
304             replace with L<oauth_authentication_url|Twitter::API/oauth_athentication_url>
305             or L<oauth_request_token|Twitter::API/oauth_request_token> and
306             L<oauth_authentication_url|Twitter::API/oauth_athentication_url>
307              
308             =item *
309              
310             B<get_authorization_url>
311              
312             replace with L<oauth_authorization_url|Twitter::API/oauth_authorization_url> or
313             L<oauth_request_token|Twitter::API/oauth_request_token> and
314             L<oauth_authorization_url|Twitter::API/oauth_authorization_url>
315              
316             =item *
317              
318             B<get_access_token>
319              
320             replace with L<oauth_access_token|Twitter::API/oauth_access_token>
321              
322             =back
323              
324             If you are using the B<AppAuth> trait, replace B<request_access_token> calls
325             with B<oauth2_token> calls. Method B<oauth2_token> does not set the
326             C<access_token> attribute. Method C<request_access_token> is provided for
327             transitional support, only. It warns like the OAuth methods discussed above, and
328             it sets the C<access_token> attribute so existing code should work as expected
329             during migration. It will be removed in a future release.
330              
331             =head1 Migrating from Net::Twitter::Lite
332              
333             The discussion, above applies for L<Net::Twitter::Lite> with a few exceptions.
334              
335             Net::Twitter::Lite does not use traits. Change your constructor call from:
336              
337             my $client = Net::Twitter::Lite::WithAPIv1_1->new(%args);
338              
339             To:
340              
341             my $client = Twitter::API->new_with_traits(
342             traits => [ qw/Migration ApiMethods/ ],
343             %args,
344             );
345              
346             If you're using the option B<wrap_result>, see the discussion above about the
347             Net::Twitter WrapResult trait. There is migration support for B<wrap_result>.
348             It will be removed in a future release.
349              
350             =head1 AUTHOR
351              
352             Marc Mims <marc@questright.com>
353              
354             =head1 COPYRIGHT AND LICENSE
355              
356             This software is copyright (c) 2015-2021 by Marc Mims.
357              
358             This is free software; you can redistribute it and/or modify it under
359             the same terms as the Perl 5 programming language system itself.
360              
361             =cut