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