I22r-Translate-Microsoft

 view release on metacpan or  search on metacpan

lib/I22r/Translate/Microsoft.pm  view on Meta::CPAN

    my $content0 = qq[
<GetTranslationsArrayRequest>
  <AppId />
  <From>$src</From>
  <Options>
    <Category xmlns="http://schemas.datacontract.org/2004/07/Microsoft.MT.Web.Service.V2">general</Category>
    <ContentType xmlns="http://schemas.datacontract.org/2004/07/Microsoft.MT.Web.Service.V2">text/plain</ContentType>
    <ReservedFlags xmlns="http://schemas.datacontract.org/2004/07/Microsoft.MT.Web.Service.V2"/>
    <State xmlns="http://schemas.datacontract.org/2004/07/Microsoft.MT.Web.Service.V2" />
    <Uri xmlns="http://schemas.datacontract.org/2004/07/Microsoft.MT.Web.Service.V2"></Uri>
    <User xmlns="http://schemas.datacontract.org/2004/07/Microsoft.MT.Web.Service.V2">TestUserId</User>
  </Options>
  <Texts>
<TXT/>
  </Texts>
  <To>$dest</To>
  <MaxTranslations><COUNT/></MaxTranslations>
</GetTranslationsArrayRequest>];

    return $content0;
}







sub _check_token {
    my ($pkg, $req) = @_;

    if (time < ($token->{expires} // 0)) {
	I22r::Translate->log( $req->{logger}, "Microsoft backend: ",
			      "auth token still valid" );
	return 1;
    }

    my ($client_id, $secret);
    if ($req) {
	$client_id = $req->config('CLIENT_ID');
	$secret = $req->config('SECRET');
    } else {
	$client_id = $pkg->config('CLIENT_ID');
	$secret = $pkg->config('SECRET');
    }
    unless ($client_id && $secret) {
	I22r::Translate->log( $req->{logger},
			      "Microsoft backend: ",
			      "client_id or secret missing, ",
			      "cannot obtain auth token!" );
	return;
    }

    if (!$token->{secret} || $token->{secret} ne $secret) {
	$token->{secret} = $secret;
	$token->{secretx} = url_encode( $secret );
    }
    $token->{client_idx} = url_encode( $client_id );

    my $content = join( '&', 
			'grant_type=client_credentials',
			'client_id=' . $token->{client_idx},
			'client_secret=' . $token->{secretx},
			'scope=http://api.microsofttranslator.com/' );

    my $headers = HTTP::Headers->new(
	'Content-Type', 'application/x-www-form-urlencoded');
    $token->{ua} //= LWP::UserAgent->new;
    my $request = HTTP::Request->new(
	POST => TOKENAUTH_URL,
	$headers, $content );
    my $req_start = time;
    my $res = $token->{ua}->request( $request );
    if (!$res->is_success) {

	eval {
	    my $js = decode_json( $res->decoded_content );
	    if ($js->{error} && $js->{error_description}) {
		carp __PACKAGE__, 
			": Failed to refresh authorization token ",
			"for client [$client_id\n$secret]:\n",
		    "Error: ", $js->{error}, "\n",
		    "Error description: ", $js->{error_description}, "\n",
		    "Result code: ", $res->{_rc}, "\n",
		    "FULL ERROR: ", join(";",%$js), "\n",
		    "REQUEST: ", join(" ",%$request), "\n",
		    "REQ_HEADERS: ", join(" ", %{$request->{_headers}}), "\n";
		I22r::Translate->log( $req->{logger},
				      "request for auth token failed: ",
				      $js->{error}, "/",
				      $js->{error_description} );
		1;
	    }
	} or carp __PACKAGE__, ": Failed to refresh authorization token for",
			       " client [$client_id]. $!\n";
	return;
    }
    my $dc = $res->decoded_content;
    my $js = eval { decode_json( $dc ) };
    if ($@) {
	carp "decode_json error. input was $dc";
	return;
    }

    my $expires = $js->{expires_in};
    if ($expires > 120) {
	$expires -= 60;
    } else {
	$expires /= 2;
    }
    $token->{expires} = $req_start + $expires;
    $token->{token} = $js->{access_token};
    $token->{authorization} = "Bearer " . $token->{token};
    I22r::Translate->log($req->{logger}, "Microsoft backend: ",
			 "obtained auth token");
    return 1;
}

1;
# End of I22r::Translate::Microsoft

lib/I22r/Translate/Microsoft.pm  view on Meta::CPAN


Invokes Microsoft's translation webservice to translate content
from one language to another.

=head1 CONFIG

You instruct the L<I22r::Translate> package to use the
Microsoft backend by passing a key-value  pair to the
L<I22r::Translate::config|I22r::Translate/"config"> method
where the key is the string "C<I22r::Translate::Microsoft>"
and the value is a hash reference with at least the following
key-value pairs:

=over 4

=item ENABLED => 0 | 1

Must be set to a true value for the Microsoft backend to function.

=item CLIENT_ID => userid

Required Windows Azure Marketplace client ID for accessing the
Microsoft Translator API. See L<"CREDENTIALS">, below.

=item SECRET => 44-character string

Required Windows Azure Marketplace "client secret" for accessing the
Microsoft Translator API. See L<"CREDENTIALS">, below.

=item timeout => integer

Stops a translation job after a certain number of seconds have
passed. Optional. Any translations that were completed before
the timeout will still be returned.

=item callback => code reference or function name

A function to be invoked when the Microsoft backend obtains
a translation result. 
The function will be called with two arguments: the
L<request|I22r::Translate::Request> object that is handling the
translation, and a hash reference containing the fields and values
for the new translation result.

You can have separate callbacks in the global configuration, for each
backend, and for the current request.

=item filter => array reference

List of filters to use (see L<I22r::Translate::Filter>) when
sending text to the Microsoft Translate webservice.

=back

=head1 CREDENTIALS

This package interacts with the Microsoft Translator API,
which requires some you/us to provide a "client id" and
"client secret" to access Microsoft's data services.
As of October 2012, here are the steps you need to take
to get those credentials. (If these steps don't work anymore,
and you do figure out what steps you need to do, L<let me 
know|mailto:mob@cpan.org> or L<file a bug report|"SUPPORT">
and I'll update this document.

=over 4

=item 1. 

If you don't have a  Windows Live ID , sign up
for one at L<https://signup.live.com/signup.aspx?lic=1>    

=item 2. 

Visit L<https://datamarket.azure.com/dataset/bing/microsofttranslator>.
Register for a "Windows Azure Marketplace" account.

=item 3. 

Choose a Microsoft Translator data plan. One of the
available plans is a free option for 2,000,000 characters/month.

=item 4. 

Now you have to "register an application". Visit
L<https://datamarket.azure.com/developer/applications> and hit the
big green B<REGISTER> button.

=item 5. 

Choose any "Client ID" and "Name" for your application. The "URI"
is also a required field, but the translator API doesn't use it, so you
can put whatever you like in that field, too.

Make a note of the "Client ID"  value that you entered and the
"Client secret" value that Microsoft provided. You will have to provide
these values to the C<I22r::Translate::Microsoft> backend configuration
with the C<CLIENT_ID> and C<SECRET> keys.

Example: If your application registration screen looks like:

    * Client ID         angus
    * Name              The Beefinator
    * Client secret     ykiDjfQ9lztW/oFUC4t2ciPWH2nJS88FqXcQbs/Z9Y=7
    * Redirect URI      https://ilikebeef.com/
      Description       The multilingual Beefinator site

Then you would configure the Microsoft backend with

    I22r::Translate->config(
        'I22r::Translate::Microsoft' => {
            ENABLED => 1,
            CLIENT_ID => "angus",
            SECRET => "ykiDjfQ9lztW/oFUC4t2ciPWH2nJS88FqXcQbs/Z9Y=7"
        } );

(these are not real credentials).

=back

=head1 AUTHOR

Marty O'Brien, C<< <mob at cpan.org> >>

=head1 BUGS

Please report any bugs or feature requests to 
C<bug-i22r-translate-microsoft at rt.cpan.org>, or through
the web interface at 
L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=I22r-Translate-Microsoft>.
I will be notified, and then you'll automatically be notified of progress
on your bug as I make changes.

=head1 SUPPORT

You can find documentation for this module with the perldoc command.

    perldoc I22r::Translate::Microsoft

You can also look for information at:

=over 4

=item * RT: CPAN's request tracker (report bugs here)

L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=I22r-Translate-Microsoft>

=item * AnnoCPAN: Annotated CPAN documentation

L<http://annocpan.org/dist/I22r-Translate-Microsoft>

=item * CPAN Ratings

L<http://cpanratings.perl.org/d/I22r-Translate-Microsoft>

=item * Search CPAN

L<http://search.cpan.org/dist/I22r-Translate-Microsoft/>

=back

=head1 SUBROUTINES/METHODS

There should be no need to use the methods of this package directly.
See L<I22r::Translate::Backend> and L<I22r::Translate>.

=head1 SEE ALSO

L<I22r::Translate>

=head1 LICENSE AND COPYRIGHT

Copyright 2012-2013 Marty O'Brien.

This program is free software; you can redistribute it and/or modify it
under the terms of either: the GNU General Public License as published
by the Free Software Foundation; or the Artistic License.



( run in 0.583 second using v1.01-cache-2.11-cpan-5511b514fd6 )